Syncing Integrations via API

The sync endpoint lets you trigger an integration sync on demand — a fresh pull of an app's accounts and entitlements into Lumos — from a script, a CI pipeline, or a scheduler. You don't need to manage the integration's connection through the API to use it: it works for integrations connected in the Lumos UI, via the Integrations API, or via Terraform.

Overview

A sync is how Lumos pulls an integration's current data - accounts, groups, and entitlements - so what you see in Lumos matches what's in the app. Lumos already syncs every connected integration on a regular schedule, and connecting or reconnecting an integration triggers a sync automatically.

The sync endpoint covers the moments in between: when you've just made changes in the app and want them reflected in Lumos now, rather than at the next scheduled sync. Typical triggers:

  • Right after automation finishes a change in the app - an offboarding wave, a role migration, a department reorg.
  • Right after terraform apply connects an integration, from the same CI pipeline.
  • Before kicking off an access review, so reviewers see current data.
  • On your own schedule, if you want a specific integration refreshed more often.

Before you start

You need:

  • An API token. Create one in the Lumos UI under Settings → API Tokens. The token is shown once - copy it somewhere safe. Examples below read it from a LUMOS_API_TOKEN environment variable.
  • Permission to manage integrations. A token acts as the user who created it, so that user must be an admin with permission to manage integrations. Without it, calls return 403.
  • A connected integration. Connected in the Lumos UI, via the API, or via Terraform — any of them works.
  • The base URL https://api.lumos.com. All paths below are relative to it.

Authentication

Send your token as a bearer token in the Authorization header on every request:

curl -s https://api.lumos.com/v1/apps \
  -H "Authorization: Bearer $LUMOS_API_TOKEN"

A request with a missing or invalid token returns 401.

Concept-to-endpoint map

I want to...EndpointNotes
Find the integration's idGET /v1/appsPaginated; ?disconnected=false narrows to connected apps.
Trigger a sync on demandPOST /v1/apps/{id}/syncRuns a full sync. 409 while one is already running.

Core workflow

1. Find the integration's id

Syncs are triggered by the integration's id (a UUID). List your apps and pick the one you want — ?disconnected=false narrows the list to connected ones:

curl -s "https://api.lumos.com/v1/apps?disconnected=false" \
  -H "Authorization: Bearer $LUMOS_API_TOKEN"
{
  "items": [
    {
      "id": "7d3b1c2e-8f4a-4c1d-9b2e-1a2b3c4d5e6f",
      "app_class_id": "okta.com",
      "instance_id": "your-org.okta.com",
      "disconnected": false
    }
  ],
  "total": 1,
  "page": 1,
  "size": 50,
  "pages": 1
}

(Response trimmed to the relevant fields.)

If you connected the integration programmatically you already have this id: it's the id returned by the connect call, and the id attribute of the lumos_app Terraform resource (terraform state show lumos_app.okta).

2. Trigger the sync

Call the sync endpoint with the sync_type you want. Today the only supported value is full_sync — a full re-pull of the integration's accounts, groups, and entitlements:

curl -s -X POST https://api.lumos.com/v1/apps/$INTEGRATION_ID/sync \
  -H "Authorization: Bearer $LUMOS_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "sync_type": "full_sync" }'

Precondition: the integration is connected (or its last sync failed — retrying after a failure is allowed).

A 202 Accepted confirms the sync was launched:

{
  "app_id": "7d3b1c2e-8f4a-4c1d-9b2e-1a2b3c4d5e6f",
  "sync_type": "full_sync",
  "status": "SYNCING"
}

sync_type is required even though there's one value today — new sync kinds will be added as additional values, so your request shape won't change.

3. Understand what happens next

The sync runs asynchronously — the 202 means it was launched, not that it finished. How long it takes depends on the integration and the amount of data; when it completes, the refreshed accounts and entitlements are visible in Lumos.

Only one sync runs at a time per integration. If a sync is already in progress — including a scheduled one Lumos started — the call returns 409 Conflict:

{
  "detail": "A sync is currently running for this app. Wait for it to finish, then retry.",
  "type": "conflict",
  "code": "conflict",
  "errors": []
}

Wait for the running sync to finish, then retry. Since the running sync is already pulling the app's current data, a 409 usually means the refresh you wanted is underway anyway.

Handling errors

Errors return the relevant HTTP status and a JSON body with a human-readable detail, plus machine-readable type and code fields your automation can branch on.

StatusCauseWhat to do
400 Bad RequestThe request body failed validation — a missing or unsupported sync_type.Send {"sync_type": "full_sync"}; the errors[] list names the offending field.
401 UnauthorizedMissing or invalid API token.Send a valid Authorization: Bearer token.
403 ForbiddenYour user can't manage integrations.Use a token for an admin with integration permissions.
404 Not FoundNo integration with that id in your domain.Check the id against GET /v1/apps.
409 ConflictA sync is already running; or the integration isn't connected yet; or its first sync is deferred pending an admin review in the Lumos UI.Wait and retry; connect the integration first; or complete the review in the Lumos UI.
422 Unprocessable EntityThe app is a manual/CSV app, which can't be synced via the API.Manual/CSV apps are updated by uploading data instead.
502 Bad GatewayThe sync failed to launch downstream.Retry; if it persists, contact support.

Next steps



Did this page help you?