> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lumos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Subject

> Read one subject: what is being reviewed, who is reviewing it, what they decided, and what removal that decision led to.

What a subject is follows from the app review's type — an accounts review reviews accounts, an entitlements review reviews the entitlements an account holds — and `subject_type` says which. An entitlement subject also names the account it belongs to, so one shape serves both.

`removal.status` is current even while the removal runs. Evidence is reported beside `removal` rather than in it (`is_evidence_attached`, `evidence_required_by`, and the files under `expand=evidence`), since an approved subject can owe evidence too.

`removal.error` says which capability failed and what the integration reported. It does not say whether retrying will help; a removal waiting on a person clears only once that person acts.



## OpenAPI

````yaml /api-reference/lumos-api-v1.json get /v1/access-reviews/{review_uuid}/apps/{app_review_uuid}/subjects/{subject_uuid}
openapi: 3.1.0
info:
  title: Lumos API (v1)
  description: >

    Lumos API v1 is the programmatic interface to your connected apps, the
    entitlements on them, and

    the workflows that grant access to those entitlements.


    Every path is prefixed with `/v1`. Authenticate with an API token, which
    inherits the permissions

    of the user who created it: a call returns what that user could see in the
    Lumos UI, and nothing

    more.


    New here? Browse what you can connect with `GET /v1/integrations`, read the
    credentials an

    integration expects with `GET
    /v1/integrations/{app_class_id}/connection-schema`, then connect it

    with `POST /v1/apps`.


    Every list endpoint shares one pagination contract. Set the page length with
    `page_size`, then send

    the `next_page_token` from a response back as `page_token` to fetch the next
    page. A `null`

    `next_page_token` means you have reached the end.


    Every error shares one envelope. Branch on the machine-readable `code`, not
    on `detail`.
  version: 0.1.0
servers:
  - url: https://api.lumos.com
