Preview — not for production reliance
Documentation

Docs API reference

Organizations

Organizations, members, invitations and service tokens.

18 operations. See the API overview for authentication, errors, idempotency and caching rules that apply to all of them.

List my organizations

GET/v1/organizations

Authentication
Session (passkey-verified) or Service token
Operation ID
listOrganizations

A person gets every organization they are an active member of (oldest first), each with the caller's role. A service token gets the single organization it is bound to, with its scopes in my_roles.

Responses

StatusDescriptionBody
200Organizations.application/json OrganizationList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "organizations": [
    {
      "id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
      "legal_name": "Example Payments, Inc.",
      "jurisdiction": "US-DE",
      "registration_reference": "DE-5849201",
      "verification_status": "verified",
      "version": 4,
      "created_at": "2026-10-05T11:40:00.000Z",
      "updated_at": "2026-10-05T12:30:00.000Z",
      "my_roles": [
        "organization_owner"
      ]
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Create an organization

POST/v1/organizations

Authentication
Session (passkey-verified)
Operation ID
createOrganization

Creates a draft organization and makes the caller its owner. Human only; platform staff accounts cannot create or belong to organizations. At most 5 organizations per principal per rolling 24 hours (429). Identity is verified later by review, through a claim.

Parameters

NameInRequiredTypeDescription
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Request body

application/json, required: CreateOrganizationRequest

FieldTypeRequiredDescription
legal_namestringYesNFC-normalized, trimmed, 1 to 200 code points, no control or bidi characters.
1 to 200 characters
jurisdictionstringYesISO 3166-1 alpha-2 country, optionally with an ISO 3166-2 subdivision (for example US or US-DE)., examples: [US-DE]
registration_referencestring or nullNoat most 100 characters

Example

json
{
  "legal_name": "Example Payments, Inc.",
  "jurisdiction": "US-DE",
  "registration_reference": "DE-5849201"
}

Responses

StatusDescriptionBody
201The new organization.application/json Organization
400invalid_request. Malformed JSON, an invalid or unknown field (see field_errors), a missing or malformed Idempotency-Key, or a bad query. Also used with status 413 (body over 64 KiB) and 415 (wrong Content-Type).application/json Error
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
429rate_limited. A per-client or per-record limit was reached; retry later.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

201 example

json
{
  "id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
  "legal_name": "Example Payments, Inc.",
  "jurisdiction": "US-DE",
  "registration_reference": "DE-5849201",
  "verification_status": "draft",
  "version": 1,
  "created_at": "2026-10-05T11:40:00.000Z",
  "updated_at": "2026-10-05T11:40:00.000Z",
  "my_roles": [
    "organization_owner"
  ]
}

400 example

json
{
  "code": "invalid_request",
  "message": "Invalid organization.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "legal_name",
      "message": "must be 1-200 characters"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

429 example

json
{
  "code": "rate_limited",
  "message": "Too many requests.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Get an organization

GET/v1/organizations/{id}

Authentication
Session (passkey-verified) or Service token
Operation ID
getOrganization

Any member (or a service token bound to this organization).

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.

Responses

StatusDescriptionBody
200The organization.application/json Organization
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
  "legal_name": "Example Payments, Inc.",
  "jurisdiction": "US-DE",
  "registration_reference": "DE-5849201",
  "verification_status": "verified",
  "version": 4,
  "created_at": "2026-10-05T11:40:00.000Z",
  "updated_at": "2026-10-05T12:30:00.000Z",
  "my_roles": [
    "organization_owner"
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Edit an organization's legal identity

PATCH/v1/organizations/{id}

Authentication
Session (passkey-verified) or Session with step-up (passkey within 300 s)
Operation ID
updateOrganization

Owner only, human only. expected_version is optimistic concurrency: a stale value is 409. At least one field to change is required. Send registration_reference: null (or "") to clear it.

A draft organization is edited freely. Once its identity has been reviewed (verified or pending_review), an edit is a material change (spec §4): it needs recent step-up, at least one value must actually change (400 otherwise), and in the same commit the organization returns to pending_review and every claim that passed identity review goes back to pending_identity. Their issuer bindings are suspended (resumable for 30 days once a reviewer re-approves identity and authority); delegations granted under them are revoked. A public claim.state_changed event is written for each claim that leaves verified.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Request body

application/json, required: UpdateOrganizationRequest

FieldTypeRequiredDescription
expected_versionintegerYesminimum 1
legal_namestringNo1 to 200 characters
jurisdictionstringNo
registration_referencestring or nullNonull or "" clears it.
at most 100 characters

Example

json
{
  "expected_version": 1,
  "legal_name": "Example Payments, Incorporated"
}

Responses

StatusDescriptionBody
200The updated organization.application/json Organization
400invalid_request. Malformed JSON, an invalid or unknown field (see field_errors), a missing or malformed Idempotency-Key, or a bad query. Also used with status 413 (body over 64 KiB) and 415 (wrong Content-Type).application/json Error
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
422semantic_check_failed. The request is well formed but a policy or proof check failed (for example an issuer-control proof did not verify, a challenge expired, or the organization is not yet verified). field_errors[].message is often a stable reason code.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
  "legal_name": "Example Payments, Incorporated",
  "jurisdiction": "US-DE",
  "registration_reference": "DE-5849201",
  "verification_status": "draft",
  "version": 2,
  "created_at": "2026-10-05T11:40:00.000Z",
  "updated_at": "2026-10-05T11:45:00.000Z",
  "my_roles": [
    "organization_owner"
  ]
}

400 example

json
{
  "code": "invalid_request",
  "message": "Invalid organization.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "legal_name",
      "message": "must be 1-200 characters"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

422 example

json
{
  "code": "semantic_check_failed",
  "message": "Issuer-control proof failed (endpoint_http_404). 4 attempt(s) left on this challenge.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "method",
      "message": "endpoint_http_404"
    }
  ]
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

List the organization's claims

GET/v1/organizations/{id}/claims

Authentication
Session (passkey-verified) or Service token
Operation ID
listOrganizationClaims

Any member. Newest first, at most 200. Use GET /v1/claims/{id} for detail.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.

Responses

StatusDescriptionBody
200Claims.application/json ClaimList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "claims": [
    {
      "id": "clm_4c8e2g6k0m3q7s1w5y9a2d6f8h",
      "domain": "payments.example.com",
      "state": "verified",
      "resume_state": null,
      "version": 7,
      "created_at": "2026-10-05T11:50:00.000Z",
      "updated_at": "2026-10-05T12:20:00.000Z",
      "authority_expires_at": "2027-10-05T12:20:00.000Z",
      "permitted_actions": [
        "authorize_issuer",
        "delegate"
      ]
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

List the organization's issuer bindings

GET/v1/organizations/{id}/issuer-bindings

Authentication
Session (passkey-verified) or Service token
Operation ID
listOrganizationIssuerBindings

Any member. Newest first, at most 200.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.

Responses

StatusDescriptionBody
200Issuer bindings (summaries).application/json IssuerBindingList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "issuer_bindings": [
    {
      "id": "bnd_9r2t5w8z1b4d7f0h3k6n9q2s5v",
      "trust_domain": "agents.payments.example.com",
      "verified_domain": "payments.example.com",
      "mapping": "dns",
      "profile": "spiffe-x509",
      "workload_scope": [
        "/agent/checkout"
      ],
      "environment": "production",
      "status": "active",
      "version": 6,
      "current_version": 1,
      "expires_at": "2027-10-05T11:58:12.000Z",
      "created_at": "2026-10-05T11:56:00.000Z",
      "updated_at": "2026-10-05T11:58:12.000Z",
      "latest_version": 1
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

List active members

GET/v1/organizations/{id}/members

Authentication
Session (passkey-verified) or Service token
Operation ID
listMembers

Any member. Email addresses are shown only to owners.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.

Responses

StatusDescriptionBody
200Active members.application/json MemberList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "members": [
    {
      "principal_id": "prn_6d9g2j5m8q1t4w7z0c3f6h9k2n",
      "role": "organization_owner",
      "status": "active",
      "version": 1,
      "display_name": "Ada Lovelace",
      "idp": "github",
      "email": "ada@example.com",
      "created_at": "2026-10-05T11:40:00.000Z",
      "updated_at": "2026-10-05T11:40:00.000Z"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Change a member's role

PATCH/v1/organizations/{id}/members/{principalId}

Authentication
Session with step-up (passkey within 300 s)
Operation ID
updateMemberRole

Owner, human, step-up. expected_version is the member's version. Demoting an owner revokes the service tokens they created for this organization in the same commit. The last owner can never be demoted (409).

Material change (spec §4): if the member is the approved representative of a claim and the new role is neither the role they held when their authority was approved nor organization_owner, that claim goes back to pending_authority in the same commit, its issuer bindings are suspended (resumable for 30 days after re-approval) and a public claim.state_changed event is written.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
principalIdpathYesstringA member's principal id. DELETE also accepts the literal me.
example prn_6d9g2j5m8q1t4w7z0c3f6h9k2n
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Request body

application/json, required: UpdateMemberRequest

FieldTypeRequiredDescription
roleOrgRoleYes
expected_versionintegerYesminimum 1

Example

json
{
  "role": "issuer_administrator",
  "expected_version": 1
}

Responses

StatusDescriptionBody
200The updated member (with email, as the caller is an owner).application/json Member
400invalid_request. Malformed JSON, an invalid or unknown field (see field_errors), a missing or malformed Idempotency-Key, or a bad query. Also used with status 413 (body over 64 KiB) and 415 (wrong Content-Type).application/json Error
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "principal_id": "prn_8h1k4n7q0t3w6z9c2f5j8m1p4s",
  "role": "issuer_administrator",
  "status": "active",
  "version": 2,
  "display_name": "Grace Hopper",
  "idp": "google",
  "email": "grace@example.com",
  "created_at": "2026-10-05T11:50:00.000Z",
  "updated_at": "2026-10-05T12:10:00.000Z"
}

400 example

json
{
  "code": "invalid_request",
  "message": "Invalid organization.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "legal_name",
      "message": "must be 1-200 characters"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Remove a member, or leave

DELETE/v1/organizations/{id}/members/{principalId}

Authentication
Session with step-up (passkey within 300 s)
Operation ID
removeMember

Removing another member needs an owner with step-up and a body { "expected_version" }. Using me as principalId is leaving: any active human member may do it with no step-up, and expected_version is optional. The last owner can never go (409). The departing member's service tokens for this organization are revoked and their pending invitations are cancelled in the same commit. If they are the approved representative of a claim, that claim goes back to pending_authority in the same commit and its issuer bindings are suspended (spec §4 material change). This DELETE takes a JSON body; send Content-Type: application/json when you include one.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
principalIdpathYesstringA member's principal id. DELETE also accepts the literal me.
example prn_6d9g2j5m8q1t4w7z0c3f6h9k2n
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Request body

application/json: RemoveMemberRequest

expected_version is required when removing another member and optional when leaving (me).

FieldTypeRequiredDescription
expected_versionintegerNominimum 1

Example

json
{
  "expected_version": 2
}

Responses

StatusDescriptionBody
204Removed.None
400invalid_request. Malformed JSON, an invalid or unknown field (see field_errors), a missing or malformed Idempotency-Key, or a bad query. Also used with status 413 (body over 64 KiB) and 415 (wrong Content-Type).application/json Error
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

400 example

json
{
  "code": "invalid_request",
  "message": "Invalid organization.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "legal_name",
      "message": "must be 1-200 characters"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

List pending invitations

GET/v1/organizations/{id}/invitations

Authentication
Session (passkey-verified)
Operation ID
listOrganizationInvitations

Owner only. Pending, unexpired invitations the organization has sent.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.

Responses

StatusDescriptionBody
200Pending invitations.application/json OrganizationInvitationList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "invitations": [
    {
      "id": "inv_8h1k4n7q0t3w6z9c2f5j8m1p4s",
      "role": "issuer_administrator",
      "status": "pending",
      "invited_by": "prn_6d9g2j5m8q1t4w7z0c3f6h9k2n",
      "created_at": "2026-10-05T12:00:00.000Z",
      "expires_at": "2026-10-12T12:00:00.000Z"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Invite someone by email

POST/v1/organizations/{id}/invitations

Authentication
Session with step-up (passkey within 300 s)
Operation ID
createInvitation

Owner, human, step-up. Consent based: nobody becomes a member until they accept. The answer is the same 202 whether or not an account with that address exists, and never reveals a principal. Only a keyed hash of the address is stored; it is matched against the invitee's IdP-verified email. A newer invitation to the same address supersedes the pending one. Invitations expire after 7 days. 503 if the deployment has no invitation key configured.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Request body

application/json, required: CreateInvitationRequest

FieldTypeRequiredDescription
emailstring (email)Yesat most 254 characters
roleOrgRoleYes

Example

json
{
  "email": "grace@example.com",
  "role": "issuer_administrator"
}

Responses

StatusDescriptionBody
202Invitation recorded.application/json InvitationCreated
400invalid_request. Malformed JSON, an invalid or unknown field (see field_errors), a missing or malformed Idempotency-Key, or a bad query. Also used with status 413 (body over 64 KiB) and 415 (wrong Content-Type).application/json Error
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

202 example

json
{
  "invitation_id": "inv_8h1k4n7q0t3w6z9c2f5j8m1p4s",
  "organization_id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
  "role": "issuer_administrator",
  "status": "pending",
  "expires_at": "2026-10-12T12:00:00.000Z"
}

400 example

json
{
  "code": "invalid_request",
  "message": "Invalid organization.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "legal_name",
      "message": "must be 1-200 characters"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Cancel a pending invitation

DELETE/v1/organizations/{id}/invitations/{invId}

Authentication
Session with step-up (passkey within 300 s)
Operation ID
cancelInvitation

Owner, human, step-up. Cancelling an already-cancelled invitation is 204; an accepted or declined one is 409.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
invIdpathYesstring
example inv_8h1k4n7q0t3w6z9c2f5j8m1p4s
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Responses

StatusDescriptionBody
204Cancelled.None
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

List service tokens

GET/v1/organizations/{id}/service-tokens

Authentication
Session (passkey-verified)
Operation ID
listServiceTokens

Owner only. Never includes secrets.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.

Responses

StatusDescriptionBody
200Service tokens, oldest first.application/json ServiceTokenList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "service_tokens": [
    {
      "id": "stk_1f4j7m0q3t6w9z2c5g8k1n4r7v",
      "name": "ci-claims-bot",
      "scopes": [
        "domain_administrator"
      ],
      "expires_at": "2026-11-04T12:00:00.000Z",
      "created_by": "prn_6d9g2j5m8q1t4w7z0c3f6h9k2n",
      "created_at": "2026-10-05T12:00:00.000Z",
      "revoked_at": null,
      "last_used_at": "2026-10-05T12:05:00.000Z"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Create a service token

POST/v1/organizations/{id}/service-tokens

Authentication
Session with step-up (passkey within 300 s)
Operation ID
createServiceToken

Owner, human, step-up. The secret (token) is returned once; only its hash is stored, and an idempotent replay returns the record with token: null and token_redacted: true. A service token can use the scopes you give it but is never an owner, and it cannot step up.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Request body

application/json, required: CreateServiceTokenRequest

FieldTypeRequiredDescription
namestringYes1 to 100 characters
scopesarray of ServiceTokenScopeYesat least 1 items; unique items
expires_in_daysintegerNo1 to 90; default 30

Example

json
{
  "name": "ci-claims-bot",
  "scopes": [
    "domain_administrator"
  ],
  "expires_in_days": 30
}

Responses

StatusDescriptionBody
201The token record, including the one-time secret.
Headers: Cache-Control: no-store
application/json ServiceTokenCreated
400invalid_request. Malformed JSON, an invalid or unknown field (see field_errors), a missing or malformed Idempotency-Key, or a bad query. Also used with status 413 (body over 64 KiB) and 415 (wrong Content-Type).application/json Error
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

201 example

json
{
  "id": "stk_1f4j7m0q3t6w9z2c5g8k1n4r7v",
  "organization_id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
  "principal_id": "prn_2k5n8r1v4y7b0e3h6m9q2t5x8a",
  "name": "ci-claims-bot",
  "scopes": [
    "domain_administrator"
  ],
  "expires_at": "2026-11-04T12:00:00.000Z",
  "created_by": "prn_6d9g2j5m8q1t4w7z0c3f6h9k2n",
  "created_at": "2026-10-05T12:00:00.000Z",
  "revoked_at": null,
  "last_used_at": null,
  "token": "art_st_0Yq3Lw8Zk1Vb5Nn9Xc2Ta6Re4Hs7Dm0Pj"
}

400 example

json
{
  "code": "invalid_request",
  "message": "Invalid organization.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w",
  "field_errors": [
    {
      "field": "legal_name",
      "message": "must be 1-200 characters"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Revoke a service token

DELETE/v1/organizations/{id}/service-tokens/{tokenId}

Authentication
Session (passkey-verified)
Operation ID
revokeServiceToken

Owner, human. Deliberately no step-up: revocation only removes access and must stay fast in an incident. Revoking an already-revoked token is 204.

Parameters

NameInRequiredTypeDescription
idpathYesOrganizationIdOrganization id.
tokenIdpathYesstring
example stk_1f4j7m0q3t6w9z2c5g8k1n4r7v
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Responses

StatusDescriptionBody
204Revoked.None
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Invitations addressed to me

GET/v1/invitations

Authentication
Session (passkey-verified)
Operation ID
listMyInvitations

Human only. Pending, unexpired invitations whose inviter is still an active owner, matched on the hash of the caller's IdP-verified email. Empty if the caller's principal has no email.

Responses

StatusDescriptionBody
200My invitations.application/json MyInvitationList
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "invitations": [
    {
      "id": "inv_8h1k4n7q0t3w6z9c2f5j8m1p4s",
      "organization": {
        "id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
        "legal_name": "Example Payments, Inc."
      },
      "role": "issuer_administrator",
      "created_at": "2026-10-05T12:00:00.000Z",
      "expires_at": "2026-10-12T12:00:00.000Z"
    }
  ]
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Accept an invitation

POST/v1/invitations/{id}/accept

Authentication
Session with step-up (passkey within 300 s)
Operation ID
acceptInvitation

Step-up: joining an organization grants authority, so it needs a fresh passkey assertion. Every miss (unknown, not yours, expired, inviter no longer an owner) is the same 404. Platform staff accounts cannot accept (403).

Parameters

NameInRequiredTypeDescription
idpathYesstring
example inv_8h1k4n7q0t3w6z9c2f5j8m1p4s
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Responses

StatusDescriptionBody
200You are now a member.application/json InvitationAccepted
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
403forbidden. Authenticated but not allowed: a role that does not permit the action, a service token on a human-only operation, a missing or wrong CSRF token, or a request Origin that is not allowed.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

200 example

json
{
  "organization_id": "org_7k3m9q2x8d5f1h4j6n0p2r4t8v",
  "role": "issuer_administrator",
  "status": "active"
}

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

403 example

json
{
  "code": "forbidden",
  "message": "Your role does not permit this action.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

Decline an invitation

POST/v1/invitations/{id}/decline

Authentication
Session (passkey-verified)
Operation ID
declineInvitation

No step-up needed. Every miss is the same 404.

Parameters

NameInRequiredTypeDescription
idpathYesstring
example inv_8h1k4n7q0t3w6z9c2f5j8m1p4s
Idempotency-KeyheaderYesstringUnique key for this logical mutation (1 to 255 characters of A-Z a-z 0-9 . _ : -). Replays within 24 hours return the original outcome.
1 to 255 characters; pattern ^[A-Za-z0-9._:-]+$
example 7f3c1b52-9d44-4a0e-8f21-0a6e5b9d3c77
x-art-csrfheaderYesstringThe csrf_token from GET /auth/session. Required on every session-authenticated mutation.
example Kk3jVq0bYw2p0mT1aZc9sD8eF4gH6iJ7nL5oP2rQ1uA

Responses

StatusDescriptionBody
204Declined.None
401unauthenticated (no or invalid credentials, or the session has not completed the passkey ceremony) or step_up_required (the passkey assertion is too old; also returned to service tokens, which can never step up). Both are 401; tell them apart by code.application/json Error
404not_found. No such resource, or one the caller may not see (the two are indistinguishable by design).application/json Error
409conflict. The record changed since you read it (stale expected_version), the action is not valid in the record's current state, the Idempotency-Key was reused with a different request, or the same request is still in flight.application/json Error
503unavailable (temporarily unavailable; also a feature that is not configured in this deployment) or provider_unavailable (an identity provider is not configured). Both are 503. During maintenance (for example a database recovery) every mutating request answers unavailable "The directory is under maintenance; try again later." Reads keep working.application/json Error

401 unauthenticated

json
{
  "code": "unauthenticated",
  "message": "Sign in required.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

401 step_up_required

json
{
  "code": "step_up_required",
  "message": "Recent passkey verification required for this action.",
  "request_id": "req_5a8c1f4h7k0m3p6s9v2x5z8b1d"
}

404 example

json
{
  "code": "not_found",
  "message": "No such resource.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

409 example

json
{
  "code": "conflict",
  "message": "The record changed since you read it; reload and retry with the current version.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}

503 example

json
{
  "code": "unavailable",
  "message": "Temporarily unavailable.",
  "request_id": "req_3m6p9s2v5y8b1e4h7k0n3q6t9w"
}