Skip to main content
Most app calls move to v1 with a new path and a few renamed fields. The AppStore is the exception. Its two v0 settings endpoints become one endpoint with a flat body, and some settings moved into workflows. App IDs don’t change. The id you stored from v0 is the id v1 uses in /v1/apps/{app_uuid}, so you don’t need to find apps again. Read What changes in v1 first for the conventions every endpoint shares, such as pagination and the error envelope.

Apps

The app object changed in a few places:
  • user_friendly_label is now label. label, category, description, logo_url, and website_url are read-only on v1. The create and update bodies take label_override instead of name, and the matching *_override fields for the others, as Display fields describes.
  • sources, links, request_instructions, and allow_multiple_permission_selection are no longer fields on the app object. The last two are AppStore settings now. Create App and Update App still accept request_instructions.
  • v1 adds approval_workflow, default_provisioning_workflow, default_deprovisioning_workflow, appstore_settings, post_approval_message, sync_status, and admins. admins appears only with expand=admins.
The App object page describes every field.

Values

v1 values are lowercase kebab-case labels, in responses, filters, and request bodies. A v0 value in a filter or body returns 400. v0’s request_flow.admins split admins into users and groups. v1’s admins is one list, and each entry’s type is user or group.
v0
v1
The list now uses page tokens. Read apps and next_page_token instead of items, total, and pages, as Pagination describes.

Creating and reconnecting

Create App returns 201, where v0 returned 200. It takes one of two bodies:
  • app_class_id with auth, settings, and version connects an integration.
  • label_override, category_override, and description_override create a custom app.
Sending auth, settings, or version without an integration’s app_class_id returns 400. Reconnecting moved from PUT /apps/{app_id} to Update App, the same endpoint that updates the app’s label_override and description_override. app_class_id is optional there. Lumos replaces the credential fields as one group instead of merging them, so send auth whenever you send settings or version. A body without auth returns 400, and Lumos keeps the stored credentials.
v0
v1
Sending credentials while a sync is running returns 409 with code set to app.sync_in_progress and a Retry-After header. v0 returned 429. Sending credentials for an app that wasn’t connected through the API also returns 409.

Disconnect versus delete

DELETE means something different on v1. DELETE /apps/{app_id} disconnected an app on v0. DELETE /v1/apps/{app_uuid} deletes it, and it removes the credentials in every case.A custom app’s delete returns 204 once the app is gone. If the app still has accounts, or other Lumos data still references it, the call returns 409 with code set to app.delete_blocked, and the app stays in a disconnected state. An app connected through an integration returns 202 with an operation, and Lumos deletes its record in the background. Poll the operation until done is true, as Long-running operations describes.To disconnect an app as v0’s DELETE did, call POST /v1/apps/{app_uuid}:disconnect. It returns the same id, app_class_id, and disconnected fields.
v0
v1

Syncs

Trigger App Sync takes { "sync_type": "full-sync" }, where v0 took full_sync, and returns an operation instead of app_id, sync_type, and status. Poll the operation, rather than the app, until done is true. Long-running operations describes what it returns. Requesting a sync while another sync is running still returns 409.

AppStore

v1’s AppStore settings object is flat. v0’s request_flow and provisioning objects are gone, and each of their fields either sits at the top level or moved elsewhere: v1 also adds custom_intake_fields, the questions a requester answers on the request form, which v0’s API didn’t expose.

null in AppStore settings

Update AppStore Settings is a merge patch. A field you omit keeps its value, and Lumos clears a field you send as null. v0 mostly treated null as “leave it alone”, so a body built for v0 that sends null for untouched fields erases them on v1. For list fields, such as allowed_requester_group_uuids and custom_intake_fields, Lumos replaces the whole list with the value you send.

Entitlement selection

v1 replaces v0’s requestable permissions with entitlements. groups_provisioning becomes allow_permission_selection:
  • GROUPS_AND_VISIBLE is allow_permission_selection: true.
  • GROUPS_AND_HIDDEN is allow_permission_selection: false. Requesters can’t choose, so a request gets the app’s default_entitlement, or no entitlement when none is set.
  • DIRECT_TO_USER has no single field. On v0 it hid every requestable permission on the app. On v1, set visible_in_appstore to false on each entitlement with Update Entitlement AppStore Settings.

Time-based access

time_based_access.options is null when the app uses your organization’s default options. v0 returned the defaults themselves, so v0 can’t tell you whether the app had its own list. Setting options pins that list on the app, so later changes to the defaults no longer apply to it. Read the app on v1 before you write. If options is null, leave it unset instead of copying v0’s list. v1 returns each option as a label and value_seconds. PATCH takes labels.

Adding an app to the AppStore

An app still needs at least one admin, a user or a group, before you can add it to the AppStore. Set them first with Set App Admins. The error for a missing admin changed from 400 to 409, with code set to app.admin_required.
v0
v1

Finding an app by name

name_search is now search, a case-insensitive substring match. On List Apps it matches label, instance_id, and app_class_id. On Get AppStore Catalog it matches label and description. There’s no exact_match, so to find one app by name, search and compare label yourself. The catalog handles search-only apps as v0 did. A listing without search excludes apps whose catalog_visibility is search-only. A call with search includes the ones that match.
v0
v1

Account uploads

The body keeps app_id and accounts. Each account’s permissions is now entitlements, with the same unique_identifier, type, and name fields. Each account’s status takes a v1 label, such as active rather than ACTIVE. Lifecycle status lists them. accounts is now required and must hold at least one account. A request with an unknown field returns 400. The response is 202 with an operation rather than 200 with job_id and state. Poll the operation until done is true. Here’s how v0’s job states map onto the operation:
  • NOT_STARTED and RUNNING are done: false.
  • SUCCESS is done: true with a result.
  • FAILURE is done: true with an error whose code is account_upload.failed.
  • A cancelled upload, which v0 reported as SUCCESS, ends with error.code set to account_upload.cancelled.
Long-running operations describes the operation, and the Account object page has an upload example.

What takes extra steps on v1

Three things v0 did in one call take extra steps on v1:
  • Finding an app by exact name. Search, then compare label, as Finding an app by name describes.
  • Naming allowed groups by integration_specific_id. v1 takes Lumos group IDs only. Find them with List Groups and its app_id and integration_specific_id filters.
  • Hiding every entitlement on an app (v0’s DIRECT_TO_USER). Update each entitlement, as Entitlement selection describes.

Terraform

In version 1.x of the Lumos Terraform provider, lumos_app_store_app becomes lumos_app_appstore_settings, and its approvers and provisioning steps move into workflows. lumos_app sets display fields through its *_override attributes, as v1 does. Migrating from 0.x to 1.x maps each attribute.