Skip to main content

Import Resources

ThunderID provides the POST /import API to import declarative YAML content into runtime stores.

note

Declarative resource attributes use camelCase (for example ouId, authFlowId, clientId), matching the REST API.

note

An application resource requires a type attribute (browser, fullstack, mobile, m2m, or custom). The type is set on creation and does not change on a later import. See Application Types.

Use this API when you want to:

  • Bootstrap resources from a YAML bundle.
  • Apply declarative updates in CI/CD.
  • Test resource definitions before applying them.

Authentication and authorization​

Use an access token with the system scope.

Send the token in the Authorization header:

http
Authorization: Bearer <access_token>

Endpoint Summary​

  • POST /import: Imports one or more YAML documents into runtime stores.
  • POST /import/delete: Deletes a file-backed declarative resource file by type and key.

Request Model​

POST /import accepts the following payload:

json
{
"content": "# YAML content with one or more documents",
"variables": {
"CLIENT_ID": "my-client-id"
},
"dryRun": false,
"deletions": [
{
"resourceType": "application",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
],
"options": {
"upsert": true,
"continueOnError": true,
"target": "runtime"
}
}

A request has to carry work to do: content to upsert, deletions to remove, or both. A request carrying neither is rejected.

Options Behavior​

  • options.upsert:
    • Omitted: defaults to true.
    • true: updates existing resources when supported.
    • false: skips update behavior and attempts create semantics.
  • options.continueOnError:
    • Omitted: defaults to true.
    • true: continues processing remaining documents after an item failure.
    • false: stops at the first failed item.
  • options.target:
    • Omitted: defaults to runtime.
    • runtime is currently supported.

Removing Resources​

content can create and update but never remove, so a resource dropped from a configuration would otherwise linger on every deployment that configuration was applied to. deletions names the resources to remove, so one request can reconcile a deployment with the configuration as it now stands.

Each entry names a resourceType and an id. User types and agent types are separate resource types, user_type and agent_type, as they are in content.

json
{
"deletions": [
{ "resourceType": "application", "id": "550e8400-e29b-41d4-a716-446655440000" },
{ "resourceType": "agent_type", "id": "660e8400-e29b-41d4-a716-446655440001" }
]
}

Deletion Behavior​

  • Removals run after the upserts. A resource this same request moved or replaced is in place before its predecessor is pruned.
  • Removals are ordered as the reverse of the import dependency order, so a dependent goes before what it depends on rather than failing on a reference that is still live.
  • Removing something already absent is a success. Re-applying the same configuration has to be a no-op, and a request that failed because the removal already happened would make retrying impossible. Where the service reports not found, the outcome carries the message resource already absent and does not add to summary.deleted.
  • A type with no runtime delete is reported, not skipped. translation and server_config are reported as an unsupported outcome, because a configuration that dropped one would otherwise look reconciled when it is not.
  • A removal the owning service refuses is reported with its reason. An agent_type deletion fails with USRS-1015, because agent creation depends on the default agent type.
  • A dry run reports what it would remove and removes nothing.
  • deletions alone is a valid request. Removing what a configuration dropped does not require also restating what it kept.

Deletions follow options.continueOnError as documents do: by default one refused removal does not hold back the rest.

Response Model​

A successful import returns summary metrics and per-document outcomes.

json
{
"summary": {
"totalDocuments": 2,
"imported": 2,
"deleted": 1,
"failed": 0,
"importedAt": "2026-04-23T12:10:52Z"
},
"results": [
{
"resourceType": "connection",
"resourceId": "550e8400-e29b-41d4-a716-446655440000",
"resourceName": "Google",
"operation": "create",
"status": "success"
},
{
"resourceType": "flow",
"resourceId": "660e8400-e29b-41d4-a716-446655440001",
"resourceName": "Default Login Flow",
"operation": "update",
"status": "success"
},
{
"resourceType": "application",
"resourceId": "550e8400-e29b-41d4-a716-446655440000",
"operation": "delete",
"status": "success"
}
]
}

summary.deleted counts the deletions this request completed, separately from imported. A dry run completes none, and a resource a service reports as not found is not counted, though both are still reported as a success in results. Not every service distinguishes an absent id from a removed one, so treat this as the number of deletions that completed rather than a guarantee that each one had something to remove. Every deletion appears in results with operation set to delete, and that list is where the per-resource outcome is.

Example: Import with Variables​

bash
curl -X POST "https://localhost:8090/import" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"content": "resource_type: application\nname: Console\ntype: browser\nauthFlowId: {{.AUTH_FLOW_ID}}\n",
"variables": {
"AUTH_FLOW_ID": "edc013d0-e893-4dc0-990c-3e1d203e005b"
},
"dryRun": false,
"options": {
"upsert": true,
"continueOnError": true,
"target": "runtime"
}
}'

Cross-Resource References by Handle​

Instead of embedding environment-specific resource identifiers in YAML files, you can reference organization units and flows by their human-readable handles. The importer resolves each handle to its resource identifier at import time, making the same YAML portable across environments.

The following handle fields are supported:

Resource typeHandle fieldResolves to
ApplicationouHandleouId
ApplicationauthFlowHandleauthFlowId
ApplicationregistrationFlowHandleregistrationFlowId
ApplicationrecoveryFlowHandlerecoveryFlowId
AgentauthFlowHandleauthFlowId
AgentregistrationFlowHandleregistrationFlowId
User typeouHandleouId

If you provide both a handle field and the corresponding ID field, the ID takes precedence and the handle is ignored.

Updating an existing application or agent with a document that sets only a handle field re-resolves it and keeps the resolved ID.

If a handle cannot be resolved (because the target resource does not exist or the required adapter is not configured), the import item fails with a descriptive error message. When continueOnError is true, the importer continues processing the remaining documents.

Example: Application with Handle References​

yaml
resource_type: application
name: My App
type: fullstack
ouHandle: default
authFlowHandle: default-basic-flow
registrationFlowHandle: default-registration-flow
isRegistrationFlowEnabled: true

Dry-Run Behavior​

When dryRun is true, the importer validates documents and reports what would be created or updated, but does not write any changes to runtime stores. Handle resolution is also skipped in dry-run mode: the importer accepts handle fields without attempting to look up their target resources. Use dry-run to validate YAML structure before applying it.

Delete File-Backed Declarative Resource​

POST /import/delete removes a declarative file-backed resource by resourceType and resourceKey.

json
{
"resourceType": "application",
"resourceKey": "my-console-app"
}

Example response:

json
{
"resourceType": "application",
"resourceKey": "my-console-app",
"deletedFile": "applications/my-console-app.yaml"
}

Expected Side Effects​

When import runs with dryRun=false, ThunderID persists resource changes in runtime stores.

When POST /import/delete succeeds, ThunderID removes the matching declarative YAML file from config/resources.

Error Handling​

Typical failures include:

  • Invalid request payload (IMP-1001).
  • Invalid YAML content (IMP-1002).
  • Template resolution failures (IMP-1003).
  • Adapter not configured for a resource type (IMP-1004).
  • Internal server error (SSE-5000).

Explore with AI

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© Copyright Linux Foundation Europe.For web site terms of use, trademark policy and other project policies please see https://linuxfoundation.eu/en/policies.