---
updatedAt: 2026-04-29T19:37:06.000Z
agentTools:
  projectIndex: https://developers.lumos.com/llms.txt
---

# Add Apps To Access Review

Add apps to an existing access review. Allowed on any review that is not yet `COMPLETED`. Soft-errors on invalid or duplicate domain app UUIDs — per-app failures are returned in the `errors` array rather than raising.

# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Lumos",
    "description": "\n    The Lumos API gives you the building blocks to administer and extend Lumos programmatically.\n    Our REST API provides a management interface for the AppStore and a read interface\n    for the Lumos Core.\n    Go to https://developers.lumos.com to see our complete documentation.\n",
    "version": "0.1.0"
  },
  "servers": [
    {
      "url": "https://api.lumos.com"
    }
  ],
  "paths": {
    "/access_reviews/{access_review_id}/apps": {
      "post": {
        "tags": [
          "Access Reviews"
        ],
        "summary": "Add Apps To Access Review",
        "description": "Add apps to an existing access review. Allowed on any review that is not yet `COMPLETED`. Soft-errors on invalid or duplicate domain app UUIDs — per-app failures are returned in the `errors` array rather than raising.",
        "operationId": "addAppsToAccessReview",
        "security": [
          {
            "HTTPBearer": []
          }
        ],
        "parameters": [
          {
            "name": "access_review_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Access Review Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddAppsInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddAppsOutput"
                }
              }
            }
          },
          "400": {
            "description": "Validation error — the request violated a business rule (e.g. duplicate review name, deadline in the past, review not in the required status for this operation)."
          },
          "403": {
            "description": "Forbidden — the caller lacks permission to create or manage access reviews. Requires the Access Review Administrator or App Admin role on the domain."
          },
          "404": {
            "description": "Not found — the referenced review / app does not exist."
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AccessReviewDomainAppErrorOutput": {
        "properties": {
          "app_id": {
            "type": "string",
            "title": "App Id",
            "description": "UUID of the domain app that could not be added."
          },
          "error": {
            "type": "string",
            "title": "Error",
            "description": "Description of why the app could not be added."
          }
        },
        "type": "object",
        "required": [
          "app_id",
          "error"
        ],
        "title": "AccessReviewDomainAppErrorOutput"
      },
      "AccessReviewDomainAppInput": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "UUID of the domain app to include in this review."
          },
          "review_type": {
            "$ref": "#/components/schemas/ReviewType",
            "description": "What to review for this app.",
            "default": "ENTITLEMENTS"
          },
          "scope_filters": {
            "anyOf": [
              {
                "items": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ScalarScopeFilterInput"
                    },
                    {
                      "$ref": "#/components/schemas/CustomAttributeScopeFilterInput"
                    },
                    {
                      "$ref": "#/components/schemas/DatetimeScopeFilterInput"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "group",
                    "mapping": {
                      "ACCESS_APPROVED_AT": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCESS_GRANTED_AT": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCESS_LENGTH": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCESS_PROVISIONED_AT": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCESS_REQUESTED_AT": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCOUNT": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCOUNT_DELTA": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCOUNT_ENTITLEMENT": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCOUNT_SOURCE": "#/components/schemas/ScalarScopeFilterInput",
                      "ACCOUNT_STATUS": "#/components/schemas/ScalarScopeFilterInput",
                      "CATEGORIES": "#/components/schemas/ScalarScopeFilterInput",
                      "CUSTOM_ATTRIBUTE": "#/components/schemas/CustomAttributeScopeFilterInput",
                      "EMAIL_DOMAIN": "#/components/schemas/ScalarScopeFilterInput",
                      "EMPLOYMENT_STATUS": "#/components/schemas/ScalarScopeFilterInput",
                      "ENTITLEMENT_TAG": "#/components/schemas/ScalarScopeFilterInput",
                      "IDENTITY": "#/components/schemas/ScalarScopeFilterInput",
                      "LAST_ACTIVITY": "#/components/schemas/DatetimeScopeFilterInput",
                      "LAST_LOGIN": "#/components/schemas/DatetimeScopeFilterInput",
                      "SOD_POLICY": "#/components/schemas/ScalarScopeFilterInput",
                      "TEAM": "#/components/schemas/ScalarScopeFilterInput",
                      "UNMATCHED_ACCOUNTS": "#/components/schemas/ScalarScopeFilterInput",
                      "USER_OR_GROUP": "#/components/schemas/ScalarScopeFilterInput"
                    }
                  }
                },
                "type": "array",
                "maxItems": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Scope Filters",
            "description": "Scope filters to limit which accounts/entitlements are included in this review. Filters within the same group are OR'd; filters across groups are AND'd. Capped at 1000 filters per app."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "id"
        ],
        "title": "AccessReviewDomainAppInput"
      },
      "AccessReviewDomainAppOutput": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "UUID of this access review domain app record."
          },
          "url": {
            "type": "string",
            "title": "Url",
            "description": "Link to this app review in the Lumos web app."
          },
          "domain_app_id": {
            "type": "string",
            "title": "Domain App Id",
            "description": "UUID of the domain app being reviewed."
          },
          "domain_app_name": {
            "type": "string",
            "title": "Domain App Name",
            "description": "Display name of the domain app."
          },
          "domain_app_sources": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Domain App Sources",
            "description": "List of sources for the domain app."
          },
          "status": {
            "type": "string",
            "enum": [
              "IN_PREPARATION",
              "ASSIGNING_REVIEWERS",
              "IN_PROGRESS",
              "COMPLETED",
              "WAITING_FOR_MANUAL_ACTION",
              "DELETED"
            ],
            "title": "Status",
            "description": "Status of this app within the review."
          },
          "review_type": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReviewType"
              },
              {
                "type": "null"
              }
            ],
            "description": "What is being reviewed: ENTITLEMENTS or ACCOUNTS."
          },
          "app_last_synced_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "App Last Synced At",
            "description": "When the app data was last synced."
          },
          "last_synced_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Synced At",
            "description": "When this review's data was last synced."
          },
          "account_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Count",
            "description": "Number of accounts in scope for this app."
          },
          "launched_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Launched At",
            "description": "When this app's review was launched."
          },
          "completed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Completed At",
            "description": "When this app's review was completed."
          },
          "scope_filters": {
            "anyOf": [
              {
                "items": {
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scope Filters",
            "description": "Scope filters applied to this app's review."
          }
        },
        "type": "object",
        "required": [
          "id",
          "url",
          "domain_app_id",
          "domain_app_name",
          "domain_app_sources",
          "status"
        ],
        "title": "AccessReviewDomainAppOutput"
      },
      "AddAppsInput": {
        "properties": {
          "apps": {
            "items": {
              "$ref": "#/components/schemas/AccessReviewDomainAppInput"
            },
            "type": "array",
            "maxItems": 200,
            "title": "Apps",
            "description": "List of domain apps to add to the access review. Capped at 200 entries per the Access Review scale limits (technically-supported tier)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "apps"
        ],
        "title": "AddAppsInput",
        "examples": [
          {
            "apps": [
              {
                "id": "00000000-0000-0000-0000-000000000002",
                "review_type": "ENTITLEMENTS"
              }
            ]
          }
        ]
      },
      "AddAppsOutput": {
        "properties": {
          "added_apps": {
            "items": {
              "$ref": "#/components/schemas/AccessReviewDomainAppOutput"
            },
            "type": "array",
            "title": "Added Apps",
            "description": "Apps that were successfully added to the access review."
          },
          "errors": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/AccessReviewDomainAppErrorOutput"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Errors",
            "description": "Per-app errors for any domain apps that could not be added (invalid, not connected, or already present)."
          }
        },
        "type": "object",
        "required": [
          "added_apps"
        ],
        "title": "AddAppsOutput"
      },
      "CustomAttributeScopeFilterInput": {
        "properties": {
          "group": {
            "type": "string",
            "enum": [
              "CUSTOM_ATTRIBUTE"
            ],
            "const": "CUSTOM_ATTRIBUTE",
            "title": "Group",
            "description": "Always CUSTOM_ATTRIBUTE."
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "title": "Name",
            "description": "Custom attribute label (e.g. 'Department'). Matches the label from scope_options."
          },
          "label": {
            "type": "string",
            "maxLength": 255,
            "title": "Label",
            "description": "Human-readable display label."
          },
          "value": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "Value",
            "description": "Value to filter by for this custom attribute."
          },
          "type": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "Type",
            "description": "Attribute type (STRING, INTEGER, DATETIME, USER, GROUP, SINGLESELECT, MULTISELECT)."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "group",
          "name",
          "label"
        ],
        "title": "CustomAttributeScopeFilterInput",
        "description": "Scope filter for ``CUSTOM_ATTRIBUTE`` groups.\n\nCustom attributes are keyed by ``name`` (the attribute label, e.g.\n\"Department\"). ``type`` declares the attribute's type (STRING, INTEGER,\nDATETIME, USER, GROUP, SINGLESELECT, MULTISELECT)."
      },
      "DatetimeScopeFilterInput": {
        "properties": {
          "group": {
            "type": "string",
            "enum": [
              "LAST_LOGIN",
              "LAST_ACTIVITY"
            ],
            "title": "Group",
            "description": "Datetime scope filter group. Must be LAST_LOGIN or LAST_ACTIVITY."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Optional. If given, must equal the group's `name` from GET /access_reviews/scope_options (e.g. 'Last Login'); the stored filter always uses that name."
          },
          "after": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "After",
            "description": "Inclusive lower bound. Records where the datetime field is >= this value match."
          },
          "before": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Before",
            "description": "Inclusive upper bound. Records where the datetime field is <= this value match."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "group"
        ],
        "title": "DatetimeScopeFilterInput",
        "description": "Scope filter for datetime-valued groups (``LAST_LOGIN``, ``LAST_ACTIVITY``).\n\nProvide ``after``, ``before``, or both. Bounds are inclusive. At least one\nmust be set.\n\n- ``after`` alone: matches records where the field is on or after that timestamp.\n- ``before`` alone: matches records where the field is on or before that timestamp.\n- Both: matches records in the closed interval ``[after, before]``. If the\n  two bounds are equal, this matches records at exactly that timestamp."
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ReviewType": {
        "type": "string",
        "enum": [
          "ACCOUNTS",
          "ENTITLEMENTS"
        ],
        "title": "ReviewType"
      },
      "ScalarScopeFilterInput": {
        "properties": {
          "group": {
            "type": "string",
            "enum": [
              "ACCOUNT_ENTITLEMENT",
              "TEAM",
              "EMPLOYMENT_STATUS",
              "EMAIL_DOMAIN",
              "CATEGORIES",
              "ACCOUNT_DELTA",
              "ACCOUNT_STATUS",
              "ACCOUNT_SOURCE",
              "SOD_POLICY",
              "ACCESS_GRANTED_AT",
              "ACCESS_REQUESTED_AT",
              "ACCESS_APPROVED_AT",
              "ACCESS_PROVISIONED_AT",
              "ACCESS_LENGTH",
              "USER_OR_GROUP",
              "UNMATCHED_ACCOUNTS",
              "ENTITLEMENT_TAG",
              "IDENTITY",
              "ACCOUNT"
            ],
            "title": "Group",
            "description": "Scope filter group. Use DatetimeScopeFilterInput for LAST_LOGIN / LAST_ACTIVITY and CustomAttributeScopeFilterInput for CUSTOM_ATTRIBUTE."
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "title": "Name",
            "description": "Internal identifier for this filter item. For ACCOUNT_ENTITLEMENT this is the entitlement **type label** (e.g. 'Team', 'Role', 'Repo Access') — copy it from the matching item's `name` in GET /access_reviews/scope_options."
          },
          "label": {
            "type": "string",
            "maxLength": 255,
            "title": "Label",
            "description": "Human-readable display label."
          },
          "value": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "Value",
            "description": "The value to filter by. This must be the exact `value` of an item returned by GET /access_reviews/scope_options for this app — the machine-matchable identifier, **not** the human-readable `label`. For ACCOUNT_ENTITLEMENT the value is the entitlement's integration_specific_entitlement_id, which may be an opaque id (e.g. a numeric team id) rather than its display name. Posting a `label`, or any value not present in scope_options, is rejected."
          },
          "type": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 255
              },
              {
                "type": "null"
              }
            ],
            "title": "Type",
            "description": "Attribute type. Required for USER_OR_GROUP (must be 'USER' or 'GROUP'). Ignored for all other groups."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "group",
          "name",
          "label"
        ],
        "title": "ScalarScopeFilterInput",
        "description": "Scope filter for groups whose value is a simple string/UUID/enum.\n\nDatetime-valued groups (``LAST_LOGIN``, ``LAST_ACTIVITY``) use\n:class:`DatetimeScopeFilterInput`; ``CUSTOM_ATTRIBUTE`` uses\n:class:`CustomAttributeScopeFilterInput`."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    },
    "securitySchemes": {
      "HTTPBearer": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "Access Reviews",
      "description": "\nCreate and manage access review campaigns — scheduled reviews of who has access to what\nacross your connected apps.\n\n**Typical workflow for creating a review:**\n\n1. `GET /apps` — find the domain app UUIDs you want to review.\n2. `GET /access_reviews/scope_options?domain_app_id={id}` — discover available scope\n   filters (employment status, team, last login, etc.). Each returned `items` entry is a\n   ready-to-POST `scope_filters` payload; datetime and custom-attribute groups instead\n   expose a `filter_input_template`.\n3. `POST /access_reviews` with `apps` (optionally with `scope_filters` per app) —\n   creates the campaign.\n4. `GET /access_reviews/{id}` — poll until `status` transitions from `IN_PREPARATION`\n   to `IN_PROGRESS`.\n\n**After creation:**\n\n- `POST /access_reviews/{id}/apps` — add more apps while `status != COMPLETED`.\n- `PATCH /access_reviews/{id}` — update name / deadline / owner, or per-ARDA\n  `scope_filters` and removal action.\n- `DELETE /access_reviews/{id}` — soft-delete the whole campaign.\n- `DELETE /access_reviews/{id}/apps/{arda_id}` — soft-delete a single app from the\n  campaign.\n\nAll endpoints require an API token with the `access_reviews.create` or\n`access_reviews.view` permission (Access Review Administrator or App Admin role).\n"
    }
  ]
}
```