security: []
tags:
  - name: Access Policies
    description: >

      An access policy grants apps, and optionally specific entitlements on
      them, to the identities that

      qualify under its `access_condition`, a Lumos Condition object.


      `POST /v1/access-policies` creates a policy and returns 201. `GET
      /v1/access-policies` lists

      policies, and `GET`, `PUT`, and `DELETE` on
      `/v1/access-policies/{access_policy_id}` read, replace,

      and delete one.


      Each entitlement a policy grants appears under `apps[].entitlements[]`,
      identified by its

      Entitlement UUID, the `id` that `GET /v1/entitlements/{entitlement_uuid}`
      returns.
  - name: Access Requests
    description: >

      An access request asks for access to an app, or to specific entitlements
      on it, for you or for

      another user.


      - `POST /v1/access-requests` creates requests, naming entitlements by
      Entitlement UUID in
        `entitlement_ids`, and returns them as a list.
      - `GET /v1/access-requests` and `GET /v1/access-requests/{id}` read
      requests.

      - `POST /v1/access-requests/{id}:cancel` cancels a pending request.


      Of the built-in roles, Admin, Read Only Admin, AppStore Read Only Admin,
      and App Admin can read

      every access request in your organization. Anyone else sees only the
      requests they made and the

      ones made for them.
  - name: Access Reviews
    description: >

      An access review is a campaign that reviews who has access to what across
      your connected apps.

      Each app in a campaign is an app review.


      v1 has two access-review endpoints so far, both scoped to one app review:


      - `GET
      /v1/access-reviews/{review_uuid}/apps/{app_review_uuid}/subject-filters`
      lists the fields
        you can filter the app review's subjects on. Each field comes with the operators it supports
        and, when it has a fixed set of values, the values it accepts.
      - `POST /v1/access-reviews/{review_uuid}/apps/{app_review_uuid}:sync` runs
      the app review's data
        import, optionally with new scope filters. It returns 202 with an operation. Poll
        `GET /v1/operations/{operation_id}` until `done` is true.

      You can't create, list, or update campaigns in v1 yet. Lumos enables these
      endpoints per

      organization, separately from the rest of v1, so contact your Lumos
      representative to turn them on.
  - name: Accounts
    description: >

      An account is a person's presence inside a connected app. Accounts arrive
      through sync; you cannot

      create one through this API.


      `GET /v1/accounts/{account_uuid}/entitlements` lists what one account
      holds. It reads the same

      relationship as `GET /v1/entitlements/{entitlement_uuid}/accounts`, from
      the account's side rather

      than the entitlement's.
  - name: Activity Logs
    description: >

      Activity logs record the actions taken across your organization's apps and
      identities.

      `GET /v1/activity-logs` lists them, newest first.


      Reading activity logs requires permission to view them across your
      organization. Of the built-in

      roles, Admin and Read Only Admin have it. Without it, the request returns
      403.
  - name: App Categories
    description: >

      App categories are the fixed set of categories an app can belong to, such
      as `Developers`.

      `GET /v1/app-categories` lists them as `{label}` objects.


      A `label` is the exact value to send as `category` to `POST /v1/apps` and

      `PATCH /v1/apps/{app_uuid}`. It is also the value the app read endpoints
      report. Read the list

      instead of hard-coding it.
  - name: Apps
    description: >

      An app is an integration you have connected, one per connected instance of
      a service. Your Okta

      tenant is an app. A second Slack workspace is a second app.


      ### Connecting one


      1. `GET /v1/integrations/{app_class_id}/connection-schema` to see which
      `auth` and `settings`
         keys the integration expects.
      2. `POST /v1/apps` with those credentials. Apps whose credentials validate
      right away connect, and
         their first sync waits for an admin to review match rules. It starts from the Lumos UI, or from
         `POST /v1/apps/{app_uuid}:sync` with `skip_first_sync_review: true`. Apps that need browser
         consent are finished in the Lumos UI.
      3. `GET /v1/apps/{app_uuid}` to follow the first sync. `sync_status` shows
      the state of the
         app's most recent sync. A sync started with `POST /v1/apps/{app_uuid}:sync` also returns an
         operation, which you poll with `GET /v1/operations/{operation_id}`.
      4. `POST /v1/apps/{app_uuid}:sync` to resync later. Only one sync runs per
      app at a time, so a
         second request while one is in flight returns 409.

      Rotate credentials with `PATCH /v1/apps/{app_uuid}`, which also updates an
      app's metadata.

      `POST /v1/apps/{app_uuid}:disconnect` drops the stored credentials and
      returns the app to a

      connectable state; `DELETE /v1/apps/{app_uuid}` removes the app outright.


      ### Reading apps


      `expand` is opt-in and evaluated per field: ask for `admins`,
      `custom_attributes`,

      `appstore_settings`, or any of the three workflow fields. A field you lack
      permission to read is

      left out of the response instead of failing the whole request, so a 200
      does not prove every field

      you asked for came back.


      To list only the connected apps you manage through the API, combine
      `connection_source=api` with

      `disconnected=false`.


      ### Bound workflows


      Each app carries three bindings: an approval workflow, a default
      provisioning workflow, and a

      default deprovisioning workflow. The two `default_` workflows are the ones
      that entitlements on

      the app fall back to. To bind a workflow to one entitlement instead, use
      the Entitlements

      endpoints.
  - name: Custom Attribute Definitions
    description: >

      Custom attributes are the extra fields your organization keeps on users.
      These endpoints read

      their *definitions*, not the values stored against any particular user.


      `GET /v1/custom-attribute-definitions` returns one entry per label,
      unified across every app that

      supplies it. Narrow the list with `source_type` to tell attributes synced
      from an app apart from

      ones your team created, or with `app_id` to see only what a single app
      supplies.


      `GET /v1/custom-attribute-definitions/{id}` reads one definition by its
      `id`, and

      `GET /v1/custom-attribute-definitions/{id}/configs` lists the configs
      behind it, highest priority

      first.
  - name: Entitlements
    description: >

      An entitlement is a grantable unit of access on an app: a role, a license
      tier, a group, or

      another access right. Accounts hold entitlements.


      - `POST /v1/entitlements` creates a requestable entitlement on an app.

      - `GET /v1/apps/{app_uuid}/entitlements` lists the entitlements on one
      app.

      - `GET /v1/entitlements/{entitlement_uuid}/accounts` lists who currently
      holds one.

      - `PATCH /v1/entitlements/{entitlement_uuid}` updates its `label`,
      `description`, and
        `custom_approval_message_override`. Sending any other field returns 400.
      - `DELETE /v1/entitlements/{entitlement_uuid}` refuses while the
      entitlement is still held,
        returning 409 with an `active_accounts` count.

      ### Per-entitlement workflows


      An entitlement can have its own approval override, provisioning workflow,
      and deprovisioning

      workflow, bound to it rather than to the whole app. Each has a GET and a
      PUT, and the approval

      override also has a DELETE that turns it off.


      An entitlement that can't be requested returns 404 with

      `Workflows are not available for this entitlement.` on each of these
      endpoints.
  - name: Groups
    description: >

      Lumos syncs groups from your connected apps, such as your Okta groups, and
      these endpoints read

      them.


      - `GET /v1/groups` lists groups. Filter by `name` (add `exact_match=true`
      to require an exact
        match), by `integration_specific_id` (the group's ID in the source system), or by `app_id`.
      - `GET /v1/groups/{group_id}` reads one group, and `GET
      /v1/groups/{group_id}/users` lists its
        members.

      An `app_id` that matches no app in your organization returns 404.
  - name: Identity Events
    description: >

      Identity events are the changes Lumos detects on your organization's
      identities, such as a change

      to a status, a group membership, or a custom attribute. `GET
      /v1/identity-events` lists them.

      Narrow the list with `identity_ids`, `changed_fields`, `start_time`, and
      `end_time`.


      A page can come back empty while `next_page_token` is still set, because
      events Lumos can't read

      are dropped after a page is fetched. Keep paging until `next_page_token`
      is absent, not until a

      page is empty.
  - name: Inline Webhooks
    description: >

      Inline webhooks are the webhooks your organization has configured in
      Lumos.

      `GET /v1/inline-webhooks` lists all of them, whatever their type.


      A webhook's `type` says where Lumos uses it.
  - name: Integrations
    description: >

      An integration is a service Lumos knows how to connect to, identified by
      an `app_class_id` such as

      `okta.com` or `workspace.google.com`. This is the catalog you connect
      *from*. Apps you have

      already connected are read through the Apps endpoints.


      Only connectable integrations appear here. Software discovered in your
      environment that has no

      Lumos integration behind it is excluded.


      ### Discovering how to connect


      1. `GET /v1/integrations?query=google` to find the integration. The filter
      matches both the
         `app_class_id` and the display name, so `google` returns `workspace.google.com` and
         `cloud.google.com`.
      2. `GET /v1/integrations/{app_class_id}/connection-schema` for the JSON
      schema of the `auth` and
         `settings` fields it expects.
      3. `POST /v1/apps` with those values.


      Step 2 is the point of this group: it lets you build a connect form
      without hardcoding one

      credential shape per integration.


      `GET /v1/integrations/{app_class_id}` and the connection schema return 404
      for any integration the

      list leaves out. The connection schema also returns 404 for an integration
      whose schema Lumos

      cannot describe yet.
  - name: Knowledge
    description: >

      Knowledge entries are the documents and notes Lumos agents draw on when
      they answer access

      questions. Each entry carries a title, body, tags, and product scopes,
      plus an optional file

      attachment.


      Because of that attachment, create and update send `multipart/form-data`
      rather than JSON. On

      update, tag and scope lists replace what was there instead of appending,
      and `clear_attachment=true`

      removes an existing file without uploading a replacement.


      `DELETE` deletes a knowledge entry. It no longer appears in list results,
      and you can't restore

      it through the API.


      Pages here are small: `page_size` defaults to 10 and is clamped to 25.
  - name: Lifecycle Management
    description: >

      Lifecycle management covers user offboardings. An offboarding runs your
      organization's

      offboarding workflow for one user, either right away or at a scheduled
      time.


      - `POST /v1/lifecycle-management/user-offboardings` starts an offboarding
      now, or at
        `scheduled_at` when you send a future time.
      - `GET /v1/lifecycle-management/user-offboardings/{user_offboarding_id}`
      reads one.

      - `POST
      /v1/lifecycle-management/user-offboardings/{user_offboarding_id}:cancel`
      cancels one that
        is scheduled or in progress.

      There is no list endpoint, so keep the `id` that create returns.


      `workflow_config_id` names an offboarding workflow configuration, not a
      workflow from

      `/v1/workflows`. Omit it to use the configuration your organization has
      selected for automatic

      offboarding. Only organizations with the multiple offboarding workflows
      feature can send it. For

      any other organization, a request that includes it returns 400.
  - name: Meta
    description: >

      `GET /v1/info` returns the API's current git revision, and `GET /v1/art`
      returns Lumos ASCII art.

      Use either to check your setup.


      Both require an API token. A 200 means your token works.
  - name: Operations
    description: >

      An operation tracks work that continues after the request that started it
      has returned. These

      endpoints start such work and respond with 202 and an operation:


      - `POST /v1/apps/{app_uuid}:sync`

      - `POST /v1/accounts:upload`

      - `POST /v1/access-reviews/{review_uuid}/apps/{app_review_uuid}:sync`


      Poll `GET /v1/operations/{operation_id}` until `done` is true. While
      `done` is false, neither

      `result` nor `error` is set. Once `done` is true, exactly one of them is.


      An app-sync operation shows the app's most recent sync, which can be a
      later run than the one you

      started.
  - name: Pre-Approval Rules
    description: >

      A pre-approval rule pre-approves matching access requests for an app.


      - `GET /v1/apps/{app_uuid}/pre-approval-rules` lists an app's rules, and
      `POST` on the same path
        creates one.
      - `GET`, `PATCH`, and `DELETE` on
      `/v1/apps/{app_uuid}/pre-approval-rules/{pre_approval_rule_id}`
        read, update, and delete one.

      If the app has been merged into another app, these endpoints work on the
      rules of the app it was

      merged into.


      Lumos enables condition-based pre-approval rules per organization,
      separately from the rest of v1,

      so contact your Lumos representative to turn them on.
  - name: Tasks
    description: >

      A task is work Lumos assigns to a person or group, such as approving an
      access request or

      provisioning access by hand. A workflow that creates a task waits for
      someone to act on it before

      it continues.


      ### Finding tasks


      `GET /v1/tasks` lists the tasks visible to you. `show_all_tasks=true`
      lists every task in your

      organization instead. It needs permission to view every task, which the
      built-in Admin, Read Only

      Admin, and AppStore Read Only Admin roles have, and which a custom role
      can also grant. Anyone

      else gets a 403.


      Filter with `type`, `category`, `status`, and `product_area`, whose values
      are lowercase and

      kebab-case. For example,

      `GET /v1/tasks?category=approval&product_area=appstore&status=pending`
      lists pending AppStore

      approvals.


      A task names the entitlement it grants or removes in `entitlement_id`, an
      Entitlement UUID.


      ### Acting on a task


      - `POST /v1/tasks/{task_id}:complete` approves an approval task, or
      completes another task with
        its one completion action.
      - `POST /v1/tasks/{task_id}:dismiss` denies an approval task, or dismisses
      another task without
        doing its work.
      - `POST /v1/tasks/{task_id}:perform-action` takes a specific action.
        `GET /v1/tasks/{task_id}/actions` lists the actions you can take and the statuses each one can
        move the task to, which are the values `transition_to` accepts.
      - `POST /v1/tasks/{task_id}:reassign` changes who the task is assigned to.
  - name: Users
    description: >

      Users are the people in your organization. These endpoints read them, and
      the only thing they

      change is a user's Lumos roles.


      - `GET /v1/users` lists users. `search` matches names and emails, and
      `exact_match=true`
        requires an exact match.
      - `GET /v1/users/current` returns the user who owns your API token.

      - `GET /v1/users/{user_id}` reads one user, and `GET
      /v1/users/{user_id}/accounts` lists the
        accounts that user holds.
      - `GET /v1/users/{user_id}/roles` lists a user's Lumos roles. Each role
      has an `id` (a built-in
        role's kebab-case name such as `app-admin`, or a custom role's UUID), a display `label`,
        `is_custom`, and a `resource_type` that is null for roles that apply across the organization.
        `POST /v1/users/{user_id}/roles/{role_id}` assigns one, and
        `DELETE /v1/users/{user_id}/roles/{role_id}` removes one, where `role_id` is the role's `id`.
        Assigning a role the user already has, or removing one they don't have, changes nothing.

      A user who has been deleted returns the same 404 as one who doesn't exist
      in your organization.
  - name: Workflows
    description: >

      A workflow is a reusable definition of the steps Lumos runs to approve a
      request, provision access,

      or deprovision it. Create the definition here, then bind it to an app or
      an entitlement through

      their own workflow endpoints.


      ### Building one


      1. `GET /v1/workflow-steps?app_id={app_uuid}&type={workflow type}` to
      discover the steps available
         for that app in the type of workflow you will create, each with the input schema it accepts.
         Without `type`, it lists only the steps every workflow type accepts.
      2. `POST /v1/workflows` with the steps you want.

      3. Bind it, for example with `PUT
      /v1/apps/{app_uuid}/default-provisioning-workflow`.


      `type` and `app_id` are fixed at creation. `PUT
      /v1/workflows/{workflow_id}` returns 400 for a

      change to either.


      ### Workflows this API cannot describe


      Some workflows Lumos builds for you, including the out-of-the-box
      provisioning defaults, contain

      steps with no public representation. `GET /v1/workflows` skips them, so a
      page can hold fewer items

      than `page_size` while more results remain. Treat an absent
      `next_page_token`, not a short page, as

      the end of the list. Binding one of these to an app or entitlement returns
      400.
paths:
  /v1/access-reviews/{review_uuid}/apps/{app_review_uuid}/subjects/{subject_uuid}:
    get:
      tags:
        - Access Reviews
      summary: Get Subject
      description: >-
        Read one subject: what is being reviewed, who is reviewing it, what they
        decided, and what removal that decision led to.


        What a subject is follows from the app review's type — an accounts
        review reviews accounts, an entitlements review reviews the entitlements
        an account holds — and `subject_type` says which. An entitlement subject
        also names the account it belongs to, so one shape serves both.


        `removal.status` is current even while the removal runs. Evidence is
        reported beside `removal` rather than in it (`is_evidence_attached`,
        `evidence_required_by`, and the files under `expand=evidence`), since an
        approved subject can owe evidence too.


        `removal.error` says which capability failed and what the integration
        reported. It does not say whether retrying will help; a removal waiting
        on a person clears only once that person acts.
      operationId: getSubject
      parameters:
        - name: review_uuid
          in: path
          required: true
          schema:
            type: string
            description: The access review's ID.
            title: Review Uuid
          description: The access review's ID.
        - name: app_review_uuid
          in: path
          required: true
          schema:
            type: string
            description: >-
              The app review's ID. An app review is one app within the access
              review that `review_uuid` names.
            title: App Review Uuid
          description: >-
            The app review's ID. An app review is one app within the access
            review that `review_uuid` names.
        - name: subject_uuid
          in: path
          required: true
          schema:
            type: string
            description: >-
              The subject's ID. A subject is one thing under review in the app
              review that `app_review_uuid` names: an account, or one
              entitlement an account holds.
            title: Subject Uuid
          description: >-
            The subject's ID. A subject is one thing under review in the app
            review that `app_review_uuid` names: an account, or one entitlement
            an account holds.
        - name: expand
          in: query
          required: false
          schema:
            anyOf:
              - items:
                  type: string
                type: array
              - type: 'null'
            description: >-
              Comma-separated related data to load: `ai_recommendation`,
              `evidence`, `removal.itsm_ticket`. A field not asked for is absent
              from the response rather than null.
            title: Expand
          description: >-
            Comma-separated related data to load: `ai_recommendation`,
            `evidence`, `removal.itsm_ticket`. A field not asked for is absent
            from the response rather than null.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subject'
        '400':
          description: >-
            Validation error — an unsupported `expand` field, or
            `expand=ai_recommendation` on an app review with AI Assist turned
            off (`app_review.ai_disabled`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
          description: Unauthorized
        '403':
          description: Forbidden — the caller may not read this app review.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '404':
          description: >-
            Not found — no campaign with this UUID in your organization
            (`access_review.not_found`), the campaign holds no app review with
            this UUID (`app_review.not_found`), or the app review holds no
            subject with this UUID (`subject.not_found`). A resource under a
            different parent reports the same code as one that never existed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
          description: Conflict
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
          description: Too Many Requests
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
          description: Internal Server Error
      security:
        - HTTPBearer: []
components:
  schemas:
    Subject:
      properties:
        id:
          type: string
          title: Id
          description: The subject's ID.
        subject_type:
          $ref: '#/components/schemas/SubjectType'
          description: >-
            Whether this subject is an account or one entitlement held by an
            account. Follows from the app review's type, so every subject under
            one app review carries the same value.
        account_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Account Name
          description: The account's name in the app being reviewed.
        identity:
          anyOf:
            - $ref: '#/components/schemas/User'
            - type: 'null'
          description: >-
            The Lumos user the account belongs to. Null for an account that
            matched no user — an unmatched account is still reviewed.
        reviewers:
          items:
            $ref: '#/components/schemas/SubjectAssignee'
          type: array
          title: Reviewers
          description: >-
            Who is assigned to decide this subject. Empty before reviewers are
            assigned.
        entitlement:
          anyOf:
            - $ref: '#/components/schemas/SubjectEntitlement'
            - type: 'null'
          description: >-
            The entitlement under review. Present only when `subject_type` is
            `account-entitlement`.
        decision:
          type: string
          enum:
            - approve-access
            - modify-access
            - pending
            - reject-access
            - reviewing-permissions
          title: Decision
          description: What the reviewer decided. `pending` until someone decides.
        decided_by:
          anyOf:
            - $ref: '#/components/schemas/User'
            - type: 'null'
          description: Who made the decision.
        decided_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Decided At
          description: When the decision was made.
        note:
          anyOf:
            - type: string
            - type: 'null'
          title: Note
          description: The note the reviewer left for the auditor alongside the decision.
        removal:
          anyOf:
            - $ref: '#/components/schemas/SubjectRemoval'
            - type: 'null'
          description: >-
            The removal this decision led to. Null when the decision leaves the
            access in place, or when removals have not started.
        is_evidence_attached:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Is Evidence Attached
          description: >-
            Whether any evidence is attached to this subject. Whether any is
            owed is `evidence_required_by`.
        evidence_required_by:
          anyOf:
            - $ref: '#/components/schemas/EvidenceRequiredBy'
            - type: 'null'
          description: >-
            Why evidence is owed, as the highest-ranked reason that applies:
            `review-setting-all-removals` when the app review asks for evidence
            on every removal, `decision-reason` when the decision's reason does,
            `manual-action` when a person acted on the removal or still must,
            `no-removal-request` when no workflow could carry the removal. Null
            when nothing asks for evidence. Read apart from `removal`, so an
            approved subject whose decision reason asks for evidence carries it
            too.
        evidence:
          anyOf:
            - items:
                $ref: '#/components/schemas/SubjectEvidence'
              type: array
            - type: 'null'
          title: Evidence
          description: >-
            Files attached as evidence for this subject, identifying fields only
            and no download link. Requires `expand=evidence`.
        ai_recommendation:
          anyOf:
            - $ref: '#/components/schemas/AiRecommendation'
            - type: 'null'
          description: >-
            What AI Assist recommended for this subject, if it reached one.
            Requires `expand=ai_recommendation`.
      type: object
      required:
        - id
        - subject_type
        - decision
      title: Subject
      description: 'One thing under review: an account, or one of an account''s entitlements.'
    ApiErrorEnvelope:
      properties:
        error:
          $ref: '#/components/schemas/ApiError'
          description: The error that caused this response.
      type: object
      required:
        - error
      title: ApiErrorEnvelope
      description: >-
        The V1 error response body. Every error nests under `error`, so an error
        body is

        recognizable by its shape, not only its status code.
    SubjectType:
      type: string
      enum:
        - account
        - account-entitlement
      title: SubjectType
    User:
      properties:
        id:
          type: string
          title: Id
          description: The ID of this user.
        email:
          anyOf:
            - type: string
            - type: 'null'
          title: Email
          description: The email of this user.
        given_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Given Name
          description: The given name of this user.
        family_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Family Name
          description: The family name of this user.
        status:
          anyOf:
            - type: string
              enum:
                - staged
                - active
                - suspended
                - inactive
            - type: 'null'
          title: Status
          description: The status of this user.
      type: object
      required:
        - id
      title: User
    SubjectAssignee:
      properties:
        id:
          anyOf:
            - type: string
            - type: 'null'
          title: Id
          description: >-
            The assigned user's ID. Null when a group holds the assignment
            rather than a user — see `group_id`.
        group_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Group Id
          description: The assigned group's ID, when a group holds the assignment.
        group_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Group Name
          description: The assigned group's name, when a group holds the assignment.
        email:
          anyOf:
            - type: string
            - type: 'null'
          title: Email
          description: The assigned user's email address.
        given_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Given Name
          description: The assigned user's given name.
        family_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Family Name
          description: The assigned user's family name.
      type: object
      title: SubjectAssignee
    SubjectEntitlement:
      properties:
        id:
          anyOf:
            - type: string
            - type: 'null'
          title: Id
          description: The entitlement's ID.
        label:
          anyOf:
            - type: string
            - type: 'null'
          title: Label
          description: The entitlement's name in the app.
        type:
          anyOf:
            - type: string
            - type: 'null'
          title: Type
          description: The entitlement's type in the app, e.g. `Role` or `Group`.
      type: object
      title: SubjectEntitlement
    SubjectRemoval:
      properties:
        status:
          $ref: '#/components/schemas/RemovalStatus'
          description: >-
            Where the removal stands, current even while the removal runs.
            `waiting-manual-step` is a workflow blocked on a person;
            `manual-removal` is a removal left to a person with no workflow to
            track it. It describes the removal only: a finished removal reads
            `completed` while evidence of it is still owed, which the subject's
            `evidence_required_by` reports.
        method:
          anyOf:
            - $ref: '#/components/schemas/RemovalMethod'
            - type: 'null'
          description: >-
            How a completed removal was carried out: `automated` when the
            workflow did it with no manual task, `manual` when a person did.
            Null until the removal is `completed`.
        assignees:
          items:
            $ref: '#/components/schemas/SubjectAssignee'
          type: array
          title: Assignees
          description: >-
            Who is responsible for carrying out a removal that a person
            performs. An entitlement also lists the removers assigned on its
            account, whose remit covers every entitlement bundled under it.
        error:
          anyOf:
            - $ref: '#/components/schemas/RemovalError'
            - type: 'null'
          description: >-
            Why the last removal attempt failed, if one did. Null when the run
            recorded no reason, which a `failed` status does not by itself
            guarantee.
        itsm_ticket:
          anyOf:
            - $ref: '#/components/schemas/RemovalItsmTicket'
            - type: 'null'
          description: >-
            The ITSM ticket tracking this removal. Requires
            `expand=removal.itsm_ticket`.
      type: object
      required:
        - status
      title: SubjectRemoval
    EvidenceRequiredBy:
      type: string
      enum:
        - review-setting-all-removals
        - decision-reason
        - manual-action
        - no-removal-request
      title: EvidenceRequiredBy
    SubjectEvidence:
      properties:
        filename:
          type: string
          title: Filename
          description: The file's name as uploaded.
        content_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Content Type
          description: >-
            The file's media type, inferred from its extension. Null when the
            extension maps to no known type.
        description:
          anyOf:
            - type: string
            - type: 'null'
          title: Description
          description: The note the uploader attached.
        uploaded_by:
          anyOf:
            - $ref: '#/components/schemas/User'
            - type: 'null'
          description: Who attached the file.
        uploaded_at:
          type: string
          format: date-time
          title: Uploaded At
          description: When the file was attached.
      type: object
      required:
        - filename
        - uploaded_at
      title: SubjectEvidence
      description: One file attached as evidence for a subject. Evidence files have no ID.
    AiRecommendation:
      properties:
        decision:
          type: string
          enum:
            - auto-approve
            - auto-reject
            - unclear
            - suggest-approve
            - suggest-reject
          title: Decision
          description: What the recommendation is, and how firmly it is held.
        decision_category:
          anyOf:
            - type: string
            - type: 'null'
          title: Decision Category
          description: >-
            The kind of finding behind the recommendation, e.g. `Unusual
            Access`. Free text — group on it, but do not branch on a fixed set.
        reasoning:
          anyOf:
            - type: string
            - type: 'null'
          title: Reasoning
          description: Why the recommendation was made, in plain language.
      type: object
      required:
        - decision
      title: AiRecommendation
    ApiError:
      properties:
        detail:
          type: string
          title: Detail
          description: Human-readable summary of the error.
        type:
          $ref: '#/components/schemas/ErrorType'
          description: >-
            Category:
            validation|authentication|permission|not_found|conflict|rate_limited|runtime.
        code:
          type: string
          title: Code
          description: Stable machine-readable error code; branch on this, not 'detail'.
        errors:
          items:
            $ref: '#/components/schemas/ApiErrorField'
          type: array
          title: Errors
          description: Field-level errors; empty for non-validation errors.
      type: object
      required:
        - detail
        - type
        - code
      title: ApiError
      description: The V1 error object — the contents of the envelope's `error` field.
    RemovalStatus:
      type: string
      enum:
        - in-progress
        - waiting-manual-step
        - manual-removal
        - failed
        - completed
      title: RemovalStatus
    RemovalMethod:
      type: string
      enum:
        - automated
        - manual
      title: RemovalMethod
    RemovalError:
      properties:
        code:
          type: string
          title: Code
          description: >-
            What failed: the removal capability on a directly-attempted removal
            (e.g. `DEPROVISION`), or the workflow step on a workflow-driven one.
            Reported as the removal run recorded it rather than mapped to a
            fixed set, so a new capability or step surfaces here without an API
            change. Empty when the run recorded no name for it.
        message:
          type: string
          title: Message
          description: What the integration or the workflow reported back.
      type: object
      required:
        - code
        - message
      title: RemovalError
    RemovalItsmTicket:
      properties:
        external_id:
          type: string
          title: External Id
          description: The ticket's ID in the ITSM system.
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
          description: A link to the ticket.
      type: object
      required:
        - external_id
      title: RemovalItsmTicket
    ErrorType:
      type: string
      enum:
        - validation
        - authentication
        - permission
        - not_found
        - conflict
        - rate_limited
        - runtime
      title: ErrorType
    ApiErrorField:
      properties:
        field:
          type: string
          title: Field
          description: Input field this error refers to, e.g. 'steps[2].inputs.group_id'.
        code:
          type: string
          title: Code
          description: Stable machine-readable code for this field error.
        message:
          type: string
          title: Message
          description: Human-readable description of the field error.
      type: object
      required:
        - field
        - code
        - message
      title: ApiErrorField
      description: A single field-level error (used for validation failures).
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````