> ## 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.

# Set up an app in the AppStore

> Add an app to the AppStore through v1: create or connect it, give it entitlements, decide who approves, configure how people request it, and check what they see.

Setting up an app for self-service access spans five v1 resources:
[integrations](https://docs.lumos.com/reference/v1/objects/integration.md), [apps](https://docs.lumos.com/reference/v1/objects/app.md),
[entitlements](https://docs.lumos.com/reference/v1/objects/entitlement.md), the app's AppStore settings, and
[workflows](https://docs.lumos.com/reference/v1/objects/workflow.md). This guide puts the pieces those pages describe in
order. It covers both an app connected through a Lumos integration and a custom app whose accounts
you maintain yourself.

You can set up a custom app entirely through the API, but connecting an app through an integration
also needs the Lumos UI, as steps 1-3 describe.

## Before you start

Create your API token as a user with the Admin role. A token can do only what the user who created
it can do, as
[What a token is allowed to do](https://docs.lumos.com/reference/v1/authentication.md#what-a-token-is-allowed-to-do)
describes. Of the built-in roles, only Admin can create or connect apps. App Admin can configure the
AppStore for the apps they administer.

Run the steps below in order. Before you set `default_entitlement` or
`request_validation_webhook_uuid`, you must have the entitlement's or the inline webhook's ID.

## Setting up the app

**1. Create or connect the app**

**To connect an app through an integration**, find the integration's `app_class_id` with
[List Integrations](https://docs.lumos.com/api-reference/v1/integrations/list-integrations.md). Then read the credentials it
needs from
[Get Integration Connection Schema](https://docs.lumos.com/api-reference/v1/integrations/get-integration-connection-schema.md).
Its `auth_schema` describes `auth`, and its `settings_schema` describes `settings`. Send
`app_class_id`, `auth`, and `settings` to [Create App](https://docs.lumos.com/api-reference/v1/apps/create-app.md).

```bash theme={null}
curl -s -X POST 'https://api.lumos.com/v1/apps' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "app_class_id": "okta.com",
    "auth": { "api_key": "your_okta_api_key" },
    "settings": { "app_instance_identifier": "myorg.okta.com" }
  }'
```

Create App returns `201` with the app. Save its `id`, because every later step uses it. If Create
App returns `422` with `code` set to `app.api_unsupported`, the API can't connect this
integration, so connect it in the Lumos UI.
[Create a custom app or connect an integration](https://docs.lumos.com/reference/v1/objects/app.md#create-a-custom-app-or-connect-an-integration)
lists those integrations, and what to do about an on-prem integration.

For an integration that needs browser consent, send `auth: {}`. Then finish connecting the app in
the Lumos UI.

**To create a custom app**, an app that Lumos has no integration for, send `label_override`,
`category_override`, and `description_override` to
[Create App](https://docs.lumos.com/api-reference/v1/apps/create-app.md). Don't send `app_class_id`. `category_override`
must be a `label` from
[List App Categories](https://docs.lumos.com/api-reference/v1/app-categories/list-app-categories.md).

```bash theme={null}
curl -s -X POST 'https://api.lumos.com/v1/apps' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "label_override": "Deploy Dashboard",
    "category_override": "Developers",
    "description_override": "Internal deploy dashboard."
  }'
```

Lumos makes the user who created the token the new app's admin.

**2. Give it accounts and entitlements**

**An app connected through an integration** gets its accounts and entitlements from syncs. Its
first sync waits for a review of the app's identity matching rules. To start it without the review,
send `skip_first_sync_review: true` to [Trigger App Sync](https://docs.lumos.com/api-reference/v1/apps/trigger-app-sync.md). To
review the rules first, start it from the Lumos UI instead.

```bash theme={null}
curl -s -X POST 'https://api.lumos.com/v1/apps/2b3c4d5e-6f70-8901-bcde-f12345678901:sync' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{ "sync_type": "full-sync", "skip_first_sync_review": true }'
```

Trigger App Sync returns an operation to poll, as
[Syncs and their status](https://docs.lumos.com/reference/v1/objects/app.md#syncs-and-their-status) describes.
[The first sync](https://docs.lumos.com/reference/v1/objects/app.md#the-first-sync) explains when you must send the flag
again.

**A custom app** has no integration, so you supply both. Send its accounts with
[Upload Accounts](https://docs.lumos.com/api-reference/v1/accounts/upload-accounts.md).
[Uploading accounts](https://docs.lumos.com/reference/v1/objects/account.md#uploading-accounts) shows the body. Then add each
entitlement people can request with
[Create Entitlement](https://docs.lumos.com/api-reference/v1/entitlements/create-entitlement.md):

```bash theme={null}
curl -s -X POST 'https://api.lumos.com/v1/entitlements' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "app_id": "2b3c4d5e-6f70-8901-bcde-f12345678901",
    "label": "Deployer"
  }'
```

Step 5 shows or hides each entitlement.
[Creating, updating, and deleting](https://docs.lumos.com/reference/v1/objects/entitlement.md#creating-updating-and-deleting)
explains which entitlements start visible.

**3. Give it an admin and approvers**

Check the app's admins with `expand=admins`:

```bash theme={null}
curl -s 'https://api.lumos.com/v1/apps/2b3c4d5e-6f70-8901-bcde-f12345678901?expand=admins' \
  --header 'Authorization: Bearer lsk_your_token'
```

A custom app you created already has an admin. For an app connected through an integration, set
its admins with [Set App Admins](https://docs.lumos.com/api-reference/v1/apps/set-app-admins.md). Send the complete list,
because it replaces the app's admins:

```bash theme={null}
curl -s -X PUT 'https://api.lumos.com/v1/apps/2b3c4d5e-6f70-8901-bcde-f12345678901/admins' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "admins": [
      { "id": "5e6f7081-9203-1234-ef12-345678901234", "type": "user" },
      { "id": "4d5e6f70-8192-0123-def0-234567890123", "type": "group" }
    ]
  }'
```

The app needs at least one admin before you add it to the AppStore in step 4. Otherwise that call
returns `409` with `code` set to `app.admin_required`.

While the app has no approval workflow bound, Lumos uses the app's approval settings in the Lumos
UI.

> [!WARNING]
>
> By default, requests for a new app need no approval. Before you make the app visible in step 6,
> do one of these:
>
> * Set its approvers in the Lumos UI.
> * Bind an approval workflow with
>   [Set App Approval Workflow](https://docs.lumos.com/api-reference/v1/apps/set-app-approval-workflow.md).

[The Workflow object](https://docs.lumos.com/reference/v1/objects/workflow.md) explains what a workflow is, and
[Bound workflows](https://docs.lumos.com/reference/v1/objects/app.md#bound-workflows) covers the provisioning workflows,
which work the same way.

**4. Add it to the AppStore, still hidden**

Add the app to the AppStore with
[Update AppStore Settings](https://docs.lumos.com/api-reference/v1/apps/update-appstore-settings.md). Set
`catalog_visibility` to `hidden` so that requesters don't see it yet. An entitlement's AppStore
settings exist only while its app is in the AppStore, so add the app before step 5:

```bash theme={null}
curl -s -X PATCH 'https://api.lumos.com/v1/apps/2b3c4d5e-6f70-8901-bcde-f12345678901/appstore-settings' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "in_app_store": true,
    "catalog_visibility": "hidden"
  }'
```

A new app's `catalog_visibility` is already `hidden`. If the app was already visible, this call
hides it.

**5. Configure its entitlements**

List the entitlements by visibility with
[List App Entitlements](https://docs.lumos.com/api-reference/v1/apps/list-app-entitlements.md).
[Finding entitlements](https://docs.lumos.com/reference/v1/objects/entitlement.md#finding-entitlements) explains the
`visible_in_appstore` filter.

Show or hide each one with
[Update Entitlement AppStore Settings](https://docs.lumos.com/api-reference/v1/entitlements/update-entitlement-appstore-settings.md):

```bash theme={null}
curl -s -X PATCH 'https://api.lumos.com/v1/entitlements/3c4d5e6f-7081-9012-cdef-123456789012/appstore-settings' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{ "visible_in_appstore": true }'
```

For an entitlement without AppStore settings, this call returns `404`. To make that access
requestable anyway, create a separate entitlement for it with
[Create Entitlement](https://docs.lumos.com/api-reference/v1/entitlements/create-entitlement.md).
[AppStore settings](https://docs.lumos.com/reference/v1/objects/entitlement.md#appstore-settings) on the Entitlement object
explains which entitlements have AppStore settings, and lists the other fields.

**6. Make it visible**

Set `catalog_visibility` to `visible` with Update AppStore Settings. You can change other settings
in the same call:

```bash theme={null}
curl -s -X PATCH 'https://api.lumos.com/v1/apps/2b3c4d5e-6f70-8901-bcde-f12345678901/appstore-settings' \
  --header 'Authorization: Bearer lsk_your_token' \
  --header 'Content-Type: application/json' \
  --data '{
    "catalog_visibility": "visible",
    "request_instructions": "Request the role your team lead approved."
  }'
```

[AppStore settings](https://docs.lumos.com/reference/v1/objects/app.md#appstore-settings) on the App object describes every
field.

**7. Check what a requester sees**

[Get AppStore Catalog](https://docs.lumos.com/api-reference/v1/apps/get-appstore-catalog.md) lists the apps one user can
request.
[Get App Entitlement AppStore Catalog](https://docs.lumos.com/api-reference/v1/apps/get-app-entitlement-appstore-catalog.md)
lists what they can request on one app. Both results depend on that user's groups.

To see someone else's catalog, pass their user `id` from
[List Users](https://docs.lumos.com/api-reference/v1/users/list-users.md) as `target_user_uuid`. Of the built-in roles,
Admin, Read Only Admin, and AppStore Read Only Admin can pass it to both endpoints. App Admin can
pass it to the entitlement catalog for the apps they administer. A custom role can also allow it.

```bash theme={null}
curl -s 'https://api.lumos.com/v1/apps/appstore-catalog?target_user_uuid=5e6f7081-9203-1234-ef12-345678901234&search=Deploy' \
  --header 'Authorization: Bearer lsk_your_token'
```

A listing without `search` omits apps whose `catalog_visibility` is `search-only`, so search by
name when you check a `search-only` app. The catalog also omits apps whose allowed requester
groups don't include the user.

The entitlement catalog returns an empty page, not `404`, while the app isn't in the AppStore or
its `catalog_visibility` is `hidden`. To see every app in the AppStore, call
[List Apps](https://docs.lumos.com/api-reference/v1/apps/list-apps.md) with `in_app_store=true`. Add `catalog_visibility`
(`visible`, `search-only`, or `hidden`) to filter by visibility.
[Access requests and tasks](https://docs.lumos.com/reference/v1/guides/access-requests-and-tasks.md#file-a-request-and-follow-it)
covers filing a request and following it.

## Removing an app from the AppStore

Send `in_app_store: false` to
[Update AppStore Settings](https://docs.lumos.com/api-reference/v1/apps/update-appstore-settings.md). The app keeps its
settings, so sending `true` again restores it with the same settings. To remove the app from Lumos
instead, disconnect or delete it.
[Creating, updating, disconnecting, and deleting apps](https://docs.lumos.com/reference/v1/objects/app.md#creating-updating-disconnecting-and-deleting-apps)
explains the difference.
