Preview. The published OpenAPI operation remains the authority for its
response codes and any endpoint-specific retry behavior.
Read response body
Most Registry, Skill, Agent, File, and MCP failures use anapplication/problem+json body with title, status, detail, and stable
code. A refused request (400, 409, or 422) says why it was refused in
detail when that cause is safe to publish; otherwise detail stays a
generic sentence. Preserve trace_id when it is present. OTLP ingestion
instead returns its documented JSON error shape with code, message, and
details.
Log the status, stable code, operation, and trace ID when available. Do not log
the bearer credential, request body, or a bundle’s contents.
Recover by status
Retry writes deliberately
Safe retries depend on the operation. For example, OTLP ingestion acceptsX-Atlan-Ingest-Id to identify the same batch on a retry. Skill uploads refuse
content identical to the current version as a duplicate that names the existing
skill, so read that skill instead of uploading again; a bundle whose only
difference is a file’s permission, such as a script made executable, becomes a
new version. Some Registry writes answer their own repeat: revoking an
invitation that is already revoked, deactivating an encryption key that is
already verified, or withdrawing a release that is already withdrawn answers
200 with the resource’s current state and changes nothing. An invitation that
was accepted or has expired, or an encryption key that is pending, retired, or
Atlan-managed, still returns 409.
Connecting a GitHub installation (POST /github/v1/installations), creating a
repository binding (POST /github/v1/installations/{installation_id}/bindings),
or adding repositories in a batch
(POST /github/v1/installations/{installation_id}/bindings/batch) accepts an
optional Idempotency-Key. While the first request with a given key is still
running, another request with the same key returns 409
idempotency_conflict instead of connecting or binding a second time. Resend
the same key after the first request finishes to receive its result. A batch
reports each repository’s outcome in request order: a repository it could not
place carries its own status and code in its result while the batch still
completes for the rest.
Creating an artifact and appending a version to it also accept an optional
Idempotency-Key: 1–128 ASCII letters, digits, hyphens, or underscores.
Resending the same key with the same request returns the version the first
attempt committed, for 24 hours, instead of writing a duplicate. A resend
marks its reply: the artifact it returns carries replayed: true, and every
other reply — including a write that wrote — leaves the field out. The same key
with a different request is refused with 409 idempotency_conflict. The key
is scoped to the caller and the operation and never replaces authorization.
Creating an artifact of an identity-bearing kind does not accept the key — that
create reveals a credential and is never replayed — and a malformed key is a
400.
Relationship edges can also be written against the state you reviewed. Every
relationship the Registry returns carries an etag, an opaque token over the
edge’s stored state. To assert an edge without overwriting a concurrent
writer’s change, use the conditional write
POST /registry/v1/artifacts/{artifact_kind}/{artifact_id}/relationships/conditional:
send the source’s reviewed version handle (source_version_id, a ver_…
handle) and ETag (source_etag), the edge state you reviewed as
expected_edge, and the ordinary relationship body. expected_edge states
either {"state": "absent"} — no row with that edge key exists, including
archived rows — or {"state": "present", "etag": "<reviewed etag>"} for the
reviewed state of an active or archived edge. The server asserts the edge only
while the source and the edge still match what you reviewed. Stale state
returns 409 with no side effects, and the 201 response carries the new
edge’s etag. To archive exactly the edge you read, use
POST /registry/v1/artifacts/{artifact_kind}/{artifact_id}/relationships/archive/conditional
with the same source fields, the edge’s rel_type, to_id, and its reviewed
expected_etag; it returns 204, and the same 409 when the state moved on.
The conditional archive is its own route, so a deployment that does not serve
it yet refuses the request — never retry the change through the unconditional
archive. Releases and withdrawals have conditional variants too,
POST /registry/v1/artifacts/{artifact_kind}/{artifact_id}/releases/conditional
and POST /registry/v1/releases/{release_id}/withdraw/conditional; the
published reference remains the authority for their request shapes.
Do not add a generic retry loop around every POST, PATCH, or archive call.
If a write times out or returns a 5xx response, read the intended resource first
and retry only when the endpoint contract makes the next action safe.
Get help without exposing data
For a trace issue fromaireg, collect its health check and recent log, as
described in the aireg CLI reference, and
inspect both before sharing. If you exported traces by hand, re-run the export
as aireg trace export --log-level debug first, so the log covers it. For a
scheduled export, also include aireg job runs.
For an HTTP request, share only the operation, status, stable error code, and
trace ID where your support process permits it. Keep tokens, full request
bodies, and customer content out of tickets and chat.