{"components":{"headers":{"AccountsVersion":{"description":"The API version that served this response, like `2026-10-01`.","schema":{"examples":["2026-10-01"],"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},"IdempotentReplayed":{"description":"`true` when this is the stored answer to an earlier request with the same Idempotency-Key: nothing ran twice.","schema":{"enum":["true"],"type":"string"}},"RequestId":{"description":"The request id: the caller's `X-Request-Id` when it was 1 to 128 characters of `A-Z a-z 0-9 - _ . :`, else a generated UUIDv7. Quote it when you report a problem.","schema":{"type":"string"}},"RetryAfter":{"description":"Seconds to wait before trying again (423, 429, and 503 `imports_busy`).","schema":{"minimum":0,"type":"integer"}}},"parameters":{"AccountsVersionHeader":{"description":"Pin the API version. Absent = the current version, `2026-10-01`. An unknown version answers 400 `unsupported_version` with `details.supported`.","in":"header","name":"Accounts-Version","required":false,"schema":{"examples":["2026-10-01"],"pattern":"^\\d{4}-\\d{2}-\\d{2}$","type":"string"}},"AppId":{"description":"The app's id.","in":"path","name":"app_id","required":true,"schema":{"$ref":"#/components/schemas/AppId"}},"Cursor":{"description":"The `next_cursor` of the previous page, unchanged. Anything else is 400 `invalid_cursor`.","in":"query","name":"cursor","required":false,"schema":{"type":"string"}},"CustodianRequestId":{"description":"The custodian request's id.","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},"EmailPath":{"description":"One of your email addresses (`@` and `+` may be sent as they are).","in":"path","name":"email","required":true,"schema":{"type":"string"}},"FlowId":{"description":"The sign-in flow's id.","in":"path","name":"id","required":true,"schema":{"type":"string"}},"IdempotencyKey":{"description":"1 to 200 visible ASCII characters (a UUID works well). The same key, caller, endpoint and body replays the first answer with `Idempotent-Replayed: true`; another body is 409 `idempotency_key_reused`; while the first request runs, 409 `idempotency_in_progress`. Failures are not stored. Answers are kept 24 hours, or 10 minutes when they carry a new secret.","in":"header","name":"Idempotency-Key","required":false,"schema":{"pattern":"^[\\x21-\\x7E]{1,200}$","type":"string"}},"JobId":{"description":"The import job's id.","in":"path","name":"job_id","required":true,"schema":{"format":"uuid","type":"string"}},"Limit":{"description":"Page size: 1 to 200, default 50 (values outside are clamped).","in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},"PhonePath":{"description":"One of your phone numbers, E.164 (`+` may be sent as is or as `%2B`).","in":"path","name":"phone","required":true,"schema":{"type":"string"}},"ProofId":{"description":"The proof's id.","in":"path","name":"proof_id","required":true,"schema":{"format":"uuid","type":"string"}},"Provider":{"description":"The identity provider.","in":"path","name":"provider","required":true,"schema":{"enum":["google","apple"],"type":"string"}},"SiliconDeliveryId":{"description":"The webhook delivery's id.","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},"SiliconRef":{"description":"The Silicon's uuid or its current si:id (`K1E` and `si:scout` name the same Silicon). A Silicon you aren't custodian of is 404 `silicon_not_found`.","in":"path","name":"uuid","required":true,"schema":{"type":"string"}},"SubscriptionId":{"description":"The subscription's id.","in":"path","name":"subscription_id","required":true,"schema":{"format":"uuid","type":"string"}},"UserCode":{"description":"The code the CLI shows, like MVHB-KQAW; matched without case, spaces or dashes.","in":"path","name":"user_code","required":true,"schema":{"type":"string"}}},"responses":{"AppDisabled":{"content":{"application/json":{"example":{"error":{"code":"app_disabled","message":"The app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The app is disabled.\n\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_disabled"]},"AppOwnerForbidden":{"content":{"application/json":{"example":{"error":{"code":"app_mismatch","message":"App credentials were used on another app's /v1/apps/{app_id} URL."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Another app's credentials, an account that isn't one of the app's authors (its owner or an accepted co-author), or a disabled app's credentials (its authors can still manage it). `origin_not_allowed` applies only to cookie-authenticated writes.\n\n- `app_mismatch`: app credentials were used on another app's `/v1/apps/{app_id}` URL\n- `not_app_owner`: an account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it\n- `app_disabled`: the app is disabled\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_mismatch","not_app_owner","app_disabled","origin_not_allowed"]},"AppUnauthorized":{"content":{"application/json":{"example":{"error":{"code":"app_credentials_required","message":"An app endpoint got no credentials."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The app's Basic credentials are missing or wrong.\n\n- `app_credentials_required`: an app endpoint got no credentials\n- `invalid_app_credentials`: unknown app_id, wrong secret, or malformed Basic header","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_credentials_required","invalid_app_credentials"]},"BadRequest":{"content":{"application/json":{"example":{"error":{"code":"invalid_json","message":"The body isn't valid JSON (line and column given)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The request is malformed; retrying it unchanged fails again. The shared codes:\n\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `invalid_body`: the body couldn't be read (connection broken mid-upload)\n- `invalid_query`: a query parameter is missing, has the wrong type or an unknown value (named)\n- `invalid_path`: a path parameter is malformed\n- `invalid_cursor`: `cursor` isn't a `next_cursor` from this list; pass it unchanged or omit it\n- `invalid_request`: the request is missing something it needs (the message names it)\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_json","invalid_content_type","invalid_body","invalid_query","invalid_path","invalid_cursor","invalid_request","invalid_idempotency_key","unsupported_version"]},"CarbonOnly":{"content":{"application/json":{"example":{"error":{"code":"carbon_only","message":"A Silicon called an endpoint for Carbons (emails, phones, custodian side…)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Only a Carbon may call this. `origin_not_allowed` applies only to cookie-authenticated writes.\n\n- `carbon_only`: a Silicon called an endpoint for Carbons (emails, phones, custodian side…)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["carbon_only","origin_not_allowed"]},"Conflict":{"content":{"application/json":{"example":{"error":{"code":"idempotency_key_reused","message":"The key was used for a different body on this endpoint; use a new key for a new request."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflicts with the current state. For idempotent requests:\n\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"CookieUnauthorized":{"content":{"application/json":{"example":{"error":{"code":"unauthenticated","message":"This endpoint needs a signed-in account: send Authorization: Bearer <access token>."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"This browser has no live session.\n\n- `unauthenticated`: no credentials; sign in (`silicon-accounts login`) or send the app's Basic credentials\n- `session_expired`: the session cookie was signed out, revoked or expired","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unauthenticated","session_expired"]},"FlowNotBound":{"content":{"application/json":{"example":{"error":{"code":"flow_not_bound","message":"The request lacks this flow's sa_flow cookie: continue in the browser that started it."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The request lacks this flow's binding cookie: continue in the browser that started it. `origin_not_allowed` applies only to cookie-authenticated writes.\n\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_bound","origin_not_allowed"]},"FlowSessionRequired":{"content":{"application/json":{"example":{"error":{"code":"session_required","message":"The browser isn't signed in (any more), so the flow can't continue for its account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The browser is no longer signed in as the flow's account.\n\n- `session_required`: the browser isn't signed in (any more), so the flow can't continue for its account","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["session_required"]},"Forbidden":{"content":{"application/json":{"example":{"error":{"code":"origin_not_allowed","message":"A cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's Origin; use a Bearer token instead of the cookie."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Authenticated, but not allowed here. The shared codes:\n\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie\n- `carbon_only`: a Silicon called an endpoint for Carbons (emails, phones, custodian side…)\n- `silicon_only`: a Carbon called an endpoint for Silicons (`/v1/me/webhook…`: its own webhook, deliveries and replay)\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `app_mismatch`: app credentials were used on another app's `/v1/apps/{app_id}` URL\n- `not_app_owner`: an account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["origin_not_allowed","carbon_only","silicon_only","account_not_active","app_mismatch","not_app_owner","app_disabled"]},"InternalApiDisabled":{"content":{"application/json":{"example":{"error":{"code":"internal_api_disabled","message":"The server has no internal token configured."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The server has no internal token configured.\n\n- `internal_api_disabled`: the server has no internal token configured","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["internal_api_disabled"]},"InternalError":{"content":{"application/json":{"example":{"error":{"code":"internal","details":{"request_id":"01a11439-e90a-7133-aca9-e337db93d14f"},"message":"Something went wrong on our side."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"A fault on our side. Retry later with the same Idempotency-Key; report `details.request_id` if it persists.\n\n- `internal`: A fault on our side. Retry later. If it continues, report the `details.request_id` so we can find the request.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["internal"]},"InternalUnauthorized":{"content":{"application/json":{"example":{"error":{"code":"internal_token_required","message":"/v1/internal/* without the internal token (Silicon Apps only)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The internal token is missing or wrong.\n\n- `internal_token_required`: `/v1/internal/*` without the internal token (Silicon Apps only)\n- `invalid_internal_token`: the internal token is wrong","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["internal_token_required","invalid_internal_token"]},"Locked":{"content":{"application/json":{"example":{"error":{"code":"verification_locked","details":{"locked_until":"2026-10-07T02:41:21.818Z","retry_after_seconds":60},"message":"Too many wrong codes in a row for a***@example.test: verification is locked for 60 more seconds (until 2026-10-07T02:41:21.818Z)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Locked after too many failures. Wait `Retry-After` seconds.\n\n- `verification_locked`: 10 wrong codes in a row for this address; every code to it waits 60 seconds (`details.locked_until`)\n- `login_locked`: 10 wrong STKs in a row for this Silicon; sign-in waits 60 seconds","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["verification_locked","login_locked"]},"ManagerForbidden":{"content":{"application/json":{"example":{"error":{"code":"not_app_owner","message":"An account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Only an account that currently manages the app may call this. `origin_not_allowed` applies only to cookie-authenticated writes.\n\n- `not_app_owner`: an account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["not_app_owner","origin_not_allowed"]},"NotFound":{"content":{"application/json":{"example":{"error":{"code":"route_not_found","message":"There is no endpoint GET /v1/nope in Silicon Accounts."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found, or not visible to you. Operations list their own codes.\n\n- `route_not_found`: no endpoint has this path\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["route_not_found","unknown_app"]},"OAuthBadRequest":{"content":{"application/json":{"example":{"error":"invalid_grant","error_description":"This refresh token was already used once. Presenting a used refresh token revokes the whole sign-in to protect the account, so this sign-in is now revoked; sign in again."},"schema":{"anyOf":[{"$ref":"#/components/schemas/OAuthError"},{"$ref":"#/components/schemas/Error"}]}}},"description":"An RFC 6749 error: `invalid_request` (missing, repeated or malformed parameter; the client authenticated twice), `invalid_grant`, `unauthorized_client`, `unsupported_grant_type`, `invalid_scope`, or while polling a device code `authorization_pending`, `slow_down`, `access_denied`, `expired_token`. `error_description` says exactly which reason applied. An unsupported `Accounts-Version` is answered in the API error shape (`unsupported_version`).","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"OAuthInvalidClient":{"content":{"application/json":{"example":{"error":"invalid_client","error_description":"The app credentials are wrong: unknown app_id or wrong app_secret."},"schema":{"$ref":"#/components/schemas/OAuthError"}}},"description":"`invalid_client`: unknown app, wrong secret, disabled app, or no credentials. Carries `WWW-Authenticate: Basic realm=\"Silicon Accounts\"`.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"OAuthPayloadTooLarge":{"content":{"application/json":{"example":{"error":"invalid_request","error_description":"The request body is larger than 64 KB."},"schema":{"$ref":"#/components/schemas/OAuthError"}}},"description":"`invalid_request`: the body is over 64 KB.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"OAuthServerError":{"content":{"application/json":{"example":{"error":"server_error","error_description":"Something went wrong on our side (request 01a11439-e90a-7133-aca9-e337db93d14f)."},"schema":{"$ref":"#/components/schemas/OAuthError"}}},"description":"`server_error`: a fault on our side; the description carries the request id.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"OAuthUnavailable":{"content":{"application/json":{"example":{"error":"temporarily_unavailable","error_description":"The request ran past its 30-second budget; retry it."},"schema":{"$ref":"#/components/schemas/OAuthError"}}},"description":"`temporarily_unavailable`: the request ran past its 30-second budget.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"PayloadTooLarge":{"content":{"application/json":{"example":{"error":{"code":"payload_too_large","details":{"limit_bytes":65536},"message":"The body is over the route's limit (details.limit_bytes: 64 KB by default)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The body is over the route's limit (`details.limit_bytes`; 64 KB by default).\n\n- `payload_too_large`: the body is over the route's limit (`details.limit_bytes`: 64 KB by default)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["payload_too_large"]},"RateLimited":{"content":{"application/json":{"example":{"error":{"code":"rate_limited","details":{"retry_after_seconds":57},"hint":"Wait 57 seconds before trying again.","message":"Too many id availability checks from this network: the limit is 120 per minute."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Over a rate limit. Wait `Retry-After` seconds (also in `details.retry_after_seconds`).\n\n- `rate_limited`: over a rate limit; wait `Retry-After` seconds (also `details.retry_after_seconds`). The message names the limit; id changes add `details.limit`, `window_seconds` and `retry_at`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["rate_limited"]},"RequestTokenUnauthorized":{"content":{"application/json":{"example":{"error":{"code":"request_token_required","message":"GET /v1/silicons/requests/{id} without Bearer sarq_…."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The `sarq_` request token is missing or isn't this request's.\n\n- `request_token_required`: `GET /v1/silicons/requests/{id}` without `Bearer sarq_…`\n- `invalid_request_token`: the `sarq_` token doesn't belong to this request","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["request_token_required","invalid_request_token"]},"ServiceUnavailable":{"content":{"application/json":{"example":{"error":{"code":"database_unavailable","message":"The database is unreachable; nothing was changed; retry in a few seconds."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The database is unreachable or the request ran past its time budget. Nothing was changed by a database failure; retry in a few seconds.\n\n- `database_unavailable`: the database is unreachable; nothing was changed; retry in a few seconds\n- `request_timeout`: the request ran past its time budget (30 s, 60 s for uploads, 5 min for imports)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["database_unavailable","request_timeout"]},"SignupNotBound":{"content":{"application/json":{"example":{"error":{"code":"flow_not_bound","message":"The request lacks this flow's sa_flow cookie: continue in the browser that started it."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The request lacks this flow's or this sign-up's cookie. `origin_not_allowed` applies only to cookie-authenticated writes.\n\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `signup_not_bound`: the sign-up belongs to another browser\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_bound","signup_not_bound","origin_not_allowed"]},"SiliconOnly":{"content":{"application/json":{"example":{"error":{"code":"silicon_only","message":"A Carbon called an endpoint for Silicons (/v1/me/webhook…: its own webhook, deliveries and replay)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Only a Silicon may call this. `origin_not_allowed` applies only to cookie-authenticated writes.\n\n- `silicon_only`: a Carbon called an endpoint for Silicons (`/v1/me/webhook…`: its own webhook, deliveries and replay)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_only","origin_not_allowed"]},"Unauthorized":{"content":{"application/json":{"example":{"error":{"code":"unauthenticated","message":"This endpoint needs a signed-in account: send Authorization: Bearer <access token>."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"No credentials, or bad ones. Sign in again, or fix the token or app secret. The shared codes:\n\n- `unauthenticated`: no credentials; sign in (`silicon-accounts login`) or send the app's Basic credentials\n- `invalid_authorization`: the `Authorization` header is unreadable or uses an unsupported scheme\n- `invalid_token`: not an access token, a bad signature, or expired (access tokens last 30 minutes: refresh)\n- `token_wrong_audience`: an app's token was used where a first-party (`aud = silicon-accounts`) token is needed, or a developer-platform token (`aud = developer`, `details.aud`) outside the routes it may use (`GET /v1/me`, `GET /v1/session`, `GET /v1/me/owned-apps` and the owner routes under `/v1/apps/{app_id}/…`); the message names the method and route\n- `identity_token_not_accepted`: an identity token (`token_use: identity`, for outside services) was sent as a bearer token; send the access token\n- `token_revoked`: the sign-in behind the token ended (signed out, STK rotated, account deleted, refresh token reuse); the message says when and why; sign in again\n- `session_expired`: the session cookie was signed out, revoked or expired\n- `account_auth_required`: app credentials (Basic) were sent to an endpoint that acts for an account\n- `app_credentials_required`: an app endpoint got no credentials\n- `invalid_app_credentials`: unknown app_id, wrong secret, or malformed Basic header","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unauthenticated","invalid_authorization","invalid_token","token_wrong_audience","identity_token_not_accepted","token_revoked","session_expired","account_auth_required","app_credentials_required","invalid_app_credentials"]},"UnsupportedMediaType":{"content":{"application/json":{"example":{"error":{"code":"unsupported_media_type","message":"A photo upload's Content-Type isn't PNG, JPEG, WebP or GIF."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"A photo upload's Content-Type isn't PNG, JPEG, WebP or GIF.\n\n- `unsupported_media_type`: a photo upload's `Content-Type` isn't PNG, JPEG, WebP or GIF","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unsupported_media_type"]},"ValidationFailed":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Fields are missing, of the wrong type, invalid or unknown. `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed"]}},"schemas":{"AccountForApp":{"description":"The account as an app may see it: the fields of the granted scopes.","properties":{"custodian":{"$ref":"#/components/schemas/CustodianRef","description":"Silicons only."},"display_name":{"type":"string"},"dob":{"description":"With the `dob` scope.","format":"date","type":"string"},"email":{"description":"With the `email` scope (Carbons only): the primary email.","type":"string"},"email_verified":{"type":"boolean"},"id":{"description":"The c:id or si:id, for display; it can change.","type":["string","null"]},"kind":{"$ref":"#/components/schemas/AccountKind"},"membership_id":{"description":"`{app_id}:{uuid}`.","type":"string"},"pfp_url":{"format":"uri","type":"string"},"phone":{"description":"With the `phone` scope (Carbons only): the primary phone.","type":"string"},"phone_verified":{"type":"boolean"},"timezone":{"description":"With the `timezone` scope.","type":"string"},"updated_at":{"format":"date-time","type":"string"},"uuid":{"$ref":"#/components/schemas/AccountUuid"},"version":{"type":"integer"}},"required":["uuid","membership_id","kind","id","display_name","pfp_url","updated_at","version"],"type":"object"},"AccountId":{"description":"An account's current public id: `c:` for a Carbon, `si:` for a Silicon, then 3 to 30 characters of a-z 0-9 - _. Ids can change; key on the uuid.","examples":["c:ada","si:scout"],"pattern":"^(c|si):[a-z0-9_-]{3,30}$","type":"string"},"AccountKind":{"description":"`carbon` is a person, `silicon` an agent.","enum":["carbon","silicon"],"type":"string"},"AccountStatus":{"description":"`unclaimed`: created by an app import, not finished yet. `pending_custodian`: a self-created Silicon waiting for its custodian.","enum":["active","unclaimed","pending_custodian","deleted"],"type":"string"},"AccountSummary":{"description":"An account's public identity.","properties":{"custodian":{"description":"Only on a looked-up Silicon: its custodian.","oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]},"display_name":{"type":"string"},"id":{"description":"The current c:id or si:id; null once deleted.","type":["string","null"]},"kind":{"$ref":"#/components/schemas/AccountKind"},"pfp_url":{"format":"uri","type":"string"},"status":{"$ref":"#/components/schemas/AccountStatus"},"uuid":{"$ref":"#/components/schemas/AccountUuid"}},"required":["uuid","kind","id","display_name","pfp_url","status"],"type":"object"},"AccountUuid":{"description":"An account's permanent uuid: case-sensitive letters and digits, 3 characters, then 4 once every 3-character uuid is used. Never reused. Key on it.","examples":["8HV"],"pattern":"^[A-Za-z0-9]{3,}$","type":"string"},"AccountVerificationRequest":{"properties":{"account_uuid":{"type":"string"},"context_app":{"properties":{"app_id":{"type":"string"},"logo_url":{"type":["string","null"]},"name":{"type":"string"}},"required":["app_id","name"],"type":"object"},"reason":{"type":"string"},"request_id":{"format":"uuid","type":"string"},"response_expected_by":{"description":"A reply estimate, not a deadline.","format":"date-time","type":"string"},"reviewed_at":{"format":"date-time","type":["string","null"]},"status":{"enum":["pending","approved","rejected"],"type":"string"},"submitted_at":{"format":"date-time","type":"string"}},"required":["request_id","account_uuid","reason","status","submitted_at"],"type":"object"},"AccountVerificationState":{"properties":{"request":{"oneOf":[{"$ref":"#/components/schemas/AccountVerificationRequest"},{"type":"null"}]},"response_time_hours":{"type":"integer"}},"required":["request","response_time_hours"],"type":"object"},"AccountVerificationSubmit":{"additionalProperties":false,"properties":{"reason":{"description":"1 to 5000 characters after trimming, no NUL; plain text.","type":"string"}},"required":["reason"],"type":"object"},"AccountVerificationSubmitted":{"properties":{"created":{"description":"false when a pending request already existed (it is returned unchanged).","type":"boolean"},"request":{"$ref":"#/components/schemas/AccountVerificationRequest"},"response_time_hours":{"type":"integer"}},"required":["request","created","response_time_hours"],"type":"object"},"AgentCard":{"additionalProperties":true,"description":"An A2A agent card describing Silicon Accounts to agents.","properties":{"capabilities":{"properties":{"pushNotifications":{"type":"boolean"},"stateTransitionHistory":{"type":"boolean"},"streaming":{"type":"boolean"}},"type":"object"},"defaultInputModes":{"items":{"type":"string"},"type":"array"},"defaultOutputModes":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"documentationUrl":{"format":"uri","type":"string"},"name":{"type":"string"},"protocolVersion":{"type":"string"},"provider":{"properties":{"organization":{"type":"string"},"url":{"format":"uri","type":"string"}},"type":"object"},"security":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"securitySchemes":{"additionalProperties":true,"type":"object"},"skills":{"items":{"properties":{"description":{"type":"string"},"examples":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"tags":{"items":{"type":"string"},"type":"array"}},"required":["id","name","description"],"type":"object"},"type":"array"},"url":{"format":"uri","type":"string"},"version":{"type":"string"}},"required":["name","description","url","version","capabilities","defaultInputModes","defaultOutputModes","skills"],"type":"object"},"AllowedApps":{"properties":{"allowed_apps":{"description":"null: every app; a list: only these (empty: none).","items":{"type":"string"},"type":["array","null"]},"silicon":{"properties":{"id":{"type":["string","null"]},"uuid":{"type":"string"}},"required":["uuid"],"type":"object"}},"required":["allowed_apps"],"type":"object"},"AllowedAppsSet":{"additionalProperties":false,"properties":{"allowed_apps":{"description":"null for every app, or at most 100 app ids.","items":{"type":"string"},"type":["array","null"]}},"required":["allowed_apps"],"type":"object"},"App":{"properties":{"app_id":{"type":"string"},"config_version":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"description":{"type":["string","null"]},"homepage_url":{"type":["string","null"]},"logo_dark_url":{"type":["string","null"]},"logo_url":{"type":["string","null"]},"name":{"type":"string"},"owner":{"oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]},"signin_config":{"$ref":"#/components/schemas/SigninConfig"},"source":{"enum":["silicon_apps","fake","first_party"],"type":"string"},"stats":{"properties":{"active_last_30d":{"type":"integer"},"imported_unclaimed":{"type":"integer"},"users":{"type":"integer"}},"required":["users"],"type":"object"},"status":{"enum":["active","disabled"],"type":"string"},"updated_at":{"format":"date-time","type":"string"},"webhook":{"properties":{"secret_set":{"type":"boolean"},"url":{"type":["string","null"]}},"required":["url","secret_set"],"type":"object"}},"required":["app_id","name","status","source","signin_config","config_version","webhook"],"type":"object"},"AppId":{"description":"An app's id: 3 to 30 characters of a-z 0-9 - _, as Silicon Apps creates them; older ids of 2 to 40 characters of a-z 0-9 - starting with a letter keep working.","examples":["briefcase","my_app"],"pattern":"^(?:[a-z0-9_-]{3,30}|[a-z][a-z0-9-]{1,39})$","type":"string"},"AppProof":{"properties":{"access_ttl_seconds":{"type":"integer"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"description":"The proof's end.","format":"date-time","type":"string"},"kind":{"enum":["user_verification","app_verification"],"type":"string"},"last_refreshed_at":{"format":"date-time","type":["string","null"]},"proof_id":{"format":"uuid","type":"string"},"receiving_app":{"type":"string"},"revoke_reason":{"type":["string","null"]},"revoked_at":{"format":"date-time","type":["string","null"]},"scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["active","revoked","expired"],"type":"string"},"token_expires_at":{"description":"Its newest token's end.","format":"date-time","type":["string","null"]},"user":{"oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]}},"required":["proof_id","kind","receiving_app","scopes","status","created_at","expires_at"],"type":"object"},"AppSummary":{"properties":{"app_id":{"type":"string"},"homepage_url":{"type":["string","null"]},"logo_dark_url":{"type":["string","null"]},"logo_url":{"type":["string","null"]},"name":{"type":"string"}},"required":["app_id","name"],"type":"object"},"AppUser":{"description":"A member of the app's user base. Contact fields follow what the app may see.","properties":{"account_status":{"$ref":"#/components/schemas/AccountStatus"},"created_at":{"format":"date-time","type":"string"},"display_name":{"type":"string"},"dob":{"format":"date","type":"string"},"email":{"type":"string"},"external_id":{"type":["string","null"]},"first_signed_in_at":{"format":"date-time","type":["string","null"]},"granted_scopes":{"items":{"type":"string"},"type":"array"},"id":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/AccountKind"},"last_signed_in_at":{"format":"date-time","type":["string","null"]},"membership_id":{"type":"string"},"pfp_url":{"format":"uri","type":"string"},"phone":{"type":"string"},"source":{"enum":["signin","slt","import"],"type":"string"},"status":{"enum":["active","imported","access_removed","deleted"],"type":"string"},"timezone":{"type":"string"},"uuid":{"$ref":"#/components/schemas/AccountUuid"}},"required":["membership_id","uuid","kind","status","source"],"type":"object"},"AppUserDetail":{"allOf":[{"$ref":"#/components/schemas/AppUser"},{"properties":{"history":{"description":"The last 20 sign-ins at this app (no IP addresses).","items":{"properties":{"at":{"format":"date-time","type":"string"},"method":{"type":"string"},"outcome":{"type":"string"}},"required":["at","method","outcome"],"type":"object"},"type":"array"}},"required":["history"],"type":"object"}]},"AppVerificationRequest":{"additionalProperties":false,"description":"Unknown fields are refused.","properties":{"access_ttl_seconds":{"description":"The proof token's lifetime in seconds (default 1800).","maximum":1800,"minimum":60,"type":"integer"},"receiving_app":{"description":"Exactly one app; a body with `audiences` is 422 `app_verification_single_app`.","type":"string"},"scopes":{"description":"App-defined strings, at most 20.","items":{"pattern":"^[A-Za-z0-9_.:/-]{1,100}$","type":"string"},"maxItems":20,"type":"array"}},"required":["receiving_app"],"type":"object"},"AppWebhook":{"description":"The app's webhook. It is the app's webhook subscription, seen from the older endpoint.","properties":{"events":{"description":"null = every update.","items":{"$ref":"#/components/schemas/UpdateName"},"type":["array","null"]},"secret_set":{"type":"boolean"},"status":{"enum":["active","paused",null],"type":["string","null"]},"subscription_id":{"description":"The webhook subscription behind this webhook.","format":"uuid","type":["string","null"]},"url":{"format":"uri","type":["string","null"]}},"required":["url","secret_set","events","subscription_id","status"],"type":"object"},"AppWebhookSecret":{"properties":{"events":{"description":"The updates the webhook receives now; null = every update.","items":{"$ref":"#/components/schemas/UpdateName"},"type":["array","null"]},"secret":{"description":"`whsec_...`: the new signing secret, shown once, when this save made one (the app had none); null when the stored secret was kept.","type":["string","null"]},"url":{"format":"uri","type":"string"}},"required":["url","secret"],"type":"object"},"AppWebhookSet":{"additionalProperties":false,"description":"Unknown fields are refused.","properties":{"events":{"description":"The updates this webhook receives: absent keeps the current picks (every update for a new webhook), null picks every update, a list picks those.","items":{"$ref":"#/components/schemas/UpdateName"},"maxItems":9,"type":["array","null"]},"preserve_secret":{"deprecated":true,"description":"Accepted for compatibility and ignored: saving the URL always keeps the stored signing secret.","type":"boolean"},"url":{"description":"https, reaching a public address in production.","format":"uri","type":"string"}},"required":["url"],"type":"object"},"AppWebhookTest":{"properties":{"delivery_id":{"format":"uuid","type":"string"},"event_id":{"format":"uuid","type":"string"},"type":{"enum":["ping"],"type":"string"}},"required":["event_id","delivery_id","type"],"type":"object"},"AppsMailQueued":{"properties":{"recipients":{"type":"integer"},"status":{"enum":["queued"],"type":"string"}},"required":["status","recipients"],"type":"object"},"AppsMailRequest":{"additionalProperties":false,"properties":{"body":{"additionalProperties":true,"description":"mail.invite: `{to (email or c:id), account_uuid (with a c:id), app_id}`. mail.report: `{message (1 to 20000 bytes), pr (https, optional)}`.","type":"object"},"kind":{"enum":["mail.invite","mail.report"],"type":"string"}},"required":["kind","body"],"type":"object"},"AppsRegistry":{"properties":{"apps":{"items":{"properties":{"app_id":{"type":"string"},"authors":{"items":{"properties":{"display_name":{"type":"string"},"id":{"type":["string","null"]},"joined_at":{"type":"string"},"uuid":{"type":"string"}},"required":["uuid"],"type":"object"},"type":"array"},"created_at":{"type":"string"},"description":{"type":["string","null"]},"homepage_url":{"type":["string","null"]},"logo_url":{"type":["string","null"]},"name":{"type":"string"},"owner_uuid":{"type":["string","null"]},"source":{"type":"string"}},"required":["app_id","name","authors"],"type":"object"},"type":"array"}},"required":["apps"],"type":"object"},"AppsSyncReport":{"properties":{"apps":{"items":{"properties":{"action":{"enum":["created","updated","unchanged"],"type":"string"},"app_id":{"type":"string"},"changed":{"items":{"type":"string"},"type":"array"},"config":{"enum":["applied","reapplied","kept","unchanged"],"type":"string"},"config_version":{"type":"integer"},"owner":{"type":["string","null"]},"owner_created":{"type":"boolean"},"warnings":{"items":{"type":"string"},"type":"array"},"webhook":{"enum":["set","removed","kept","none"],"type":"string"}},"required":["app_id","action","owner","owner_created","config","config_version","webhook","changed","warnings"],"type":"object"},"type":"array"}},"required":["apps"],"type":"object"},"AppsSyncRequest":{"description":"`{\"apps\": [...]}` or a bare array, at most 5 MB.","oneOf":[{"properties":{"apps":{"items":{"$ref":"#/components/schemas/SiliconAppsApp"},"minItems":1,"type":"array"}},"required":["apps"],"type":"object"},{"items":{"$ref":"#/components/schemas/SiliconAppsApp"},"minItems":1,"type":"array"}]},"BrowserSession":{"properties":{"account":{"$ref":"#/components/schemas/AccountSummary"},"session":{"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"kind":{"enum":["browser"],"type":"string"},"last_seen_at":{"format":"date-time","type":["string","null"]}},"required":["id","kind","created_at","expires_at"],"type":"object"}},"required":["account","session"],"type":"object"},"Capabilities":{"description":"What this server can do, so a client can check before it relies on something.","properties":{"api_version":{"description":"The API version that served this answer.","type":"string"},"api_versions":{"description":"Every version this server serves.","items":{"type":"string"},"type":"array"},"auth_methods":{"items":{"properties":{"description":{"type":"string"},"header":{"type":"string"},"name":{"type":"string"}},"required":["name","description"],"type":"object"},"type":"array"},"capabilities":{"additionalProperties":{"$ref":"#/components/schemas/Capability"},"description":"Keyed by capability name: rest_json, openapi, structured_errors, rate_limit_headers, idempotency_keys, pagination, version_negotiation, capability_negotiation, bearer_tokens, client_credentials, oauth2, openid_connect, device_flow, short_lived_tokens, workload_identity_federation, identity_tokens, proofs, webhooks, webhook_signatures, webhook_replay, sse, stream_resume, subscriptions, imports, agent_card, mcp, llms_txt.","type":"object"},"limits":{"additionalProperties":true,"description":"Rate limits, sizes and lifetimes.","type":"object"},"links":{"properties":{"agent_card":{"format":"uri","type":"string"},"docs":{"format":"uri","type":"string"},"llms_txt":{"format":"uri","type":"string"},"mcp":{"format":"uri","type":"string"},"openapi":{"format":"uri","type":"string"}},"type":"object"},"public_url":{"format":"uri","type":"string"},"require":{"description":"Only with `?require=`.","properties":{"missing":{"items":{"type":"string"},"type":"array"},"requested":{"items":{"type":"string"},"type":"array"},"satisfied":{"type":"boolean"},"supported":{"items":{"type":"string"},"type":"array"}},"required":["requested","satisfied","supported","missing"],"type":"object"},"service":{"type":"string"},"version":{"description":"The service version.","type":"string"},"version_header":{"const":"Accounts-Version","type":"string"}},"required":["service","version","api_version","api_versions","version_header","public_url","capabilities","auth_methods","limits","links"],"type":"object"},"Capability":{"properties":{"description":{"type":"string"},"docs":{"format":"uri","type":"string"},"endpoints":{"description":"Method and path, like `GET /v1/events/stream`.","items":{"type":"string"},"type":"array"},"supported":{"type":"boolean"}},"required":["supported","description"],"type":"object"},"CliChallenge":{"properties":{"challenge_id":{"format":"uuid","type":"string"},"destination":{"description":"Masked.","type":"string"},"expires_at":{"format":"date-time","type":"string"}},"required":["challenge_id","destination","expires_at"],"type":"object"},"CliLoginStart":{"description":"Exactly one of `email` or `phone`. Unknown fields are ignored.","properties":{"country":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}},"type":"object"},"CliLoginVerify":{"properties":{"challenge_id":{"format":"uuid","type":"string"},"client_label":{"description":"Names the sign-in in the sessions list.","type":"string"},"code":{"type":"string"}},"required":["challenge_id","code"],"type":"object"},"CodeVerification":{"properties":{"challenge_id":{"format":"uuid","type":"string"},"code":{"pattern":"^[0-9]{6}$","type":"string"}},"required":["challenge_id","code"],"type":"object"},"ContactChallenge":{"description":"A 6-digit code was sent; verify it within 10 minutes.","properties":{"challenge_id":{"format":"uuid","type":"string"},"channel":{"enum":["email","phone"],"type":"string"},"destination":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"resend_available_at":{"format":"date-time","type":"string"}},"required":["challenge_id","channel","destination","expires_at"],"type":"object"},"CustodianRef":{"description":"A Silicon's custodian as apps see it.","properties":{"id":{"type":["string","null"]},"uuid":{"$ref":"#/components/schemas/AccountUuid"}},"required":["uuid","id"],"type":"object"},"CustodianRequest":{"description":"A request for a Carbon to become a Silicon's custodian. Requests last 14 days.","properties":{"created_at":{"format":"date-time","type":"string"},"decided_at":{"format":"date-time","type":["string","null"]},"expires_at":{"format":"date-time","type":"string"},"from":{"description":"Null for an initial request.","oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]},"id":{"format":"uuid","type":"string"},"kind":{"enum":["initial","transfer"],"type":"string"},"silicon":{"$ref":"#/components/schemas/AccountSummary"},"status":{"enum":["pending","accepted","declined","expired","cancelled"],"type":"string"},"to":{"description":"Null when the Carbon was named by an email with no account yet.","oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]}},"required":["id","kind","status","silicon","from","to","created_at","expires_at","decided_at"],"type":"object"},"CustodianRequestEnvelope":{"properties":{"request":{"$ref":"#/components/schemas/CustodianRequest"}},"required":["request"],"type":"object"},"DeleteConfirmation":{"additionalProperties":false,"properties":{"confirm":{"description":"The account's current id (case and the prefix don't matter).","type":"string"}},"required":["confirm"],"type":"object"},"DeviceAuthorization":{"properties":{"device_code":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"expires_in":{"type":"integer"},"interval":{"type":"integer"},"user_code":{"type":"string"},"verification_uri":{"format":"uri","type":"string"},"verification_uri_complete":{"format":"uri","type":"string"}},"required":["device_code","user_code","verification_uri","verification_uri_complete","expires_in","interval","expires_at"],"type":"object"},"DeviceAuthorizationRequest":{"properties":{"client_id":{"description":"`silicon-accounts` (the default), or your app's `app_id` when it turned on `device_flow`.","type":"string"},"client_label":{"description":"Shown on the approval page and in the sessions list; cut at 100 characters.","type":"string"},"scope":{"description":"For an app: details it requests to share (`email phone dob timezone`); its required details are always included. For the CLI: checked for typos only.","type":"string"}},"type":"object"},"DeviceRequest":{"properties":{"app":{"description":"For an app's tool: what the approval page shows.","properties":{"app_id":{"type":"string"},"branding":{"additionalProperties":true,"type":"object"},"copy":{"additionalProperties":true,"type":"object"},"description":{"type":"string"},"homepage_url":{"type":["string","null"]},"logo_dark_url":{"type":["string","null"]},"logo_url":{"type":["string","null"]},"name":{"type":"string"}},"required":["app_id","name"],"type":["object","null"]},"app_id":{"type":"string"},"client_label":{"type":["string","null"]},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"first_party":{"description":"True for the silicon-accounts CLI.","type":"boolean"},"scopes":{"description":"What the approving Carbon shares.","items":{"type":"string"},"type":"array"},"status":{"enum":["pending","approved","denied","consumed","expired"],"type":"string"},"user_code":{"type":"string"}},"required":["user_code","created_at","expires_at","status","app_id","first_party","scopes","app"],"type":"object"},"Email":{"description":"An email address of a Carbon.","properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"is_primary":{"type":"boolean"},"verified_at":{"format":"date-time","type":["string","null"]},"verified_via":{"enum":["code","google","apple",null],"type":["string","null"]}},"required":["email","is_primary","verified_at"],"type":"object"},"EmailAdd":{"properties":{"email":{"format":"email","type":"string"}},"required":["email"],"type":"object"},"Error":{"description":"Every error except those of the three OAuth endpoints. Branch on `code`; `message` says what was wrong, `hint` what to do next, `details` carries structured extras (`fields`, `retry_after_seconds`, `suggestions`, `request_id`, ...).","properties":{"error":{"properties":{"code":{"description":"Stable, snake_case. Branch on it, never on the message.","examples":["id_taken"],"type":"string"},"details":{"additionalProperties":true,"description":"Structured extras for this code.","type":"object"},"hint":{"description":"What to do next (sometimes absent).","type":"string"},"message":{"description":"What went wrong and why.","type":"string"}},"required":["code","message"],"type":"object"}},"required":["error"],"type":"object"},"Federation":{"description":"A trust relationship: tokens from `issuer`, for `audience`, whose claims equal every condition, sign the Silicon in.","properties":{"audience":{"description":"The `aud` the token must carry.","type":"string"},"conditions":{"additionalProperties":{"type":"string"},"description":"Claim name to the exact value it must have; every one must match.","type":"object"},"created_at":{"format":"date-time","type":"string"},"created_by":{"description":"The uuid of the Silicon or the custodian who added it.","type":"string"},"id":{"format":"uuid","type":"string"},"issuer":{"description":"The OIDC issuer, without a trailing slash.","format":"uri","type":"string"},"last_used_at":{"format":"date-time","type":["string","null"]},"name":{"type":"string"},"revoked_at":{"format":"date-time","type":["string","null"]}},"required":["id","name","issuer","audience","conditions","created_by","created_at","last_used_at","revoked_at"],"type":"object"},"FederationAdd":{"additionalProperties":false,"properties":{"audience":{"description":"The `aud` the token must carry; this service's public URL (`https://accounts.teamofsilicons.com`) when left out.","type":"string"},"conditions":{"additionalProperties":{"type":"string"},"description":"Claim name to exact value, for example `{\"repository\": \"acme/scout\", \"ref\": \"refs/heads/main\"}`. Not `iss`, `aud`, `exp`, `nbf`, `iat` or `jti`.","maxProperties":10,"minProperties":1,"type":"object"},"issuer":{"description":"An https OIDC issuer with discovery: `https://token.actions.githubusercontent.com` (GitHub Actions), `https://gitlab.com` (GitLab.com), or any other public one.","format":"uri","type":"string"},"name":{"description":"At most 100 characters; from the issuer when left out.","type":"string"}},"required":["issuer","conditions"],"type":"object"},"Flow":{"additionalProperties":true,"description":"One sign-in attempt in one browser (FlowView). `step` moves choose_method, verify_code, signup, details, review, then complete (or failed).","properties":{"app":{"additionalProperties":true,"description":"What the page needs to look like the app: name, logos, branding, copy, first_party.","type":"object"},"challenge":{"additionalProperties":true,"description":"At verify_code: channel, destination (masked), expires_at, resend_available_at.","type":["object","null"]},"details":{"additionalProperties":true,"description":"At details: the page on screen, with its fields.","type":["object","null"]},"error":{"additionalProperties":true,"description":"The last failure `{code, message, hint}` until the next action.","type":["object","null"]},"expires_at":{"format":"date-time","type":"string"},"id":{"type":"string"},"intent":{"enum":["signin","signup",null],"type":["string","null"]},"method_hint":{"type":["string","null"]},"methods":{"items":{"enum":["google","apple","email","phone"],"type":"string"},"type":"array"},"prompt":{"type":["string","null"]},"redirect_to":{"description":"At complete or failed: where to send the browser.","type":["string","null"]},"review":{"additionalProperties":true,"description":"At review: everything the app will see.","type":["object","null"]},"signed_in_as":{"oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]},"signup":{"additionalProperties":true,"description":"At signup: the prefilled details.","type":["object","null"]},"step":{"enum":["choose_method","verify_code","signup","details","review","complete","failed"],"type":"string"}},"required":["id","step","expires_at","app","methods"],"type":"object"},"FlowCode":{"properties":{"code":{"description":"The 6-digit code.","type":"string"}},"required":["code"],"type":"object"},"FlowCreate":{"additionalProperties":true,"description":"The `/authorize` query as JSON, plus the browser's `timezone`. Unknown fields are ignored; empty strings count as absent.","properties":{"app_id":{"type":"string"},"client_id":{"description":"Alias of `app_id`.","type":"string"},"code_challenge":{"type":"string"},"code_challenge_method":{"enum":["S256","plain"],"type":"string"},"intent":{"enum":["signin","signup"],"type":"string"},"login_hint":{"description":"Accepted and ignored.","type":"string"},"method":{"enum":["google","apple","email","phone"],"type":"string"},"nonce":{"type":"string"},"prompt":{"enum":["login","consent","select_account","none"],"type":"string"},"redirect_uri":{"type":"string"},"response_type":{"enum":["code"],"type":"string"},"scope":{"description":"Space-separated: profile, email, phone, dob, timezone, openid, offline_access.","type":"string"},"state":{"type":"string"},"timezone":{"description":"The browser's IANA timezone, used to prefill sign-up.","type":"string"}},"required":["redirect_uri"],"type":"object"},"FlowDetailAdd":{"description":"Exactly one of `email` or `phone` (with an optional `country`).","properties":{"country":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}},"type":"object"},"FlowDetailsContinue":{"properties":{"share":{"description":"The optional details of this page the Carbon ticked.","items":{"enum":["email","phone","dob","timezone"],"type":"string"},"type":"array"}},"type":"object"},"FlowEmail":{"properties":{"email":{"type":"string"}},"required":["email"],"type":"object"},"FlowEnvelope":{"properties":{"flow":{"$ref":"#/components/schemas/Flow"}},"required":["flow"],"type":"object"},"FlowPhone":{"properties":{"country":{"description":"ISO code for a local number.","type":"string"},"phone":{"type":"string"}},"required":["phone"],"type":"object"},"FlowReview":{"properties":{"approve":{"description":"true completes the sign-in; false is Cancel (`error=access_denied`).","type":"boolean"}},"required":["approve"],"type":"object"},"FlowSignup":{"description":"Every field is optional; missing ones keep the prefill.","properties":{"display_name":{"description":"1 to 100 characters.","type":"string"},"dob":{"description":"In the past, not before 1900-01-01.","format":"date","type":"string"},"id":{"description":"A free c: id (a bare handle gets the prefix).","type":"string"},"pfp_url":{"description":"An https URL, this sign-up's own upload, or null for the default photo.","type":["string","null"]},"timezone":{"type":"string"}},"type":"object"},"HistoryItem":{"properties":{"app":{"oneOf":[{"$ref":"#/components/schemas/AppSummary"},{"type":"null"}]},"at":{"format":"date-time","type":"string"},"detail":{"type":["string","null"]},"id":{"type":"string"},"kind":{"enum":["signin","id_change","custodian","proof","app_access","security"],"type":"string"},"meta":{"additionalProperties":true,"type":"object"},"title":{"type":"string"}},"required":["id","kind","at","title"],"type":"object"},"IdAvailability":{"properties":{"available":{"type":"boolean"},"id":{"type":"string"},"message":{"type":"string"},"reason":{"description":"Why it isn't available; null when it is.","enum":["taken","reserved","reserved_word","invalid",null],"type":["string","null"]},"reclaimable":{"description":"True when the id is reserved for you (or for your Silicon, with `for`) and you can take it back.","type":"boolean"},"suggestions":{"description":"Up to three free ids close to the one asked for.","items":{"type":"string"},"type":"array"}},"required":["id","available","reason","message","reclaimable","suggestions"],"type":"object"},"IdChange":{"additionalProperties":false,"properties":{"id":{"description":"The new id; a bare handle gets your prefix.","type":"string"}},"required":["id"],"type":"object"},"IdentityAudiences":{"properties":{"audiences":{"description":"Empty: no identity tokens at all.","items":{"type":"string"},"type":"array"},"silicon":{"properties":{"id":{"type":["string","null"]},"uuid":{"type":"string"}},"required":["uuid"],"type":"object"}},"required":["silicon","audiences"],"type":"object"},"IdentityAudiencesSet":{"additionalProperties":false,"properties":{"audiences":{"items":{"maxLength":400,"type":"string"},"maxItems":20,"type":"array"}},"required":["audiences"],"type":"object"},"IdentityLink":{"properties":{"authorize_url":{"format":"uri","type":"string"},"expires_at":{"format":"date-time","type":"string"},"flow_id":{"type":"string"},"provider":{"enum":["google","apple"],"type":"string"}},"required":["authorize_url","flow_id","provider","expires_at"],"type":"object"},"IdentityLinkStart":{"additionalProperties":false,"properties":{"return_to":{"description":"A path or URL on the account site; defaults to /sign-in-methods.","type":"string"}},"type":"object"},"IdentityToken":{"properties":{"audience":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"expires_in":{"type":"integer"},"identity_token":{"description":"The RS256 JWT to hand the outside service.","type":"string"},"issued_at":{"format":"date-time","type":"string"},"issuer":{"format":"uri","type":"string"},"jti":{"type":"string"},"kid":{"description":"The signing key's id in the JWKS.","type":"string"},"subject":{"description":"The Silicon's uuid (`sub`).","type":"string"},"token_type":{"enum":["urn:ietf:params:oauth:token-type:id_token"],"type":"string"}},"required":["identity_token","token_type","issuer","subject","audience","jti","kid","issued_at","expires_at","expires_in"],"type":"object"},"IdentityTokenRequest":{"additionalProperties":false,"properties":{"audience":{"description":"One of the Silicon's allowed audiences.","type":"string"},"ttl_seconds":{"default":300,"maximum":3600,"minimum":60,"type":"integer"}},"required":["audience"],"type":"object"},"ImportJob":{"properties":{"app_id":{"type":"string"},"counts":{"properties":{"created":{"type":"integer"},"error":{"type":"integer"},"matched":{"type":"integer"},"skipped":{"type":"integer"},"updated":{"type":"integer"},"warnings":{"type":"integer"}},"type":"object"},"created_at":{"format":"date-time","type":"string"},"created_by":{"type":"string"},"dry_run":{"type":"boolean"},"error":{"type":["string","null"]},"finished_at":{"format":"date-time","type":["string","null"]},"format":{"enum":["csv","json"],"type":"string"},"id":{"format":"uuid","type":"string"},"options":{"$ref":"#/components/schemas/ImportOptions"},"processed_rows":{"type":"integer"},"started_at":{"format":"date-time","type":["string","null"]},"status":{"enum":["queued","running","completed","failed"],"type":"string"},"total_rows":{"type":"integer"}},"required":["id","app_id","status","format","dry_run","total_rows","processed_rows","counts","created_at"],"type":"object"},"ImportJobEnvelope":{"properties":{"job":{"$ref":"#/components/schemas/ImportJob"}},"required":["job"],"type":"object"},"ImportOptions":{"additionalProperties":false,"properties":{"default_country":{"description":"ISO code for local phone numbers.","type":"string"},"dry_run":{"description":"Decide everything, write nothing.","type":"boolean"},"ignore_unknown_columns":{"type":"boolean"},"update_existing":{"type":"boolean"}},"type":"object"},"ImportRequest":{"properties":{"options":{"$ref":"#/components/schemas/ImportOptions"},"rows":{"description":"Columns: external_id, email, emails, phone, phones, display_name (alias name), username, dob, timezone, pfp_url, email_verified.","items":{"additionalProperties":true,"type":"object"},"maxItems":100000,"type":"array"}},"required":["rows"],"type":"object"},"ImportRow":{"properties":{"account_uuid":{"description":"Always null in a dry run.","type":["string","null"]},"id":{"type":["string","null"]},"input":{"additionalProperties":true,"type":"object"},"messages":{"items":{"properties":{"code":{"type":"string"},"level":{"enum":["error","warning","info"],"type":"string"},"message":{"type":"string"}},"required":["level","code","message"],"type":"object"},"type":"array"},"outcome":{"enum":["pending","created","matched","updated","skipped","error"],"type":"string"},"row_number":{"type":"integer"}},"required":["row_number","outcome","messages"],"type":"object"},"InitialRequest":{"properties":{"custodian":{"description":"The c:id, or the masked email it was named by.","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"kind":{"enum":["initial"],"type":"string"},"status":{"enum":["pending","accepted","declined","expired","cancelled"],"type":"string"}},"required":["id","kind","status","custodian","expires_at"],"type":"object"},"IntrospectRequest":{"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"token":{"type":"string"},"token_type_hint":{"type":"string"}},"required":["token"],"type":"object"},"Introspection":{"description":"An inactive, unknown or other app's token is exactly `{\"active\": false}`.","properties":{"active":{"type":"boolean"},"aud":{"type":"string"},"client_id":{"type":"string"},"exp":{"type":"integer"},"iat":{"type":"integer"},"id":{"type":"string"},"iss":{"type":"string"},"jti":{"type":"string"},"kind":{"$ref":"#/components/schemas/AccountKind"},"membership_id":{"type":"string"},"nbf":{"type":"integer"},"scope":{"type":"string"},"sub":{"type":"string"},"token_type":{"enum":["access_token","refresh_token"],"type":"string"},"username":{"type":"string"}},"required":["active"],"type":"object"},"IssuedProof":{"properties":{"expires_at":{"description":"When this proof token expires.","format":"date-time","type":"string"},"issuing_app":{"type":"string"},"kind":{"enum":["user_verification","app_verification"],"type":"string"},"proof_id":{"format":"uuid","type":"string"},"proof_refresh_token":{"description":"`sapr_...`: keep it yourself; it rotates on every refresh.","type":"string"},"proof_token":{"description":"`sap_...`: give it to the receiving app.","type":"string"},"receiving_app":{"type":"string"},"refresh_expires_at":{"format":"date-time","type":"string"},"scopes":{"items":{"type":"string"},"type":"array"},"user":{"description":"null for an App verification proof.","oneOf":[{"$ref":"#/components/schemas/ProofUser"},{"type":"null"}]}},"required":["proof_id","kind","proof_token","expires_at","proof_refresh_token","refresh_expires_at","issuing_app","receiving_app","user","scopes"],"type":"object"},"Jwks":{"description":"The keys that sign our tokens, each found by its `kid`: the Ed25519 key (`kty OKP`, `alg EdDSA`) of access tokens and id_tokens, then the RSA key (`kty RSA`, `alg RS256`) of identity tokens, which cloud providers verify. Fetch again when a token names a `kid` you don't have.","properties":{"keys":{"items":{"properties":{"alg":{"type":"string"},"crv":{"type":"string"},"e":{"description":"RSA exponent, base64url.","type":"string"},"kid":{"type":"string"},"kty":{"type":"string"},"n":{"description":"RSA modulus, base64url.","type":"string"},"use":{"type":"string"},"x":{"type":"string"}},"required":["kty","kid"],"type":"object"},"type":"array"}},"required":["keys"],"type":"object"},"LinkedIdentity":{"description":"A Google or Apple account linked to a Carbon.","properties":{"created_at":{"format":"date-time","type":"string"},"email":{"type":["string","null"]},"last_used_at":{"format":"date-time","type":["string","null"]},"provider":{"enum":["google","apple"],"type":"string"},"subject":{"description":"The provider's account id.","type":"string"}},"required":["provider","subject","created_at"],"type":"object"},"ManagedAppVerification":{"allOf":[{"$ref":"#/components/schemas/AppProof"},{"properties":{"issuing_app":{"$ref":"#/components/schemas/AppSummary"}},"required":["issuing_app"],"type":"object"}]},"Me":{"description":"Your own account, as `GET /v1/me` shows it.","discriminator":{"mapping":{"carbon":"#/components/schemas/MeCarbon","silicon":"#/components/schemas/MeSilicon"},"propertyName":"kind"},"oneOf":[{"$ref":"#/components/schemas/MeCarbon"},{"$ref":"#/components/schemas/MeSilicon"}]},"MeCarbon":{"description":"A Carbon's own account.","properties":{"created_at":{"format":"date-time","type":"string"},"custodian_of":{"description":"How many Silicons this Carbon is custodian of.","type":"integer"},"display_name":{"type":"string"},"dob":{"description":"Date of birth. A Silicon's is the day it was created.","format":"date","type":"string"},"emails":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"},"id":{"description":"The current c:id or si:id; null once deleted.","type":["string","null"]},"identities":{"items":{"$ref":"#/components/schemas/LinkedIdentity"},"type":"array"},"kind":{"const":"carbon","type":"string"},"pfp_url":{"format":"uri","type":"string"},"phones":{"items":{"$ref":"#/components/schemas/Phone"},"type":"array"},"status":{"$ref":"#/components/schemas/AccountStatus"},"timezone":{"description":"IANA timezone, like Asia/Kolkata.","type":"string"},"updated_at":{"format":"date-time","type":"string"},"uuid":{"$ref":"#/components/schemas/AccountUuid"},"version":{"description":"Bumps on every change apps can see.","type":"integer"}},"required":["uuid","kind","id","display_name","pfp_url","dob","timezone","status","created_at","updated_at","version","emails","phones","identities","custodian_of"],"type":"object"},"MePhotoUpload":{"properties":{"me":{"$ref":"#/components/schemas/Me"},"pfp_url":{"format":"uri","type":"string"},"photo":{"$ref":"#/components/schemas/PhotoInfo"}},"required":["pfp_url","photo","me"],"type":"object"},"MeSilicon":{"description":"A Silicon's own account.","properties":{"created_at":{"format":"date-time","type":"string"},"custodian":{"description":"The Carbon responsible for this Silicon; null while it waits for one.","oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]},"display_name":{"type":"string"},"dob":{"description":"Date of birth. A Silicon's is the day it was created.","format":"date","type":"string"},"id":{"description":"The current c:id or si:id; null once deleted.","type":["string","null"]},"kind":{"const":"silicon","type":"string"},"pfp_url":{"format":"uri","type":"string"},"status":{"$ref":"#/components/schemas/AccountStatus"},"stk_rotated_at":{"format":"date-time","type":["string","null"]},"timezone":{"description":"IANA timezone, like Asia/Kolkata.","type":"string"},"updated_at":{"format":"date-time","type":"string"},"uuid":{"$ref":"#/components/schemas/AccountUuid"},"version":{"description":"Bumps on every change apps can see.","type":"integer"},"webhook_url":{"description":"The Silicon's own webhook.","type":["string","null"]}},"required":["uuid","kind","id","display_name","pfp_url","dob","timezone","status","created_at","updated_at","version","custodian","webhook_url","stk_rotated_at"],"type":"object"},"MeUpdate":{"additionalProperties":false,"description":"Only real changes are written. Unknown fields are refused, naming the endpoint that owns them (`email`, `id`).","properties":{"display_name":{"description":"1 to 100 characters after trimming, no control characters.","type":"string"},"dob":{"description":"Carbons only: in the past, not before 1900-01-01. A Silicon's dob can't change (422 `dob_immutable`).","format":"date","type":"string"},"pfp_url":{"description":"An https URL (at most 2048 characters), your own upload as `POST /v1/me/photo` returned it, or null for the default photo.","type":["string","null"]},"timezone":{"description":"An IANA timezone; case is normalized.","type":"string"}},"type":"object"},"Meta":{"properties":{"delivery":{"description":"`local`: nothing is sent (development only).","enum":["providers","local"],"type":"string"},"developer_url":{"format":"uri","type":"string"},"docs_url":{"format":"uri","type":"string"},"environment":{"enum":["production","development","test"],"type":"string"},"name":{"type":"string"},"providers":{"description":"Whether one-click (managed) Google and Apple are configured.","properties":{"apple":{"type":"boolean"},"google":{"type":"boolean"}},"required":["google","apple"],"type":"object"},"public_url":{"format":"uri","type":"string"},"silicon_apps_url":{"format":"uri","type":"string"},"version":{"type":"string"}},"required":["name","version","environment","public_url"],"type":"object"},"MyApp":{"description":"An app you signed into.","properties":{"access_removed_at":{"format":"date-time","type":["string","null"]},"active_sessions":{"type":"integer"},"app":{"$ref":"#/components/schemas/AppSummary"},"first_signed_in_at":{"format":"date-time","type":["string","null"]},"granted_scopes":{"items":{"type":"string"},"type":"array"},"last_signed_in_at":{"format":"date-time","type":["string","null"]},"membership_id":{"description":"`{app_id}:{uuid}`.","type":"string"},"source":{"enum":["signin","slt","import"],"type":"string"},"status":{"enum":["active","access_removed","imported"],"type":"string"}},"required":["app","membership_id","status","source","granted_scopes"],"type":"object"},"MyProof":{"properties":{"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","type":"string"},"issuing_app":{"$ref":"#/components/schemas/AppSummary"},"last_refreshed_at":{"format":"date-time","type":["string","null"]},"proof_id":{"format":"uuid","type":"string"},"receiving_app":{"$ref":"#/components/schemas/AppSummary"},"revoke_reason":{"type":["string","null"]},"revoked_at":{"format":"date-time","type":["string","null"]},"scopes":{"items":{"type":"string"},"type":"array"},"status":{"enum":["active","revoked","expired"],"type":"string"},"token_expires_at":{"format":"date-time","type":["string","null"]}},"required":["proof_id","issuing_app","receiving_app","scopes","status","created_at","expires_at"],"type":"object"},"OAuthError":{"description":"The error body of `/v1/oauth/token`, `/v1/oauth/revoke` and `/v1/oauth/introspect` (RFC 6749), because OAuth libraries read `error` as a string.","properties":{"error":{"description":"An RFC 6749 error: `invalid_request`, `invalid_client`, `invalid_grant`, `unauthorized_client`, `unsupported_grant_type`, `invalid_scope`, `authorization_pending`, `slow_down`, `access_denied`, `expired_token`, `server_error` or `temporarily_unavailable`.","type":"string"},"error_description":{"description":"Exactly which reason applied, in words.","type":"string"}},"required":["error"],"type":"object"},"OpenIdConfiguration":{"additionalProperties":true,"properties":{"authorization_endpoint":{"format":"uri","type":"string"},"claims_parameter_supported":{"type":"boolean"},"claims_supported":{"items":{"type":"string"},"type":"array"},"code_challenge_methods_supported":{"items":{"type":"string"},"type":"array"},"device_authorization_endpoint":{"format":"uri","type":"string"},"grant_types_supported":{"items":{"type":"string"},"type":"array"},"id_token_signing_alg_values_supported":{"items":{"type":"string"},"type":"array"},"introspection_endpoint":{"format":"uri","type":"string"},"introspection_endpoint_auth_methods_supported":{"items":{"type":"string"},"type":"array"},"issuer":{"format":"uri","type":"string"},"jwks_uri":{"format":"uri","type":"string"},"prompt_values_supported":{"items":{"type":"string"},"type":"array"},"request_parameter_supported":{"type":"boolean"},"request_uri_parameter_supported":{"type":"boolean"},"response_modes_supported":{"items":{"type":"string"},"type":"array"},"response_types_supported":{"items":{"type":"string"},"type":"array"},"revocation_endpoint":{"format":"uri","type":"string"},"revocation_endpoint_auth_methods_supported":{"items":{"type":"string"},"type":"array"},"scopes_supported":{"items":{"type":"string"},"type":"array"},"service_documentation":{"format":"uri","type":"string"},"subject_types_supported":{"items":{"type":"string"},"type":"array"},"token_endpoint":{"format":"uri","type":"string"},"token_endpoint_auth_methods_supported":{"items":{"type":"string"},"type":"array"},"userinfo_endpoint":{"format":"uri","type":"string"}},"required":["issuer","authorization_endpoint","token_endpoint","jwks_uri"],"type":"object"},"OutboxMessage":{"properties":{"attempts":{"type":"integer"},"channel":{"enum":["email","sms"],"type":"string"},"code":{"description":"The 6-digit code of an otp_* message.","type":["string","null"]},"created_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"last_error":{"type":["string","null"]},"purpose":{"type":"string"},"sent_at":{"format":"date-time","type":["string","null"]},"status":{"type":"string"},"subject":{"type":["string","null"]},"text_body":{"type":"string"},"to":{"type":"string"}},"required":["id","channel","to","text_body","purpose","status","created_at","code"],"type":"object"},"OwnedApp":{"properties":{"app_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"logo_url":{"type":["string","null"]},"name":{"type":"string"},"source":{"type":"string"},"status":{"enum":["active","disabled"],"type":"string"},"users":{"type":"integer"}},"required":["app_id","name","status"],"type":"object"},"Page":{"description":"A list page. Cursors are keyset positions, so pages neither skip nor repeat items while new ones arrive.","properties":{"items":{"description":"This page's items.","items":{},"type":"array"},"next_cursor":{"description":"Pass it back unchanged as `cursor` for the next page; null on the last page.","type":["string","null"]}},"required":["items","next_cursor"],"type":"object"},"Phone":{"description":"A phone number of a Carbon. Phones are only ever verified by code.","properties":{"created_at":{"format":"date-time","type":"string"},"is_primary":{"type":"boolean"},"phone":{"description":"E.164, like +919876543210.","type":"string"},"verified_at":{"format":"date-time","type":["string","null"]},"verified_via":{"enum":["code",null],"type":["string","null"]}},"required":["phone","is_primary","verified_at"],"type":"object"},"PhoneAdd":{"properties":{"country":{"description":"ISO 3166 country code for a local number, like IN.","type":"string"},"phone":{"description":"E.164 (+919876543210), or a local number with `country`.","type":"string"}},"required":["phone"],"type":"object"},"PhotoInfo":{"properties":{"bytes":{"type":"integer"},"content_type":{"enum":["image/png","image/jpeg","image/webp","image/gif"],"type":"string"},"height":{"type":"integer"},"id":{"format":"uuid","type":"string"},"width":{"type":"integer"}},"required":["id","content_type","bytes","width","height"],"type":"object"},"ProofRefreshRequest":{"additionalProperties":false,"properties":{"access_ttl_seconds":{"description":"The proof token's lifetime in seconds (default 1800).","maximum":1800,"minimum":60,"type":"integer"},"proof_refresh_token":{"type":"string"}},"required":["proof_refresh_token"],"type":"object"},"ProofRevokeRequest":{"description":"Exactly one of `proof_id`, `proof_token` or `proof_refresh_token`.","oneOf":[{"additionalProperties":false,"properties":{"proof_id":{"format":"uuid","type":"string"}},"required":["proof_id"],"type":"object"},{"additionalProperties":false,"properties":{"proof_token":{"type":"string"}},"required":["proof_token"],"type":"object"},{"additionalProperties":false,"properties":{"proof_refresh_token":{"type":"string"}},"required":["proof_refresh_token"],"type":"object"}]},"ProofUser":{"properties":{"id":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/AccountKind"},"membership_id":{"description":"The membership with the issuing app.","type":"string"},"uuid":{"$ref":"#/components/schemas/AccountUuid"}},"required":["uuid","id","kind","membership_id"],"type":"object"},"ProofVerification":{"description":"Anything that doesn't verify is exactly `{\"valid\": false, \"expires_at\": null}`.","properties":{"expires_at":{"format":"date-time","type":["string","null"]},"issuing_app":{"properties":{"app_id":{"type":"string"},"name":{"type":"string"}},"required":["app_id","name"],"type":"object"},"kind":{"enum":["user_verification","app_verification"],"type":"string"},"proof_id":{"format":"uuid","type":"string"},"receiving_app":{"properties":{"app_id":{"type":"string"},"name":{"type":"string"}},"required":["app_id","name"],"type":"object"},"scopes":{"items":{"type":"string"},"type":"array"},"user":{"oneOf":[{"$ref":"#/components/schemas/ProofUser"},{"type":"null"}]},"valid":{"type":"boolean"}},"required":["valid","expires_at"],"type":"object"},"ProofVerifyRequest":{"additionalProperties":false,"properties":{"proof_token":{"description":"`sap_...`.","type":"string"}},"required":["proof_token"],"type":"object"},"ProviderUrl":{"properties":{"authorize_url":{"format":"uri","type":"string"}},"required":["authorize_url"],"type":"object"},"PublicApp":{"properties":{"allowed_origins":{"description":"Origins that may frame the sign-in iframe.","items":{"type":"string"},"type":"array"},"app_id":{"type":"string"},"branding":{"additionalProperties":true,"type":"object"},"copy":{"additionalProperties":true,"type":"object"},"homepage_url":{"type":["string","null"]},"logo_dark_url":{"type":["string","null"]},"logo_url":{"type":["string","null"]},"methods":{"description":"The enabled methods, in order.","items":{"enum":["google","apple","email","phone"],"type":"string"},"type":"array"},"name":{"type":"string"}},"required":["app_id","name","methods"],"type":"object"},"Readiness":{"properties":{"database":{"enum":["ok","unavailable"],"type":"string"},"error":{"additionalProperties":true,"description":"When unavailable: `{code: database_unavailable, message, hint}`.","type":"object"}},"required":["database"],"type":"object"},"ReplayRequest":{"description":"Either `delivery_ids` (1 to 100), or `status: failed` (with an optional `since`) for up to 100 failed deliveries, oldest first. Unknown fields are refused.","oneOf":[{"additionalProperties":false,"properties":{"delivery_ids":{"items":{"format":"uuid","type":"string"},"maxItems":100,"minItems":1,"type":"array"}},"required":["delivery_ids"],"type":"object"},{"additionalProperties":false,"properties":{"since":{"description":"Only deliveries created since then.","format":"date-time","type":"string"},"status":{"enum":["failed"],"type":"string"}},"required":["status"],"type":"object"}]},"ReplayResult":{"properties":{"not_replayable":{"description":"Failed deliveries that will never be sent again.","type":"integer"},"remaining":{"description":"By status: failed deliveries still waiting. Call again with a new Idempotency-Key until it is 0.","type":"integer"},"replayed":{"items":{"format":"uuid","type":"string"},"type":"array"},"skipped":{"items":{"properties":{"delivery_id":{"format":"uuid","type":"string"},"event_id":{"format":"uuid","type":"string"},"message":{"type":"string"},"reason":{"enum":["not_found","already_pending","test_ping","membership_inactive","account_deleted"],"type":"string"},"type":{"type":"string"}},"required":["delivery_id","reason","message"],"type":"object"},"type":"array"},"url":{"description":"The current URL the replays go to.","format":"uri","type":"string"}},"required":["replayed","skipped","remaining","not_replayable","url"],"type":"object"},"Report":{"properties":{"recipients":{"type":"integer"},"report_id":{"format":"uuid","type":"string"},"status":{"enum":["queued"],"type":"string"}},"required":["report_id","status","recipients"],"type":"object"},"ReportRequest":{"additionalProperties":false,"description":"Unknown fields are refused.","properties":{"message":{"maxLength":10000,"minLength":1,"type":"string"},"pr_url":{"description":"https: a pull request that fixes it.","format":"uri","type":"string"}},"required":["message"],"type":"object"},"RevokeRequest":{"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"token":{"description":"A refresh token or an access token (an expired access token works too).","type":"string"},"token_type_hint":{"description":"Accepted and ignored.","type":"string"}},"required":["token"],"type":"object"},"RevokeResult":{"description":"Always 200 once the client is authenticated, so the endpoint can't probe tokens.","properties":{"message":{"description":"When nothing was revoked: why.","type":"string"},"revoked":{"type":"boolean"}},"required":["revoked"],"type":"object"},"SessionItem":{"properties":{"created_at":{"format":"date-time","type":"string"},"current":{"description":"The session making this request.","type":"boolean"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"ip":{"type":["string","null"]},"kind":{"enum":["browser","cli","developer"],"type":"string"},"label":{"type":["string","null"]},"last_seen_at":{"format":"date-time","type":["string","null"]},"origin":{"description":"How a CLI sign-in started.","enum":["cli_code","device","silicon_login",null],"type":["string","null"]},"user_agent":{"type":["string","null"]}},"required":["id","kind","created_at","expires_at","current"],"type":"object"},"ShortLivedToken":{"properties":{"app_id":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"scope":{"type":"string"},"slt":{"description":"`slt_...`: single use, 120 seconds, only at this app.","type":"string"}},"required":["slt","app_id","scope","expires_at"],"type":"object"},"ShortLivedTokenRequest":{"additionalProperties":false,"properties":{"app_id":{"$ref":"#/components/schemas/AppId"}},"required":["app_id"],"type":"object"},"SigninConfig":{"additionalProperties":true,"description":"An app's sign-in setup. Secrets are never returned: `client_secret_set` and `private_key_set` say whether one is stored.","properties":{"allow_signup":{"type":"boolean"},"allowed_email_domains":{"description":"At most 100; empty = any.","items":{"type":"string"},"type":"array"},"allowed_origins":{"description":"At most 50 origins that may frame the sign-in iframe.","items":{"type":"string"},"type":"array"},"apple":{"additionalProperties":true,"description":"`mode` (managed or byo), `services_id`, `team_id`, `key_id`, `private_key_set`.","type":"object"},"branding":{"additionalProperties":true,"type":"object"},"copy":{"additionalProperties":true,"type":"object"},"device_flow":{"description":"Let the app's own command-line tool sign Carbons in with a code (RFC 8628), with `client_id` alone. Default false.","type":"boolean"},"flow":{"additionalProperties":true,"description":"The app's pages: `{steps: [{id, fields, title, subtitle, continue_label, layout}], review}`.","type":["object","null"]},"google":{"additionalProperties":true,"description":"`mode` (managed or byo), `client_id`, `prompt`, `hosted_domain`, `client_secret_set`.","type":"object"},"method_order":{"items":{"enum":["google","apple","email","phone"],"type":"string"},"type":"array"},"methods":{"description":"At least one enabled.","properties":{"apple":{"type":"boolean"},"email":{"type":"boolean"},"google":{"type":"boolean"},"phone":{"type":"boolean"}},"type":"object"},"optional_fields":{"description":"A checkbox on the details page.","items":{"enum":["email","phone","dob","timezone"],"type":"string"},"type":"array"},"public_client":{"description":"The app's desktop and command-line tools are public clients (RFC 8252): codes with PKCE S256 and refresh with `client_id` alone. Default false.","type":"boolean"},"redirect_uris":{"description":"At most 50.","items":{"type":"string"},"type":"array"},"remember_browser":{"type":"boolean"},"required_fields":{"description":"Always shared.","items":{"enum":["email","phone","dob","timezone"],"type":"string"},"type":"array"}},"type":"object"},"SigninConfigPatch":{"additionalProperties":false,"description":"A partial sign-in config: objects merge, arrays and plain values replace, null resets a field to its default. Unknown keys are refused. Provider secrets ride along (`google.client_secret`, `apple.private_key`) and are stored encrypted. Body limit 512 KB.","properties":{"allow_signup":{"type":["boolean","null"]},"allowed_email_domains":{"description":"At most 100; empty = any.","items":{"type":"string"},"type":["array","null"]},"allowed_origins":{"description":"At most 50 origins that may frame the sign-in iframe.","items":{"type":"string"},"type":["array","null"]},"apple":{"additionalProperties":true,"description":"`mode` (managed or byo), `services_id`, `team_id`, `key_id`, `private_key_set`.","type":["object","null"]},"branding":{"additionalProperties":true,"type":["object","null"]},"copy":{"additionalProperties":true,"type":["object","null"]},"device_flow":{"description":"Let the app's own command-line tool sign Carbons in with a code (RFC 8628), with `client_id` alone. Default false.","type":["boolean","null"]},"expected_version":{"description":"The `config_version` you read; a different current version is 409 `config_version_conflict`.","type":"integer"},"flow":{"additionalProperties":true,"description":"The app's pages: `{steps: [{id, fields, title, subtitle, continue_label, layout}], review}`.","type":["object","null"]},"google":{"additionalProperties":true,"description":"`mode` (managed or byo), `client_id`, `prompt`, `hosted_domain`, `client_secret_set`.","type":["object","null"]},"method_order":{"items":{"enum":["google","apple","email","phone"],"type":"string"},"type":["array","null"]},"methods":{"description":"At least one enabled.","properties":{"apple":{"type":"boolean"},"email":{"type":"boolean"},"google":{"type":"boolean"},"phone":{"type":"boolean"}},"type":"object"},"optional_fields":{"description":"A checkbox on the details page.","items":{"enum":["email","phone","dob","timezone"],"type":"string"},"type":["array","null"]},"public_client":{"description":"The app's desktop and command-line tools are public clients (RFC 8252): codes with PKCE S256 and refresh with `client_id` alone. Default false.","type":["boolean","null"]},"redirect_uris":{"description":"At most 50.","items":{"type":"string"},"type":["array","null"]},"remember_browser":{"type":["boolean","null"]},"required_fields":{"description":"Always shared.","items":{"enum":["email","phone","dob","timezone"],"type":"string"},"type":["array","null"]}},"type":"object"},"SigninConfigVersion":{"properties":{"actor":{"description":"`app`, `system`, or the author's uuid.","type":"string"},"actor_account":{"oneOf":[{"$ref":"#/components/schemas/AccountSummary"},{"type":"null"}]},"at":{"format":"date-time","type":"string"},"changes":{"description":"Secrets show as \"[redacted]\".","items":{"properties":{"after":{},"before":{},"path":{"type":"string"},"secret":{"type":"boolean"}},"required":["path"],"type":"object"},"type":"array"},"version":{"type":"integer"}},"required":["version","actor","at","changes"],"type":"object"},"SignupPhotoUpload":{"properties":{"pfp_url":{"format":"uri","type":"string"},"photo":{"$ref":"#/components/schemas/PhotoInfo"}},"required":["pfp_url","photo"],"type":"object"},"SiliconApp":{"properties":{"access_removed_at":{"format":"date-time","type":["string","null"]},"active_sessions":{"type":"integer"},"app":{"$ref":"#/components/schemas/AppSummary"},"first_signed_in_at":{"format":"date-time","type":["string","null"]},"granted_scopes":{"items":{"type":"string"},"type":"array"},"last_signed_in_at":{"format":"date-time","type":["string","null"]},"membership_id":{"type":"string"},"source":{"type":"string"},"status":{"enum":["active","access_removed","imported"],"type":"string"}},"required":["app","membership_id","status","granted_scopes","active_sessions"],"type":"object"},"SiliconAppsApp":{"properties":{"app_id":{"type":"string"},"author_uuids":{"description":"Complete accepted authorship; omitted keeps the current authors.","items":{"type":"string"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"description":{"type":"string"},"homepage_url":{"type":"string"},"logo_dark_url":{"type":"string"},"logo_url":{"type":"string"},"name":{"type":"string"},"owner_email":{"description":"Used to create the owner when owner_id doesn't exist yet.","type":"string"},"owner_id":{"description":"The owning Carbon's c:id.","type":"string"},"owner_uuid":{"description":"The owning Carbon's uuid (preferred: it never changes).","type":"string"},"secret":{"description":"`sa_app_...`: required to create an app; a different one rotates it.","type":"string"},"signin_defaults":{"additionalProperties":true,"description":"A partial sign-in config applied when the app is new.","type":"object"},"status":{"enum":["active","disabled"],"type":"string"},"webhook_secret":{"description":"Test kit extra.","type":"string"},"webhook_url":{"description":"Test kit extra.","type":"string"}},"required":["app_id","name"],"type":"object"},"SiliconCreate":{"additionalProperties":false,"description":"Unknown fields are refused.","properties":{"display_name":{"description":"1 to 100 characters.","type":"string"},"id":{"description":"A free si: id (a bare handle gets the prefix).","type":"string"},"pfp_url":{"description":"An https URL; the default photo otherwise.","type":"string"},"stk":{"$ref":"#/components/schemas/Stk","description":"A self-chosen STK; one is generated when absent."},"timezone":{"description":"IANA; defaults to the caller's network timezone, else UTC.","type":"string"},"webhook_url":{"description":"Where to tell the Silicon about its account (https, public address).","type":"string"}},"required":["id","display_name"],"type":"object"},"SiliconCreated":{"properties":{"silicon":{"$ref":"#/components/schemas/SiliconView"},"stk":{"description":"Shown once; null when you chose one.","type":["string","null"]},"webhook_secret":{"description":"Shown once; null without a webhook_url.","type":["string","null"]}},"required":["silicon","stk","webhook_secret"],"type":"object"},"SiliconKey":{"properties":{"algorithm":{"enum":["EdDSA"],"type":"string"},"created_at":{"format":"date-time","type":"string"},"created_by":{"description":"The uuid of the Silicon or the custodian who added it.","type":"string"},"fingerprint":{"description":"`SHA256:...`, as `ssh-keygen -l` prints it.","type":"string"},"id":{"description":"The key id (`kid` in assertions).","format":"uuid","type":"string"},"last_used_at":{"format":"date-time","type":["string","null"]},"name":{"type":"string"},"public_key":{"description":"The 32-byte Ed25519 public key, base64url.","type":"string"},"revoked_at":{"format":"date-time","type":["string","null"]}},"required":["id","name","algorithm","public_key","fingerprint","created_by","created_at","last_used_at","revoked_at"],"type":"object"},"SiliconKeyAdd":{"additionalProperties":false,"properties":{"name":{"description":"At most 100 characters; `key` when left out.","type":"string"},"public_key":{"description":"An OpenSSH line (`ssh-ed25519 AAAA...`), a PEM PUBLIC KEY, or the 32 raw bytes in base64url.","type":"string"}},"required":["public_key"],"type":"object"},"SiliconLogin":{"additionalProperties":false,"description":"Either `id` and `stk`, or `assertion`.","properties":{"assertion":{"description":"Instead of `id` and `stk`: a JWT signed with one of the Silicon's registered keys (header alg EdDSA, kid optional; iss = sub = the si:id or uuid; aud = the token endpoint; exp at most 300 seconds after iat; a new jti).","type":"string"},"client_label":{"description":"At most 100 characters; names the sign-in in the custodian's sessions list.","type":"string"},"id":{"description":"The Silicon's current si:id (with `stk`).","type":"string"},"stk":{"$ref":"#/components/schemas/Stk"}},"type":"object"},"SiliconPhotoUpload":{"properties":{"pfp_url":{"format":"uri","type":"string"},"photo":{"$ref":"#/components/schemas/PhotoInfo"},"silicon":{"$ref":"#/components/schemas/SiliconView"}},"required":["pfp_url","photo","silicon"],"type":"object"},"SiliconRequestStatus":{"properties":{"created_at":{"format":"date-time","type":"string"},"custodian":{"type":"string"},"decided_at":{"format":"date-time","type":["string","null"]},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"kind":{"enum":["initial"],"type":"string"},"silicon":{"properties":{"id":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/AccountStatus"},"uuid":{"$ref":"#/components/schemas/AccountUuid"}},"required":["uuid","id","status"],"type":"object"},"status":{"enum":["pending","accepted","declined","expired","cancelled"],"type":"string"}},"required":["id","kind","status","custodian","created_at","expires_at","decided_at","silicon"],"type":"object"},"SiliconSelfCreate":{"additionalProperties":false,"description":"Unknown fields are refused.","properties":{"custodian":{"description":"The Carbon's c:id, or an email address (which may not have an account yet).","type":"string"},"display_name":{"description":"1 to 100 characters.","type":"string"},"id":{"description":"A free si: id (a bare handle gets the prefix).","type":"string"},"pfp_url":{"description":"An https URL; the default photo otherwise.","type":"string"},"stk":{"$ref":"#/components/schemas/Stk","description":"A self-chosen STK; one is generated when absent."},"timezone":{"description":"IANA; defaults to the caller's network timezone, else UTC.","type":"string"},"webhook_url":{"description":"Where to tell the Silicon about its account (https, public address).","type":"string"}},"required":["id","display_name","custodian"],"type":"object"},"SiliconSelfCreated":{"properties":{"request":{"$ref":"#/components/schemas/InitialRequest"},"request_token":{"description":"`sarq_...`: shown once; reads the request's decision and opens the event stream while you wait.","type":"string"},"silicon":{"$ref":"#/components/schemas/MeSilicon"},"stk":{"description":"Shown once; null when you chose one.","type":["string","null"]},"webhook_secret":{"description":"`whsec_...`: shown once; null without a webhook_url.","type":["string","null"]}},"required":["silicon","stk","request","request_token","webhook_secret"],"type":"object"},"SiliconSignin":{"properties":{"app":{"properties":{"app_id":{"type":"string"},"name":{"type":["string","null"]}},"required":["app_id"],"type":["object","null"]},"at":{"format":"date-time","type":"string"},"ip":{"type":["string","null"]},"method":{"description":"`silicon_stk`, `silicon_key`, `slt`, `slt_public_client`, `device`, ...","type":"string"},"outcome":{"enum":["success","failed"],"type":"string"},"user_agent":{"type":["string","null"]}},"required":["at","app","method","outcome"],"type":"object"},"SiliconUpdate":{"additionalProperties":false,"description":"A Silicon's dob can't change and its id changes through `/id`.","properties":{"display_name":{"type":"string"},"pfp_url":{"description":"null = the default photo.","type":["string","null"]},"timezone":{"type":"string"}},"type":"object"},"SiliconView":{"allOf":[{"$ref":"#/components/schemas/MeSilicon"},{"properties":{"pending_transfer":{"oneOf":[{"$ref":"#/components/schemas/CustodianRequest"},{"type":"null"}]}},"required":["pending_transfer"],"type":"object"}],"description":"A Silicon as its custodian sees it."},"SiliconWebhookSecret":{"properties":{"webhook_secret":{"description":"`whsec_...`: a new signing secret every time, shown once.","type":"string"},"webhook_url":{"format":"uri","type":"string"}},"required":["webhook_url","webhook_secret"],"type":"object"},"SiliconWebhookTest":{"properties":{"delivery_id":{"format":"uuid","type":"string"},"event_id":{"format":"uuid","type":"string"},"superseded_pings":{"description":"Older test pings this one replaced (only the newest is retried).","type":"integer"},"type":{"enum":["ping"],"type":"string"},"url":{"format":"uri","type":"string"}},"required":["event_id","delivery_id","type","url","superseded_pings"],"type":"object"},"Stk":{"description":"A Silicon's password: `stk-` + 8 to 32 hex characters (the bare hex gets the prefix; case is ignored). Generated ones are `stk-` + 12 hex characters.","examples":["stk-2925d1f735d0"],"pattern":"^(stk-)?[0-9a-fA-F]{8,32}$","type":"string"},"StkRotate":{"additionalProperties":false,"properties":{"stk":{"$ref":"#/components/schemas/Stk","description":"Your own STK; omit it to generate one."}},"type":"object"},"StkRotation":{"properties":{"revoked_sessions":{"description":"How many sign-ins of the Silicon ended.","type":"integer"},"rotated_at":{"format":"date-time","type":"string"},"stk":{"description":"The new STK, shown once; null when you set it yourself.","type":["string","null"]}},"required":["stk","rotated_at","revoked_sessions"],"type":"object"},"Subscription":{"description":"Where an app's updates go (a webhook URL, or the event stream), which updates it wants, and whether it is active or paused. At most one webhook subscription and one stream subscription per app.","properties":{"app_id":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"delivery":{"enum":["webhook","stream"],"type":"string"},"event_types":{"description":"The event types this subscription receives.","items":{"type":"string"},"type":"array"},"id":{"format":"uuid","type":"string"},"secret_set":{"description":"Whether a signing secret is stored (webhooks).","type":"boolean"},"status":{"enum":["active","paused"],"type":"string"},"stream_url":{"description":"For a stream subscription: the GET /v1/events/stream URL.","format":"uri","type":["string","null"]},"updated_at":{"format":"date-time","type":"string"},"updates":{"description":"The updates this subscription wants; null = every update (the setting of webhooks set up before subscriptions existed).","items":{"$ref":"#/components/schemas/UpdateName"},"type":["array","null"]},"url":{"description":"The webhook URL; null for a stream.","format":"uri","type":["string","null"]}},"required":["id","app_id","delivery","status","url","updates","event_types","created_at","updated_at"],"type":"object"},"SubscriptionCreate":{"additionalProperties":false,"allOf":[{"if":{"properties":{"delivery":{"const":"webhook"}}},"then":{"properties":{"url":{"format":"uri","type":"string"}},"required":["url"]}},{"if":{"properties":{"delivery":{"const":"stream"}}},"then":{"properties":{"url":false}}}],"properties":{"delivery":{"enum":["webhook","stream"],"type":"string"},"status":{"description":"Default active.","enum":["active","paused"],"type":"string"},"updates":{"description":"Omitted = id_change, display_name_change, pfp_change, access_removed, account_deleted. null = every update.","items":{"$ref":"#/components/schemas/UpdateName"},"type":["array","null"]},"url":{"description":"Required for a webhook, refused for a stream.","format":"uri","type":"string"}},"required":["delivery"],"type":"object"},"SubscriptionCreated":{"allOf":[{"$ref":"#/components/schemas/Subscription"},{"properties":{"secret":{"description":"`whsec_...`: only for a new webhook subscription, shown once.","type":"string"}},"type":"object"}]},"SubscriptionTest":{"properties":{"delivery_id":{"description":"null for a stream subscription.","format":"uuid","type":["string","null"]},"event_id":{"format":"uuid","type":"string"},"subscription_id":{"format":"uuid","type":"string"},"type":{"enum":["ping"],"type":"string"}},"required":["subscription_id","event_id","delivery_id","type"],"type":"object"},"SubscriptionUpdate":{"additionalProperties":false,"description":"At least one field. Unknown fields are refused.","minProperties":1,"properties":{"status":{"enum":["active","paused"],"type":"string"},"updates":{"description":"null = every update.","items":{"$ref":"#/components/schemas/UpdateName"},"type":["array","null"]},"url":{"description":"Webhook subscriptions only; the signing secret stays.","format":"uri","type":"string"}},"type":"object"},"TelemetryAccepted":{"properties":{"accepted":{"type":"integer"},"forwarded":{"type":"boolean"}},"required":["accepted","forwarded"],"type":"object"},"TelemetryBatch":{"properties":{"events":{"items":{"properties":{"data":{"additionalProperties":true,"description":"At most 8 KB; never secrets. Only the known fields listed on the operation are forwarded, each only in its shape or as one of its words; the rest is dropped.","type":"object"},"name":{"description":"Only `cli.command` and `cli.step` are forwarded.","pattern":"^[a-z0-9_.]{1,64}$","type":"string"},"progress":{"maximum":1,"minimum":0,"type":"number"},"source":{"description":"1 to 64 characters of a-z 0-9 _ . -. Only `cli` is forwarded.","type":"string"},"step":{"description":"1 to 200 printable characters. Forwarded only as one of the CLI's step names (`login.device.approved`) or command paths (`app webhook set`); anything else is forwarded as `other`.","type":"string"}},"required":["source","step","name"],"type":"object"},"maxItems":50,"type":"array"}},"required":["events"],"type":"object"},"TokenExchangeResponse":{"description":"The answer to a token exchange (RFC 8693): the usual token response plus `issued_token_type`. The sign-in ends when the outside token expires, at least 30 minutes (one access token) and at most 12 hours after the exchange; its refresh tokens rotate as usual until then.","properties":{"access_token":{"description":"A first-party EdDSA JWT (`aud: silicon-accounts`).","type":"string"},"account":{"$ref":"#/components/schemas/AccountForApp"},"expires_in":{"description":"1800 seconds, or fewer when the sign-in ends sooner: an access token never outlives its sign-in.","type":"integer"},"issued_token_type":{"enum":["urn:ietf:params:oauth:token-type:access_token"],"type":"string"},"membership_id":{"type":"string"},"refresh_token":{"description":"`sar_...`; rotates on every refresh, and stops working when the sign-in ends.","type":"string"},"refresh_token_expires_at":{"description":"When the sign-in ends: when the outside token expires, at least 30 minutes and at most 12 hours from now.","format":"date-time","type":"string"},"scope":{"type":"string"},"token_type":{"enum":["Bearer"],"type":"string"}},"required":["access_token","issued_token_type","token_type","expires_in","refresh_token","refresh_token_expires_at","scope","membership_id","account"],"type":"object"},"TokenRequest":{"description":"Unknown parameters are ignored (RFC 6749); a repeated one is refused.","properties":{"assertion":{"description":"jwt-bearer: a JWT signed with one of the Silicon's registered keys (with `client_id=silicon-accounts`).","type":"string"},"client_id":{"description":"With `client_secret` instead of HTTP Basic. Alone, it is a public client: `silicon-accounts` (the CLI), `developer`, or an app that turned on `device_flow` or `public_client` (with `public_client`, also to redeem a short-lived token).","type":"string"},"client_secret":{"type":"string"},"code":{"description":"authorization_code: the `sac_...` code from your redirect URI (120 seconds, single use).","type":"string"},"code_verifier":{"description":"authorization_code: the PKCE verifier (43 to 128 characters).","type":"string"},"device_code":{"description":"device_code: the `sad_...` code from `POST /v1/device/authorize`.","type":"string"},"grant_type":{"description":"`authorization_code`, `refresh_token`, `urn:silicon:params:oauth:grant-type:slt` (alias `slt`), `urn:ietf:params:oauth:grant-type:device_code` (alias `device_code`), `urn:ietf:params:oauth:grant-type:jwt-bearer` or `urn:ietf:params:oauth:grant-type:token-exchange`.","type":"string"},"redirect_uri":{"description":"authorization_code: exactly the `redirect_uri` sent to `/authorize`.","type":"string"},"refresh_token":{"description":"refresh_token: the newest `sar_...` token.","type":"string"},"requested_token_type":{"description":"token-exchange: optional; only an access token is ever issued.","enum":["urn:ietf:params:oauth:token-type:access_token"],"type":"string"},"scope":{"description":"refresh_token: optional; may only repeat or narrow the granted scopes.","type":"string"},"silicon":{"description":"token-exchange: the si:id or uuid of the Silicon to sign in.","type":"string"},"slt":{"description":"slt: the Silicon's `slt_...` short-lived token. Apps send their secret, or `client_id` alone with `public_client` on.","type":"string"},"subject_token":{"description":"token-exchange: the outside OIDC token a CI job got (a JWT), from an issuer the Silicon trusts.","type":"string"},"subject_token_type":{"description":"token-exchange: the kind of `subject_token`.","enum":["urn:ietf:params:oauth:token-type:jwt","urn:ietf:params:oauth:token-type:id_token"],"type":"string"}},"required":["grant_type"],"type":"object"},"TokenResponse":{"properties":{"access_token":{"description":"An EdDSA (Ed25519) JWT.","type":"string"},"account":{"$ref":"#/components/schemas/AccountForApp"},"expires_in":{"description":"1800 seconds, or fewer when the sign-in ends sooner: an access token never outlives its sign-in.","type":"integer"},"id_token":{"description":"Only when `openid` was granted.","type":"string"},"membership_id":{"type":"string"},"refresh_token":{"description":"`sar_...`; rotates on every refresh. Store the new one before using it.","type":"string"},"refresh_token_expires_at":{"description":"When the sign-in ends at the latest: 900 days after it started, or sooner for an app sign-in made from a short-lived token that a Silicon's CI sign-in minted (it ends with that CI sign-in).","format":"date-time","type":"string"},"scope":{"description":"The granted scopes, space-separated.","type":"string"},"token_type":{"enum":["Bearer"],"type":"string"}},"required":["access_token","token_type","expires_in","refresh_token","refresh_token_expires_at","scope","membership_id","account"],"type":"object"},"TransferRequest":{"additionalProperties":false,"properties":{"to":{"description":"The Carbon's c:id or an email address.","type":"string"}},"required":["to"],"type":"object"},"UpdateName":{"description":"An account update an app can choose to hear about.","enum":["id_change","display_name_change","pfp_change","timezone_change","email_change","phone_change","custodian_change","access_removed","account_deleted"],"type":"string"},"UserInfo":{"allOf":[{"$ref":"#/components/schemas/AccountForApp"},{"properties":{"birthdate":{"type":"string"},"name":{"type":"string"},"phone_number":{"type":"string"},"phone_number_verified":{"type":"boolean"},"picture":{"type":"string"},"sub":{"type":"string"},"zoneinfo":{"type":"string"}},"required":["sub"],"type":"object"}],"description":"The account as the token's app may see it, plus the OIDC claim names."},"UserVerificationRequest":{"additionalProperties":false,"description":"Unknown fields are refused.","properties":{"access_ttl_seconds":{"description":"The proof token's lifetime in seconds (default 1800).","maximum":1800,"minimum":60,"type":"integer"},"receiving_app":{"type":"string"},"scopes":{"description":"App-defined strings, at most 20.","items":{"pattern":"^[A-Za-z0-9_.:/-]{1,100}$","type":"string"},"maxItems":20,"type":"array"},"subject_token":{"description":"An access token your app received for the account (its `aud` is your app).","type":"string"}},"required":["subject_token","receiving_app"],"type":"object"},"VerificationEvent":{"description":"No raw proof or refresh token values are ever returned.","properties":{"action":{"enum":["proof.issued","proof.refreshed","proof.revoked","proof.refresh_token_reused"],"type":"string"},"actor":{"properties":{"id":{"type":["string","null"]},"kind":{"type":"string"}},"required":["kind","id"],"type":"object"},"at":{"format":"date-time","type":"string"},"details":{"additionalProperties":true,"type":"object"},"event_id":{"type":"string"},"token_expires_at":{"format":"date-time","type":["string","null"]},"token_expiry_source":{"description":"Whether token_expires_at was recorded at the time or derived from the lifetime.","enum":["recorded","derived",null],"type":["string","null"]}},"required":["event_id","at","action","actor","details","token_expires_at","token_expiry_source"],"type":"object"},"WebhookAttempt":{"properties":{"attempted_at":{"format":"date-time","type":"string"},"duration_ms":{"type":"integer"},"error":{"type":["string","null"]},"status_code":{"type":["integer","null"]}},"required":["attempted_at","status_code","error","duration_ms"],"type":"object"},"WebhookDelivery":{"properties":{"account_uuid":{"type":["string","null"]},"attempts":{"description":"Attempts since the delivery was created or last replayed.","type":"integer"},"created_at":{"format":"date-time","type":"string"},"delivered_at":{"format":"date-time","type":["string","null"]},"event_id":{"format":"uuid","type":"string"},"id":{"format":"uuid","type":"string"},"last_attempt_at":{"format":"date-time","type":["string","null"]},"last_error":{"type":["string","null"]},"last_status":{"description":"The HTTP status of the last attempt.","type":["integer","null"]},"manual_replays":{"type":"integer"},"next_attempt_at":{"description":"Set only while pending.","format":"date-time","type":["string","null"]},"status":{"enum":["pending","delivered","failed"],"type":"string"},"type":{"type":"string"},"url":{"type":["string","null"]}},"required":["id","event_id","type","status","attempts","created_at"],"type":"object"},"WebhookDeliveryDetail":{"properties":{"account_uuid":{"type":["string","null"]},"attempt_count":{"type":"integer"},"attempts":{"description":"Every attempt, before and after replays.","items":{"$ref":"#/components/schemas/WebhookAttempt"},"type":"array"},"created_at":{"format":"date-time","type":"string"},"delivered_at":{"format":"date-time","type":["string","null"]},"event_id":{"format":"uuid","type":"string"},"id":{"format":"uuid","type":"string"},"last_attempt_at":{"format":"date-time","type":["string","null"]},"last_error":{"type":["string","null"]},"last_status":{"description":"The HTTP status of the last attempt.","type":["integer","null"]},"manual_replays":{"type":"integer"},"next_attempt_at":{"description":"Set only while pending.","format":"date-time","type":["string","null"]},"payload":{"$ref":"#/components/schemas/WebhookEvent","description":"The exact body that was signed."},"payload_redacted":{"description":"True when the account no longer shares its data with the app: `payload.data` is cut down to `{uuid, membership_id}`.","type":"boolean"},"payload_redacted_reason":{"type":["string","null"]},"status":{"enum":["pending","delivered","failed"],"type":"string"},"type":{"type":"string"},"url":{"type":["string","null"]}},"required":["id","event_id","type","status","attempts","attempt_count","payload","payload_redacted","created_at"],"type":"object"},"WebhookEvent":{"description":"The body of a webhook delivery, and the `data` of an event stream frame.","properties":{"app_id":{"description":"The receiving app (app events), else null.","type":["string","null"]},"data":{"additionalProperties":true,"description":"The event's data.","type":"object"},"event_id":{"description":"The same on every retry and replay: dedupe on it.","format":"uuid","type":"string"},"occurred_at":{"format":"date-time","type":"string"},"silicon":{"description":"The Silicon's uuid (Silicon events), else null.","type":["string","null"]},"type":{"description":"The event type. New types may be added: ignore the ones you don't know.","type":"string"}},"required":["event_id","type","occurred_at","app_id","silicon","data"],"type":"object"},"WebhookSecret":{"properties":{"secret":{"description":"`whsec_...`: shown once.","type":"string"}},"required":["secret"],"type":"object"},"WebhookUrl":{"additionalProperties":false,"properties":{"url":{"description":"https, reaching a public address (at most 2048 characters).","format":"uri","type":"string"}},"required":["url"],"type":"object"}},"securitySchemes":{"appAccessToken":{"bearerFormat":"JWT","description":"An access token issued to an app (any audience, first-party tokens included). Used by /v1/userinfo.","scheme":"bearer","type":"http"},"appBasic":{"description":"An app's own credentials: `Authorization: Basic base64(app_id:app_secret)`.","scheme":"basic","type":"http"},"bearerAuth":{"bearerFormat":"JWT","description":"A first-party access token (`aud: silicon-accounts`), valid 30 minutes. A Silicon gets one from `POST /v1/silicons/login` with its si:id and STK (the STK is its password, sent in that body); a Carbon from `POST /v1/cli/login/verify`, the device flow, or the account site. Renew with `grant_type=refresh_token` and `client_id=silicon-accounts`. Tokens issued to apps are refused here (401 `token_wrong_audience`).","scheme":"bearer","type":"http"},"flowCookie":{"description":"Binds a hosted sign-in flow to the browser that started it (`sa_flow` on http local stacks), 60 minutes. Set by `POST /v1/flows`. Flow POSTs also need an `Origin` equal to the public origin.","in":"cookie","name":"__Host-sa_flow","type":"apiKey"},"internalToken":{"description":"`ACCOUNTS_INTERNAL_TOKEN`: Silicon Apps only.","scheme":"bearer","type":"http"},"oauthClient":{"description":"OAuth client authentication: HTTP Basic, or `client_id` + `client_secret` form fields (never both). The public first-party clients send `client_id=silicon-accounts` (the CLI) or `client_id=developer` alone.","scheme":"basic","type":"http"},"requestToken":{"description":"The `sarq_...` token a self-created Silicon got from `POST /v1/silicons`, for `GET /v1/silicons/requests/{id}` and `GET /v1/events/stream` while it waits for its custodian.","scheme":"bearer","type":"http"},"sessionCookie":{"description":"The account site's browser session (`sa_session` on http local stacks), 900 days. Cookie-authenticated writes (POST, PUT, PATCH, DELETE) need an `Origin` equal to the public origin, or 403 `origin_not_allowed`. Scripts, Silicons and servers should use bearer tokens.","in":"cookie","name":"__Host-sa_session","type":"apiKey"},"signupCookie":{"description":"A 48-hour sign-up session (`sa_signup` on http local stacks), set when a new address verifies its code.","in":"cookie","name":"__Host-sa_signup","type":"apiKey"}}},"externalDocs":{"description":"Silicon Accounts documentation","url":"https://developers.teamofsilicons.com/docs/accounts"},"info":{"contact":{"name":"Team of Silicons","url":"https://teamofsilicons.com"},"description":"Silicon Accounts gives every Carbon (a person) and every Silicon (an agent) one account. Apps use it to sign them in, to prove who is acting for whom (App verification and User verification proofs), and to hear about changes through webhooks or an event stream.\n\n**Start here.** `GET /v1/capabilities` says what this server supports (send `?require=sse,subscriptions` to check a list at once); `GET /v1/meta` says which deployment answered.\n\n**Versions.** Every response carries `Accounts-Version`, the API version that served it (today `2026-10-01`). Send the same header to pin a version; an unknown one is 400 `unsupported_version`.\n\n**Request ids.** Every response carries `X-Request-Id`. Send your own (1 to 128 characters of `A-Z a-z 0-9 - _ . :`) or let the server make one, and quote it when you report a problem.\n\n**Errors.** One shape everywhere: `{\"error\": {\"code\", \"message\", \"hint\", \"details\"}}`. Branch on `code`, never on the message. The three OAuth endpoints (`/v1/oauth/token`, `/v1/oauth/revoke`, `/v1/oauth/introspect`) answer RFC 6749 bodies instead: `{\"error\", \"error_description\"}`.\n\n**Limits.** Over a rate limit the answer is 429 `rate_limited`; too many wrong codes or STKs lock with 423. Both carry `Retry-After` (seconds) and `details.retry_after_seconds`: wait that long.\n\n**Lists** are `{\"items\": [...], \"next_cursor\": \"...\" | null}`; pass `next_cursor` back as `cursor`. **Writes** that take an `Idempotency-Key` replay their first answer on a retry, with `Idempotent-Replayed: true`.\n\nTimestamps are RFC 3339 in UTC with milliseconds. Every `/v1` response is `Cache-Control: no-store` unless an operation says otherwise.","license":{"identifier":"MIT","name":"MIT"},"title":"Silicon Accounts API","version":"0.3.0"},"openapi":"3.1.0","paths":{"/.well-known/agent.json":{"get":{"description":"An A2A agent card: what Silicon Accounts does, its skills and how to authenticate, for agents that discover services by card.","operationId":"getAgentCard","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCard"}}},"description":"The agent card.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Agent card","tags":["Discovery"]}},"/.well-known/jwks.json":{"get":{"description":"The public keys that sign access tokens and id_tokens. CORS `*`, cacheable for 5 minutes. Fetch again when a token names a `kid` you don't have.","operationId":"getJwks","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Jwks"}}},"description":"The keys.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`public, max-age=300`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Signing keys (JWKS)","tags":["OAuth and OIDC"]}},"/.well-known/openid-configuration":{"get":{"description":"The discovery document OIDC libraries read. CORS `*`, cacheable for 5 minutes.","operationId":"getOpenIdConfiguration","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenIdConfiguration"}}},"description":"The discovery document.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`public, max-age=300`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"OpenID Connect discovery","tags":["OAuth and OIDC"]}},"/embed/v1/buttons":{"get":{"description":"The page apps put in an iframe. Its CSP carries `frame-ancestors 'self'` plus the app's `allowed_origins` (`'none'` for an unknown app). Served by the account site; the API serves it only in the legacy static-hosting setup, else 404 `route_not_found`.","operationId":"getEmbedButtons","parameters":[{"description":"The app whose buttons to show.","in":"query","name":"app_id","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"text/html":{"schema":{"type":"string"}}},"description":"The page.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"content":{"application/json":{"example":{"error":{"code":"route_not_found","message":"There is no endpoint GET /v1/nope in Silicon Accounts."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `route_not_found`: no endpoint has this path","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["route_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"content":{"application/json":{"example":{"error":{"code":"web_not_built","message":"(static hosting only) the account site build is incomplete."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Service unavailable.\n\n- `web_not_built`: (static hosting only) the account site build is incomplete\n- `database_unavailable`: the database is unreachable; nothing was changed; retry in a few seconds\n- `request_timeout`: the request ran past its time budget (30 s, 60 s for uploads, 5 min for imports)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["web_not_built","database_unavailable","request_timeout"]}},"security":[],"summary":"The sign-in buttons iframe","tags":["Service"]}},"/healthz":{"get":{"description":"On accounts-api's own address only (locally http://127.0.0.1:8589); the public origin answers its HTML 404 page. Checks nothing but the process.","operationId":"healthz","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"text/plain":{"example":"ok","schema":{"const":"ok","type":"string"}}},"description":"Alive.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"}},"security":[],"summary":"Liveness","tags":["Service"]}},"/openapi.json":{"get":{"description":"The OpenAPI 3.1 description of the whole API, served verbatim. Cacheable for 5 minutes.","operationId":"getOpenApiDocument","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"The OpenAPI document.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`public, max-age=300`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"This OpenAPI document","tags":["Discovery"]}},"/readyz":{"get":{"description":"On accounts-api's own address only. Ready when Postgres answers.","operationId":"readyz","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"example":{"database":"ok"},"schema":{"$ref":"#/components/schemas/Readiness"}}},"description":"Ready.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Readiness"}}},"description":"Not ready: the database is unreachable.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}}},"security":[],"summary":"Readiness","tags":["Service"]}},"/sdk/v1.js":{"get":{"description":"CORS `*`, cacheable for 5 minutes. Served by the account site; the API serves it only in the legacy static-hosting setup, else 404 `route_not_found`.","operationId":"getSdk","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/javascript":{"schema":{"type":"string"}}},"description":"The script.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`public, max-age=300`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"content":{"application/json":{"example":{"error":{"code":"route_not_found","message":"There is no endpoint GET /v1/nope in Silicon Accounts."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `route_not_found`: no endpoint has this path","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["route_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"content":{"application/json":{"example":{"error":{"code":"web_not_built","message":"(static hosting only) the account site build is incomplete."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Service unavailable.\n\n- `web_not_built`: (static hosting only) the account site build is incomplete\n- `database_unavailable`: the database is unreachable; nothing was changed; retry in a few seconds\n- `request_timeout`: the request ran past its time budget (30 s, 60 s for uploads, 5 min for imports)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["web_not_built","database_unavailable","request_timeout"]}},"security":[],"summary":"The JavaScript SDK","tags":["Service"]}},"/v1/accounts/by-id/{id}":{"get":{"description":"The current public identity of an account. Both lookup routes together allow 600 lookups per minute per app or account. Matches current ids only.","operationId":"getAccountById","parameters":[{"description":"The account's current c:id or si:id (`:` may be sent as is).","in":"path","name":"id","required":true,"schema":{"$ref":"#/components/schemas/AccountId"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSummary"}}},"description":"The account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_id","message":"Not a valid c:/si: id, or the wrong kind; details.reason is invalid or reserved_word."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_id","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"content":{"application/json":{"example":{"error":{"code":"account_not_found","message":"No account with this uuid or current id; at CLI sign-in, no active Carbon with that email or phone (sign up first)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `account_not_found`: no account with this uuid or current id; at CLI sign-in, no active Carbon with that email or phone (sign up first)\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["account_not_found","account_deleted"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Look up an account by c:id or si:id","tags":["Accounts"]}},"/v1/accounts/{uuid}":{"get":{"description":"The current public identity of an account. Both lookup routes together allow 600 lookups per minute per app or account.","operationId":"getAccount","parameters":[{"description":"The account's uuid (case-sensitive). To look up a c:id or si:id, use /v1/accounts/by-id/{id}.","in":"path","name":"uuid","required":true,"schema":{"$ref":"#/components/schemas/AccountUuid"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSummary"}}},"description":"The account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_uuid","message":"Not a uuid (an id was given: use /v1/accounts/by-id/{id})."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_uuid`: not a uuid (an id was given: use `/v1/accounts/by-id/{id}`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_uuid","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"content":{"application/json":{"example":{"error":{"code":"account_not_found","message":"No account with this uuid or current id; at CLI sign-in, no active Carbon with that email or phone (sign up first)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `account_not_found`: no account with this uuid or current id; at CLI sign-in, no active Carbon with that email or phone (sign up first)\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["account_not_found","account_deleted"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Look up an account by uuid","tags":["Accounts"]}},"/v1/apps/{app_id}":{"get":{"description":"The app, its sign-in setup, webhook and statistics. Secrets are never returned.","operationId":"getApp","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/App"}}},"description":"The app.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The app, its sign-in setup and statistics","tags":["Apps"]}},"/v1/apps/{app_id}/account-verification-request":{"get":{"description":"For an account that currently manages the app (an Accounts session, or a token issued to silicon-accounts or the developer platform). App credentials can't read it. The request belongs to the account, so one submitted from another managed app can appear here.","operationId":"getAccountVerificationRequest","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountVerificationState"}}},"description":"The latest request, or null.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"account_not_active","message":"The account isn't active (pending custodian, unfinished import)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `not_app_owner`: an account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["account_not_active","not_app_owner"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_app","message":"No app has this app_id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your latest manual account verification request","tags":["Apps"]},"post":{"description":"Starts a manual review of the account's eligibility to run app authorization on its own domain; a reply can take up to 48 hours. At most one pending request per account: a repeat answers 200 with the original request. 201 means the request and its notifications were saved, not that the emails arrived.","operationId":"submitAccountVerificationRequest","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountVerificationSubmit"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountVerificationSubmitted"}}},"description":"A pending request already existed; it is returned unchanged.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountVerificationSubmitted"}}},"description":"Submitted.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"account_not_active","message":"The account isn't active (pending custodian, unfinished import)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `not_app_owner`: an account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["account_not_active","not_app_owner","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_app","message":"No app has this app_id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_app"]},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Ask for manual account verification","tags":["Apps"]}},"/v1/apps/{app_id}/imports":{"get":{"description":"Newest first.","operationId":"listImports","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/ImportJob"},"type":"array"}},"type":"object"}]}}},"description":"Jobs.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The app's import jobs","tags":["Apps"]},"post":{"description":"CSV (`text/csv` or `application/csv`, options as query parameters) or JSON `{rows, options}`. At most 100,000 rows and 50 MB; 60 imports per app per hour; 2,000,000 rows per app per 24 hours. Rows are processed in the background.","operationId":"createImport","parameters":[{"$ref":"#/components/parameters/AppId"},{"description":"CSV only: ISO code for local phone numbers.","in":"query","name":"default_country","required":false,"schema":{"type":"string"}},{"description":"CSV only.","in":"query","name":"ignore_unknown_columns","required":false,"schema":{"type":"boolean"}},{"description":"CSV only: decide everything, write nothing.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"CSV only.","in":"query","name":"update_existing","required":false,"schema":{"type":"boolean"}},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/csv":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/ImportRequest"}},"text/csv":{"schema":{"type":"string"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobEnvelope"}}},"description":"Queued.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_content_type","message":"A body was sent without Content-Type: application/json (or, for imports, text/csv)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `invalid_query`: a query parameter is missing, has the wrong type or an unknown value (named)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_content_type","invalid_query","invalid_json","unsupported_version","invalid_idempotency_key"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"unknown_columns","message":"The import has columns Silicon Accounts doesn't keep (details.unknown_columns, allowed_columns); remove them or set ignore_unknown_columns."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `unknown_columns`: the import has columns Silicon Accounts doesn't keep (`details.unknown_columns`, `allowed_columns`); remove them or set `ignore_unknown_columns`\n- `duplicate_columns`: the same column twice\n- `no_identifier_columns`: no `email`, `emails`, `phone` or `phones` column\n- `empty_import`: no rows\n- `too_many_rows`: over 100,000 rows\n- `invalid_csv`: the CSV can't be parsed (line given)\n- `too_many_columns`: over 200 columns\n- `value_too_large`: a value over 8 KB, or a column name over 200 bytes (`details.row`, `details.column`)\n- `too_many_items`: a JSON list over 50 items\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_columns","duplicate_columns","no_identifier_columns","empty_import","too_many_rows","invalid_csv","too_many_columns","value_too_large","too_many_items","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"content":{"application/json":{"example":{"error":{"code":"imports_busy","details":{"retry_after_seconds":15},"message":"The server is already parsing its maximum of imports; retry after Retry-After (15 s)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Service unavailable.\n\n- `imports_busy`: the server is already parsing its maximum of imports; retry after `Retry-After` (15 s)\n- `database_unavailable`: the database is unreachable; nothing was changed; retry in a few seconds\n- `request_timeout`: the request ran past its time budget (30 s, 60 s for uploads, 5 min for imports)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["imports_busy","database_unavailable","request_timeout"]}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Import existing users","tags":["Apps"]}},"/v1/apps/{app_id}/imports/{job_id}":{"get":{"description":"Its status (queued, running, completed or failed) and row counts.","operationId":"getImport","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/JobId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportJobEnvelope"}}},"description":"The job.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"import_not_found","message":"No such import job for this app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `import_not_found`: no such import job for this app\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["import_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One import job","tags":["Apps"]}},"/v1/apps/{app_id}/imports/{job_id}/rows":{"get":{"description":"In file order. A dry run never names a matched account.","operationId":"listImportRows","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/JobId"},{"description":"Only this outcome.","in":"query","name":"outcome","required":false,"schema":{"enum":["pending","created","matched","updated","skipped","error"],"type":"string"}},{"description":"Rows with a message of this level.","in":"query","name":"level","required":false,"schema":{"enum":["error","warning","info"],"type":"string"}},{"description":"Rows with this message code, like missing_identifier.","in":"query","name":"code","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/ImportRow"},"type":"array"}},"type":"object"}]}}},"description":"Rows.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"import_not_found","message":"No such import job for this app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `import_not_found`: no such import job for this app\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["import_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Every row's outcome","tags":["Apps"]}},"/v1/apps/{app_id}/proofs":{"get":{"description":"Newest first. A User verification proof whose sign-in ended shows revoked.","operationId":"listAppProofs","parameters":[{"$ref":"#/components/parameters/AppId"},{"description":"Only this kind.","in":"query","name":"kind","required":false,"schema":{"enum":["user_verification","app_verification"],"type":"string"}},{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["active","revoked","expired"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/AppProof"},"type":"array"}},"type":"object"}]}}},"description":"Proofs.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Proofs the app issued","tags":["Proofs"]}},"/v1/apps/{app_id}/proofs/app-verification":{"post":{"description":"The same as `POST /v1/proofs/app-verification`, also for the app's authors without the app secret.","operationId":"issueAppVerificationForApp","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppVerificationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedProof"}}},"description":"The proof.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"unknown_receiving_app","message":"The receiving app doesn't exist (details.app_ids)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `unknown_receiving_app`: the receiving app doesn't exist (`details.app_ids`)\n- `invalid_receiving_app`: the issuer itself, or Silicon Accounts itself (`silicon-accounts`, `developer`)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_receiving_app","invalid_receiving_app","invalid_json","invalid_content_type","unsupported_version","invalid_idempotency_key"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"receiving_app_disabled","message":"The receiving app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `receiving_app_disabled`: the receiving app is disabled\n- `app_mismatch`: app credentials were used on another app's `/v1/apps/{app_id}` URL\n- `not_app_owner`: an account that isn't one of the app's authors (its owner or an accepted co-author) tried to manage it\n- `app_disabled`: the app is disabled\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["receiving_app_disabled","app_mismatch","not_app_owner","app_disabled","origin_not_allowed"]},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"app_verification_single_app","message":"An app verification request named apps in audiences: an app verification proof is for exactly one app; send {\"receiving_app\": \"…\"} once per app (details.field, details.apps)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `app_verification_single_app`: an app verification request named apps in `audiences`: an app verification proof is for exactly one app; send `{\"receiving_app\": \"…\"}` once per app (`details.field`, `details.apps`)\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_verification_single_app","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Issue an App verification proof for your app","tags":["Proofs"]}},"/v1/apps/{app_id}/proofs/{proof_id}":{"delete":{"description":"The receiving app's next verification answers `valid: false`.","operationId":"revokeAppProof","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/ProofId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Revoked.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_proof_id","message":"Not a UUID."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_proof_id`: not a UUID\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_proof_id","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"proof_not_found","message":"Not a proof you can see."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `proof_not_found`: not a proof you can see\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["proof_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Revoke one of the app's proofs","tags":["Proofs"]}},"/v1/apps/{app_id}/proofs/{proof_id}/history":{"get":{"description":"For one App verification record of an app you manage. Records and their history remain after the credentials expire; no raw token values are returned.","operationId":"getAppVerificationHistory","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/ProofId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/VerificationEvent"},"type":"array"}},"type":"object"}]}}},"description":"History events, newest first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ManagerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"verification_not_found","message":"No App verification history is available here for an app you manage."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `verification_not_found`: no App verification history is available here for an app you manage","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["verification_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Issuance, refresh and revocation history","tags":["Proofs"]}},"/v1/apps/{app_id}/public":{"get":{"description":"CORS `*` (errors too), `Cache-Control: no-cache` so branding changes show at once.","operationId":"getPublicApp","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApp"}}},"description":"The public config.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"app_disabled","message":"The app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_disabled"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_app","message":"No app has this app_id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"What a sign-in page needs","tags":["Apps"]}},"/v1/apps/{app_id}/signin-config":{"patch":{"description":"Objects merge, arrays and plain values replace, null resets a field to its default. Send `expected_version` to fail instead of overwriting a change made in between. No change means no new version; every change adds a history entry.","operationId":"updateSigninConfig","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SigninConfigPatch"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/App"}}},"description":"The app.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"content":{"application/json":{"example":{"error":{"code":"config_version_conflict","details":{"current_version":3},"message":"The sign-in setup changed since the version you sent (details.current_version): re-read, re-apply, resend."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `config_version_conflict`: the sign-in setup changed since the version you sent (`details.current_version`): re-read, re-apply, resend\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["config_version_conflict","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Change the sign-in setup","tags":["Apps"]}},"/v1/apps/{app_id}/signin-config/history":{"get":{"description":"Newest first. Secrets show as \"[redacted]\".","operationId":"listSigninConfigHistory","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/SigninConfigVersion"},"type":"array"}},"type":"object"}]}}},"description":"Versions.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Every version of the sign-in setup","tags":["Apps"]}},"/v1/apps/{app_id}/subscriptions":{"get":{"description":"At most two: one webhook subscription and one stream subscription.","operationId":"listSubscriptions","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Subscription"},"type":"array"}},"type":"object"}]}}},"description":"The subscriptions (`next_cursor` is always null).","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The app's subscriptions","tags":["Subscriptions"]},"post":{"description":"Pick where updates go (`webhook` with a `url`, or `stream`), which updates (omitted = id_change, display_name_change, pfp_change, access_removed, account_deleted; null = every update) and the status. A new webhook subscription answers its signing secret once; the Idempotency-Key result is kept 10 minutes because of it.","operationId":"createSubscription","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCreated"}}},"description":"Created.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"content":{"application/json":{"example":{"error":{"code":"subscription_exists","details":{"subscription_id":"01a1150c-6a2e-7b11-9f0e-3c1d2b4a5e6f"},"message":"The app already has a subscription with this delivery (details.subscription_id); change that one instead."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `subscription_exists`: the app already has a subscription with this delivery (`details.subscription_id`); change that one instead\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["subscription_exists","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once\n- `invalid_updates`: an entry of `updates` isn't an update name (`details.allowed` lists them)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed","invalid_updates"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a subscription","tags":["Subscriptions"]}},"/v1/apps/{app_id}/subscriptions/{subscription_id}":{"delete":{"description":"Deleting the webhook subscription removes the webhook URL and secret (pending deliveries fail, replayable later). Deleting the stream subscription ends open streams (`stream.closed`, reason `subscription_deleted`).","operationId":"deleteSubscription","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/SubscriptionId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Deleted.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"subscription_not_found","message":"No subscription with this id belongs to the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `subscription_not_found`: no subscription with this id belongs to the app\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["subscription_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Delete a subscription","tags":["Subscriptions"]},"get":{"description":"Its delivery, status, URL (webhooks) and the updates and event types it receives.","operationId":"getSubscription","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/SubscriptionId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}},"description":"The subscription.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"subscription_not_found","message":"No subscription with this id belongs to the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `subscription_not_found`: no subscription with this id belongs to the app\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["subscription_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One subscription","tags":["Subscriptions"]},"patch":{"description":"Change `updates`, pause or resume with `status`, or move a webhook to another `url` (the signing secret stays).","operationId":"updateSubscription","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/SubscriptionId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}},"description":"The subscription.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"subscription_not_found","message":"No subscription with this id belongs to the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `subscription_not_found`: no subscription with this id belongs to the app\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["subscription_not_found","unknown_app"]},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once\n- `invalid_updates`: an entry of `updates` isn't an update name (`details.allowed` lists them)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed","invalid_updates"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Change a subscription","tags":["Subscriptions"]}},"/v1/apps/{app_id}/subscriptions/{subscription_id}/test":{"post":{"description":"Queues a `ping` on that subscription: a webhook delivery, or a frame on open streams.","operationId":"testSubscription","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/SubscriptionId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionTest"}}},"description":"Queued.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"subscription_not_found","message":"No subscription with this id belongs to the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `subscription_not_found`: no subscription with this id belongs to the app\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["subscription_not_found","unknown_app"]},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Send a test ping on a subscription","tags":["Subscriptions"]}},"/v1/apps/{app_id}/users":{"get":{"description":"Every account that signed into the app or was imported. Deleted accounts stay listed as history with `status: deleted` and no contact details.","operationId":"listAppUsers","parameters":[{"$ref":"#/components/parameters/AppId"},{"description":"Matches the uuid exactly, the id, display name, external_id, the contacts you imported, and the primary email or phone where you were granted that scope.","in":"query","name":"q","required":false,"schema":{"type":"string"}},{"description":"Only this membership status.","in":"query","name":"status","required":false,"schema":{"enum":["active","imported","access_removed","deleted"],"type":"string"}},{"description":"Only Carbons or Silicons.","in":"query","name":"kind","required":false,"schema":{"enum":["carbon","silicon"],"type":"string"}},{"description":"How the member arrived.","in":"query","name":"source","required":false,"schema":{"enum":["signin","slt","import"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/AppUser"},"type":"array"}},"type":"object"}]}}},"description":"Members.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The app's user base","tags":["Apps"]}},"/v1/apps/{app_id}/users/{uuid}":{"get":{"description":"One member of the app's user base, plus its last 20 sign-ins at this app (no IP addresses).","operationId":"getAppUser","parameters":[{"$ref":"#/components/parameters/AppId"},{"description":"The member's account uuid (case-sensitive).","in":"path","name":"uuid","required":true,"schema":{"$ref":"#/components/schemas/AccountUuid"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppUserDetail"}}},"description":"The member.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"user_not_found","message":"The uuid isn't in this app's user base (uuids are case-sensitive)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `user_not_found`: the uuid isn't in this app's user base (uuids are case-sensitive)\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["user_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One member with recent sign-ins","tags":["Apps"]}},"/v1/apps/{app_id}/webhook":{"delete":{"description":"Removes the URL and secret. Pending deliveries become failed (replayable once a URL is set again).","operationId":"removeAppWebhook","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed. Repeating it is harmless.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove the app's webhook","tags":["Webhooks"]},"get":{"description":"The URL, whether a signing secret is stored, the updates it receives, and the webhook subscription behind it. Secrets are never returned.","operationId":"getAppWebhook","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppWebhook"}}},"description":"The webhook.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The app's webhook","tags":["Webhooks"]},"put":{"description":"Sets the app's webhook URL (its webhook subscription). One rule for the signing secret, as when a webhook subscription is moved: saving the URL, the same one or another, keeps the stored secret and `secret` is null. A new secret is made, and shown once, only when the app has none: when the webhook is first created (or set again after it was removed); a secret made with `generate-secret` before the URL is set is kept. Replace it with `rotate-secret`. `events` absent keeps the current picks (every update for a new webhook), `null` picks every update, a list picks those. A retry with the same Idempotency-Key within 10 minutes returns the same answer. `preserve_secret` is still accepted and changes nothing. In production the URL must be https and reach a public address.","operationId":"setAppWebhook","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppWebhookSet"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppWebhookSecret"}}},"description":"The webhook, its secret when this save made one (else null), and the updates it receives.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_webhook_events","message":"events may only contain the update names id_change, display_name_change, pfp_change, timezone_change, email_change, phone_change, custodian_change, access_removed and account_deleted."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_webhook_events`: `events` may only contain the update names id_change, display_name_change, pfp_change, timezone_change, email_change, phone_change, custodian_change, access_removed and account_deleted\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_webhook_events","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Set the app's webhook","tags":["Webhooks"]}},"/v1/apps/{app_id}/webhook/deliveries":{"get":{"description":"Newest first.","operationId":"listAppWebhookDeliveries","parameters":[{"$ref":"#/components/parameters/AppId"},{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["pending","delivered","failed"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookDelivery"},"type":"array"}},"type":"object"}]}}},"description":"Deliveries.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The app's webhook deliveries","tags":["Webhooks"]}},"/v1/apps/{app_id}/webhook/deliveries/{delivery_id}":{"get":{"description":"While the account has no live membership with the app, or was deleted, events carrying its data show `payload.data` cut down to `{uuid, membership_id}` with `payload_redacted: true`.","operationId":"getAppWebhookDelivery","parameters":[{"$ref":"#/components/parameters/AppId"},{"description":"The webhook delivery's id.","in":"path","name":"delivery_id","required":true,"schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}}},"description":"The delivery.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"delivery_not_found","message":"No such webhook delivery for this app, or for this Silicon (/v1/me/webhook/deliveries…)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `delivery_not_found`: no such webhook delivery for this app, or for this Silicon (`/v1/me/webhook/deliveries…`)\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["delivery_not_found","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One delivery with its attempts","tags":["Webhooks"]}},"/v1/apps/{app_id}/webhook/generate-secret":{"post":{"description":"Like rotate-secret, but works when no webhook URL is set yet, so you can configure your receiver first and then set the URL with `PUT /v1/apps/{app_id}/webhook` and `preserve_secret: true`.","operationId":"generateAppWebhookSecret","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}},"description":"The new secret, shown once.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Make a signing secret before setting a URL","tags":["Webhooks"]}},"/v1/apps/{app_id}/webhook/replay":{"post":{"description":"Each delivery goes back to pending with the same event_id and payload, to the current URL, signed with the current secret, with a fresh 72 hours of retries. With `status: failed`, call again (new Idempotency-Key) until `remaining` is 0. Events carrying the data of an account that removed the app's access or was deleted are never replayed (`membership_inactive`, `account_deleted`).","operationId":"replayAppWebhookDeliveries","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayResult"}}},"description":"What was replayed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"content":{"application/json":{"example":{"error":{"code":"webhook_not_set","hint":"Set one first with PUT /v1/apps/{app_id}/webhook {\"url\":\"https://...\"}.","message":"The app 'briefcase' has no webhook URL, so there is nowhere to send events."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `webhook_not_set`: a test ping, secret rotation or replay without a webhook URL: set one first\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["webhook_not_set","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Send deliveries again","tags":["Webhooks"]}},"/v1/apps/{app_id}/webhook/rotate-secret":{"post":{"description":"The old secret stops signing at once; deliveries, retries and replays are signed with the new one.","operationId":"rotateAppWebhookSecret","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}},"description":"The new secret, shown once.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"content":{"application/json":{"example":{"error":{"code":"webhook_not_set","hint":"Set one first with PUT /v1/apps/{app_id}/webhook {\"url\":\"https://...\"}.","message":"The app 'briefcase' has no webhook URL, so there is nowhere to send events."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `webhook_not_set`: a test ping, secret rotation or replay without a webhook URL: set one first\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["webhook_not_set","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Rotate the signing secret","tags":["Webhooks"]}},"/v1/apps/{app_id}/webhook/test":{"post":{"description":"A retry with the same Idempotency-Key queues no second ping.","operationId":"testAppWebhook","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppWebhookTest"}}},"description":"Queued.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/AppOwnerForbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"content":{"application/json":{"example":{"error":{"code":"webhook_not_set","hint":"Set one first with PUT /v1/apps/{app_id}/webhook {\"url\":\"https://...\"}.","message":"The app 'briefcase' has no webhook URL, so there is nowhere to send events."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `webhook_not_set`: a test ping, secret rotation or replay without a webhook URL: set one first\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["webhook_not_set","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Send the app a test ping","tags":["Webhooks"]}},"/v1/capabilities":{"get":{"description":"Every capability with whether it is supported, its endpoints and docs, the auth methods, limits and discovery links. Send `require` to check a list at once: anything unknown or unsupported is 422 `capabilities_missing`, so a client fails early instead of halfway.","operationId":"getCapabilities","parameters":[{"description":"Comma-separated capability names that must be supported, like `sse,subscriptions,webhooks`. Known names: rest_json, openapi, structured_errors, rate_limit_headers, idempotency_keys, pagination, version_negotiation, capability_negotiation, bearer_tokens, client_credentials, oauth2, openid_connect, device_flow, short_lived_tokens, workload_identity_federation, identity_tokens, proofs, webhooks, webhook_signatures, webhook_replay, sse, stream_resume, subscriptions, imports, agent_card, mcp, llms_txt. Aliases are accepted too, such as `event_stream`, `event_streaming`, `events_stream`, `server_sent_events` and `streaming` for `sse`.","in":"query","name":"require","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Capabilities"}}},"description":"The capabilities. With `require`, `require.satisfied` is true.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_query","message":"A query parameter is missing, has the wrong type or an unknown value (named)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_query`: a query parameter is missing, has the wrong type or an unknown value (named)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_query","unsupported_version"]},"422":{"content":{"application/json":{"example":{"error":{"code":"capabilities_missing","details":{"available":["rest_json","openapi","sse","subscriptions","webhooks"],"missing":["telepathy"],"supported":["rest_json","openapi","sse","subscriptions","webhooks"]},"hint":"Drop the capability from require, or use another server.","message":"This server doesn't support the capability telepathy."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `capabilities_missing`: a capability named in `require` is unknown or not supported here (`details.missing`, `details.supported`, `details.available`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["capabilities_missing"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"What this server supports","tags":["Discovery"]}},"/v1/cli/login/start":{"post":{"description":"Sends a 6-digit code (10 minutes) to a verified address of an existing, active Carbon. 60 starts per IP per 10 minutes; 10 codes per address per 10 minutes.","operationId":"startCliLogin","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliLoginStart"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliChallenge"}}},"description":"A code was sent.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_request","message":"The request is missing something it needs (the message names it)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_request`: the request is missing something it needs (the message names it)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_request","invalid_json","invalid_content_type","unsupported_version"]},"404":{"content":{"application/json":{"example":{"error":{"code":"account_not_found","message":"No account with this uuid or current id; at CLI sign-in, no active Carbon with that email or phone (sign up first)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `account_not_found`: no account with this uuid or current id; at CLI sign-in, no active Carbon with that email or phone (sign up first)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["account_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_email","message":"The email address can't be read (the message says why)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_email`: the email address can't be read (the message says why)\n- `invalid_phone`: the phone number can't be read (the message says why)\n- `invalid_country`: `country` isn't an ISO 3166 country code\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_email","invalid_phone","invalid_country","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Start a CLI sign-in with a code","tags":["Sign-in"]}},"/v1/cli/login/verify":{"post":{"description":"Answers first-party tokens (`aud: silicon-accounts`), listed in the sessions as origin `cli_code`.","operationId":"verifyCliLogin","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliLoginVerify"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}},"description":"Tokens.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"content":{"application/json":{"example":{"error":{"code":"challenge_not_found","message":"Unknown challenge_id (or one of another flow)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `challenge_not_found`: unknown `challenge_id` (or one of another flow)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["challenge_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"code_already_used","message":"This code was already accepted."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `code_already_used`: this code was already accepted","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_already_used"]},"410":{"content":{"application/json":{"example":{"error":{"code":"code_expired","message":"Older than 10 minutes, or replaced by a resend; send a new one."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `code_expired`: older than 10 minutes, or replaced by a resend; send a new one","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_code","details":{"remaining_attempts":9},"message":"That code is wrong; 9 more tries for a***@example.test before a 60 second cooldown."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_code`: wrong code (`details.remaining_attempts` for the address), or not 6 digits (not counted). The 10th wrong one in a row has `remaining_attempts: 0`, `details.locked_until` and `Retry-After`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_code","validation_failed"]},"423":{"$ref":"#/components/responses/Locked"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Finish a CLI sign-in","tags":["Sign-in"]}},"/v1/dev/outbox":{"get":{"description":"Development only: the emails and text messages the service recorded, newest first, with the 6-digit code parsed out. Works only with `ACCOUNTS_EXPOSE_DEV_OUTBOX=true` outside production; in production it answers like an unknown route.","operationId":"listDevOutbox","parameters":[{"description":"The exact address (case-insensitive; phones in E.164, URL-encoded as %2B...).","in":"query","name":"to","required":false,"schema":{"type":"string"}},{"description":"The exact purpose, like otp_signin.","in":"query","name":"purpose","required":false,"schema":{"type":"string"}},{"description":"1 to 200, default 50.","in":"query","name":"limit","required":false,"schema":{"default":50,"maximum":200,"minimum":1,"type":"integer"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/OutboxMessage"},"type":"array"}},"type":"object"}]}}},"description":"Messages (`next_cursor` is always null).","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"content":{"application/json":{"example":{"error":{"code":"dev_outbox_disabled","message":"The development outbox is off."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `dev_outbox_disabled`: the development outbox is off\n- `route_not_found`: no endpoint has this path","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["dev_outbox_disabled","route_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Messages recorded by a development server","tags":["Internal"],"x-internal":true}},"/v1/device/authorize":{"post":{"description":"For the silicon-accounts CLI, and for an app's own command-line tool (`client_id=<app_id>`, once the app turned on `device_flow`; no secret needed). Show `user_code` and `verification_uri` to the Carbon, who approves on the account site, then poll `POST /v1/oauth/token` with the device_code grant every `interval` seconds. 60 per IP and 600 per app per 10 minutes. Errors use the API error shape.","operationId":"startDeviceAuthorization","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceAuthorizationRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/DeviceAuthorizationRequest"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceAuthorization"}}},"description":"The device and user codes.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"unauthorized_client","message":"client_id was sent and isn't silicon-accounts."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `unauthorized_client`: `client_id` was sent and isn't `silicon-accounts`\n- `invalid_client`: `POST /v1/device/authorize` named an app that doesn't exist\n- `invalid_scope`: an unknown scope (with `details.redirect_to`)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unauthorized_client","invalid_client","invalid_scope","invalid_json","invalid_content_type","unsupported_version"]},"401":{"content":{"application/json":{"example":{"error":{"code":"invalid_app_credentials","message":"Unknown app_id, wrong secret, or malformed Basic header."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not authenticated.\n\n- `invalid_app_credentials`: unknown app_id, wrong secret, or malformed Basic header","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_app_credentials"]},"403":{"content":{"application/json":{"example":{"error":{"code":"app_disabled","message":"The app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_disabled"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Start a device sign-in (RFC 8628)","tags":["OAuth and OIDC"]}},"/v1/device/{user_code}":{"get":{"description":"Which app is asking (its name, logos and branding for the approval page) and what it will share. 60 lookups per Carbon per 10 minutes.","operationId":"getDeviceRequest","parameters":[{"$ref":"#/components/parameters/UserCode"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceRequest"}}},"description":"The device request.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"device_code_not_found","message":"No device sign-in waits for this user code."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `device_code_not_found`: no device sign-in waits for this user code","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_not_found"]},"410":{"content":{"application/json":{"example":{"error":{"code":"device_code_expired","message":"User codes last 10 minutes; start the sign-in again."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `device_code_expired`: user codes last 10 minutes; start the sign-in again","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_expired"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"A waiting device sign-in","tags":["Sign-in"]}},"/v1/device/{user_code}/approve":{"post":{"description":"The waiting tool's next poll gets tokens for you: first-party tokens for the silicon-accounts CLI, the app's tokens for an app's tool (after the app's rules: domains, required details).","operationId":"approveDeviceRequest","parameters":[{"$ref":"#/components/parameters/UserCode"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Approved.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"app_disabled","message":"The app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `app_disabled`: the app is disabled\n- `device_flow_off`: the app turned device sign-ins off after the code was made\n- `email_domain_not_allowed`: the app accepts only some email domains\n- `carbon_only`: a Silicon called an endpoint for Carbons (emails, phones, custodian side…)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_disabled","device_flow_off","email_domain_not_allowed","carbon_only","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"device_code_not_found","message":"No device sign-in waits for this user code."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `device_code_not_found`: no device sign-in waits for this user code","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"device_code_used","message":"Already approved or denied."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `device_code_used`: already approved or denied\n- `requirements_missing`: the app requires a detail the account lacks (`details.missing`); add it, then retry","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_used","requirements_missing"]},"410":{"content":{"application/json":{"example":{"error":{"code":"device_code_expired","message":"User codes last 10 minutes; start the sign-in again."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `device_code_expired`: user codes last 10 minutes; start the sign-in again","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_expired"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Approve a device sign-in","tags":["Sign-in"]}},"/v1/device/{user_code}/deny":{"post":{"description":"The waiting CLI's poll returns `access_denied`.","operationId":"denyDeviceRequest","parameters":[{"$ref":"#/components/parameters/UserCode"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Denied.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"device_code_not_found","message":"No device sign-in waits for this user code."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `device_code_not_found`: no device sign-in waits for this user code","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"device_code_used","message":"Already approved or denied."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `device_code_used`: already approved or denied","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_used"]},"410":{"content":{"application/json":{"example":{"error":{"code":"device_code_expired","message":"User codes last 10 minutes; start the sign-in again."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `device_code_expired`: user codes last 10 minutes; start the sign-in again","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["device_code_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Deny a device sign-in","tags":["Sign-in"]}},"/v1/events/stream":{"get":{"description":"The same events as webhooks, pushed over one long HTTP response. Who gets what:\n\n- an app (Basic credentials): the events of its stream subscription, with the same bodies as its webhook (it needs a stream subscription);\n- a Silicon (bearer token): its own Silicon events (silicon.created, silicon.custodian.accepted, silicon.custodian.declined, silicon.custodian.expired, silicon.updated, silicon.id_changed, silicon.stk_rotated, silicon.custodian.changed, ping);\n- a Carbon (bearer token or cookie): the Silicon events of the Silicons it is custodian of;\n- a self-created Silicon still waiting for its custodian: its own events, with its `sarq_` request token.\n\nAt most 5 open streams per app or account. Server-Sent Events. The first frame is `retry: 5000`. Then one frame per event:\n\n```\nid: <event_id>\nevent: <type>\ndata: <the webhook body JSON>\n```\n\nA comment line `: heartbeat` arrives after 15 seconds without events. Before the server ends the stream it sends `event: stream.closed` with data `{\"reason\", \"message\"}`, reason `token_expired`, `access_removed`, `subscription_deleted`, `request_decided`, `max_duration` or `server_restarting`. Reconnect with `Last-Event-ID`. Delivery is at least once: dedupe on `event_id`.","operationId":"streamEvents","parameters":[{"description":"Resume after this event_id. `Last-Event-ID` wins when both are sent.","in":"query","name":"after","required":false,"schema":{"format":"uuid","type":"string"}},{"description":"Comma-separated event types to keep, like `account.updated,account.deleted`.","in":"query","name":"types","required":false,"schema":{"type":"string"}},{"description":"An event_id: resume after it.","in":"header","name":"Last-Event-ID","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"text/event-stream":{"example":"retry: 5000\n\nid: 01a11437-b515-70c4-9a30-c372fb435334\nevent: account.updated\ndata: {\"app_id\":\"briefcase\",\"type\":\"account.updated\",\"event_id\":\"01a11437-b515-70c4-9a30-c372fb435334\",\"occurred_at\":\"2026-10-07T02:35:57.589Z\",\"silicon\":null,\"data\":{\"uuid\":\"8HV\",\"membership_id\":\"briefcase:8HV\",\"changed\":[\"pfp_url\"]}}\n\n: heartbeat\n\n","schema":{"description":"Server-Sent Events. The first frame is `retry: 5000`. Then one frame per event:\n\n```\nid: <event_id>\nevent: <type>\ndata: <the webhook body JSON>\n```\n\nA comment line `: heartbeat` arrives after 15 seconds without events. Before the server ends the stream it sends `event: stream.closed` with data `{\"reason\", \"message\"}`, reason `token_expired`, `access_removed`, `subscription_deleted`, `request_decided`, `max_duration` or `server_restarting`. Reconnect with `Last-Event-ID`. Delivery is at least once: dedupe on `event_id`.","type":"string"}}},"description":"The stream.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`no-store`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_query","message":"A query parameter is missing, has the wrong type or an unknown value (named)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_query`: a query parameter is missing, has the wrong type or an unknown value (named)\n- `unknown_event_id`: the resume cursor (`Last-Event-ID` or `after`) is not an event of this feed; reconnect without it\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_query","unknown_event_id","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"content":{"application/json":{"example":{"error":{"code":"stream_subscription_required","message":"The app has no stream subscription; create one with POST /v1/apps/{app_id}/subscriptions and delivery: stream."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `stream_subscription_required`: the app has no stream subscription; create one with `POST /v1/apps/{app_id}/subscriptions` and `delivery: stream`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["stream_subscription_required"]},"429":{"content":{"application/json":{"example":{"error":{"code":"too_many_streams","details":{"retry_after_seconds":30},"message":"This app already has 5 open event streams."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Rate limited.\n\n- `too_many_streams`: at most 5 event streams may be open per app or account; close one, or wait `Retry-After` seconds","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["too_many_streams"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"content":{"application/json":{"example":{"error":{"code":"stream_capacity_reached","message":"This server is full or restarting; reconnect after Retry-After seconds with Last-Event-ID."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Service unavailable.\n\n- `stream_capacity_reached`: this server is full or restarting; reconnect after `Retry-After` seconds with `Last-Event-ID`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["stream_capacity_reached"]}},"security":[{"appBasic":[]},{"bearerAuth":[]},{"sessionCookie":[]},{"requestToken":[]}],"summary":"Stream events as they happen (SSE)","tags":["Events"]}},"/v1/flows":{"post":{"description":"The account site's sign-in page calls this with the `/authorize` query. Apps send the browser to `/authorize` instead of calling it. Needs an `Origin` equal to the public origin. With `prompt=none` the flow is decided at once (complete, or failed with `redirect_to`), still 201. 300 flows per minute per IP.","operationId":"createFlow","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow, at choose_method.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Set-Cookie":{"description":"`sa_flow=saf_...; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600` (`__Host-sa_flow` in production).","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"unknown_app","message":"No app has this app_id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `unknown_app`: no app has this app_id\n- `app_disabled`: the app is disabled\n- `redirect_uri_not_registered`: the `redirect_uri` isn't registered exactly; never redirected to\n- `invalid_request`: the request is missing something it needs (the message names it)\n- `invalid_scope`: an unknown scope (with `details.redirect_to`)\n- `unsupported_response_type`: `response_type` other than `code`\n- `method_not_enabled`: the app didn't enable that method (or no managed credentials exist)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_app","app_disabled","redirect_uri_not_registered","invalid_request","invalid_scope","unsupported_response_type","method_not_enabled","invalid_json","invalid_content_type","unsupported_version"]},"403":{"content":{"application/json":{"example":{"error":{"code":"origin_not_allowed","message":"A cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's Origin; use a Bearer token instead of the cookie."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["origin_not_allowed"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Start a hosted sign-in flow","tags":["Sign-in"]}},"/v1/flows/{id}":{"get":{"description":"Also claims a Google or Apple answer that arrived for this flow: the browser or sign-up session is created here, on the request that carries the binding cookie. A finished flow keeps answering with its `redirect_to`.","operationId":"getFlow","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Read a flow","tags":["Sign-in"]}},"/v1/flows/{id}/continue":{"post":{"description":"\"Continue as\" the browser's signed-in Carbon (`signed_in_as`). No body. Moves to details or complete.","operationId":"continueFlow","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/FlowSessionRequired"},"403":{"content":{"application/json":{"example":{"error":{"code":"continue_not_allowed","message":"The app turned off remember_browser."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `continue_not_allowed`: the app turned off `remember_browser`\n- `reauthentication_required`: the app asked for `prompt=login`\n- `carbon_only`: a Silicon called an endpoint for Carbons (emails, phones, custodian side…)\n- `email_domain_not_allowed`: the app accepts only some email domains\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["continue_not_allowed","reauthentication_required","carbon_only","email_domain_not_allowed","flow_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"invalid_step","message":"The flow is at another step (the message names the allowed ones)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `invalid_step`: the flow is at another step (the message names the allowed ones)\n- `flow_completed`: the flow ended; `GET /v1/flows/{id}` returns its `redirect_to`\n- `flow_failed`: the flow ended; `GET /v1/flows/{id}` returns its `redirect_to`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_step","flow_completed","flow_failed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"sessionCookie":[]}],"summary":"Continue as the signed-in Carbon","tags":["Sign-in"]}},"/v1/flows/{id}/details/add":{"post":{"description":"Sends a 6-digit code to add an email or phone that is missing on the page on screen. When the account already has it, nothing is sent.","operationId":"addFlowDetail","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowDetailAdd"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/FlowSessionRequired"},"403":{"content":{"application/json":{"example":{"error":{"code":"email_domain_not_allowed","message":"The app accepts only some email domains."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `email_domain_not_allowed`: the app accepts only some email domains\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_domain_not_allowed","flow_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"detail_not_on_page","message":"details/add for a detail that isn't on the page on screen."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `detail_not_on_page`: `details/add` for a detail that isn't on the page on screen\n- `email_in_use`: it belongs to another account; an address belongs to one account only\n- `phone_in_use`: it belongs to another account; an address belongs to one account only\n- `account_changed`: the browser is now signed in as a different account than the flow's","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["detail_not_on_page","email_in_use","phone_in_use","account_changed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"email_limit_reached","message":"10 already; remove one first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `email_limit_reached`: 10 already; remove one first\n- `phone_limit_reached`: 10 already; remove one first\n- `invalid_email`: the email address can't be read (the message says why)\n- `invalid_phone`: the phone number can't be read (the message says why)\n- `invalid_country`: `country` isn't an ISO 3166 country code\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_limit_reached","phone_limit_reached","invalid_email","invalid_phone","invalid_country","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"sessionCookie":[]}],"summary":"Add a missing email or phone on a details page","tags":["Sign-in"]}},"/v1/flows/{id}/details/back":{"post":{"description":"Answers are kept. Also works from review.","operationId":"backFlowDetails","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/FlowSessionRequired"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"no_previous_page","message":"details/back on the first page."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `no_previous_page`: `details/back` on the first page\n- `account_changed`: the browser is now signed in as a different account than the flow's","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["no_previous_page","account_changed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"sessionCookie":[]}],"summary":"Back to the previous details page","tags":["Sign-in"]}},"/v1/flows/{id}/details/continue":{"post":{"description":"`share` lists the optional details of this page the Carbon ticked. Moves to the next page, to review, or completes.","operationId":"continueFlowDetails","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowDetailsContinue"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/FlowSessionRequired"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"requirements_missing","details":{"missing":["phone"]},"message":"DM requires your phone number, which your account doesn't have yet."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `requirements_missing`: the app requires a detail the account lacks (`details.missing`); add it, then retry\n- `flow_changed`: the flow moved on in another tab while this request ran, or the app changed its flow and the details page is gone: `GET /v1/flows/{id}` shows where it is now\n- `account_changed`: the browser is now signed in as a different account than the flow's","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["requirements_missing","flow_changed","account_changed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"sessionCookie":[]}],"summary":"Continue from a details page","tags":["Sign-in"]}},"/v1/flows/{id}/details/verify":{"post":{"description":"Adds the address, verified, to the account (its primary when it has none). The flow stays on the page.","operationId":"verifyFlowDetail","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowCode"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/FlowSessionRequired"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"no_code_sent","message":"A resend (or a requirement verify) before any code was sent in this flow."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `no_code_sent`: a resend (or a requirement verify) before any code was sent in this flow\n- `code_already_used`: this code was already accepted\n- `email_in_use`: it belongs to another account; an address belongs to one account only\n- `phone_in_use`: it belongs to another account; an address belongs to one account only\n- `flow_changed`: the flow moved on in another tab while this request ran, or the app changed its flow and the details page is gone: `GET /v1/flows/{id}` shows where it is now\n- `account_changed`: the browser is now signed in as a different account than the flow's","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["no_code_sent","code_already_used","email_in_use","phone_in_use","flow_changed","account_changed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app\n- `code_expired`: older than 10 minutes, or replaced by a resend; send a new one","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired","code_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_code","details":{"remaining_attempts":9},"message":"That code is wrong; 9 more tries for a***@example.test before a 60 second cooldown."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_code`: wrong code (`details.remaining_attempts` for the address), or not 6 digits (not counted). The 10th wrong one in a row has `remaining_attempts: 0`, `details.locked_until` and `Retry-After`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_code","validation_failed"]},"423":{"$ref":"#/components/responses/Locked"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"sessionCookie":[]}],"summary":"Verify the added email or phone","tags":["Sign-in"]}},"/v1/flows/{id}/email":{"post":{"description":"Moves to verify_code with a masked `challenge`. Codes last 10 minutes. 10 codes per address and 30 per IP per 10 minutes.","operationId":"sendFlowEmailCode","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEmail"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"method_not_enabled","message":"The app didn't enable that method (or no managed credentials exist)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `method_not_enabled`: the app didn't enable that method (or no managed credentials exist)\n- `email_domain_not_allowed`: the app accepts only some email domains\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["method_not_enabled","email_domain_not_allowed","flow_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"invalid_step","message":"The flow is at another step (the message names the allowed ones)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `invalid_step`: the flow is at another step (the message names the allowed ones)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_step"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_email","message":"The email address can't be read (the message says why)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_email`: the email address can't be read (the message says why)\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_email","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Send a sign-in code by email","tags":["Sign-in"]}},"/v1/flows/{id}/oauth/{provider}":{"post":{"description":"Send the browser to `authorize_url`. Uses the app's own credentials in bring-your-own mode, ours otherwise.","operationId":"startFlowProvider","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/Provider"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderUrl"}}},"description":"Where to send the browser.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"method_not_enabled","message":"The app didn't enable that method (or no managed credentials exist)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `method_not_enabled`: the app didn't enable that method (or no managed credentials exist)\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["method_not_enabled","flow_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id\n- `unknown_provider`: the provider in the URL isn't `google` or `apple`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found","unknown_provider"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"content":{"application/json":{"example":{"error":{"code":"provider_not_configured","message":"No Google/Apple credentials for this app or deployment."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Service unavailable.\n\n- `provider_not_configured`: no Google/Apple credentials for this app or deployment\n- `database_unavailable`: the database is unreachable; nothing was changed; retry in a few seconds\n- `request_timeout`: the request ran past its time budget (30 s, 60 s for uploads, 5 min for imports)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["provider_not_configured","database_unavailable","request_timeout"]}},"security":[{"flowCookie":[]}],"summary":"Start Google or Apple sign-in","tags":["Sign-in"]}},"/v1/flows/{id}/phone":{"post":{"description":"`country` is an ISO code for local numbers; E.164 numbers need none. Moves to verify_code. Same send limits as email.","operationId":"sendFlowPhoneCode","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowPhone"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"method_not_enabled","message":"The app didn't enable that method (or no managed credentials exist)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `method_not_enabled`: the app didn't enable that method (or no managed credentials exist)\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["method_not_enabled","flow_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"invalid_step","message":"The flow is at another step (the message names the allowed ones)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `invalid_step`: the flow is at another step (the message names the allowed ones)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_step"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_phone","message":"The phone number can't be read (the message says why)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_phone`: the phone number can't be read (the message says why)\n- `invalid_country`: `country` isn't an ISO 3166 country code\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_phone","invalid_country","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Send a sign-in code by text message","tags":["Sign-in"]}},"/v1/flows/{id}/resend":{"post":{"description":"A new code to the same destination (the sign-in code, or at details the code that adds a missing email or phone). The old code stops working; the failure count carries over. Counts toward the send limits.","operationId":"resendFlowCode","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"no_code_sent","message":"A resend (or a requirement verify) before any code was sent in this flow."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `no_code_sent`: a resend (or a requirement verify) before any code was sent in this flow","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["no_code_sent"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Send the code again","tags":["Sign-in"]}},"/v1/flows/{id}/review":{"post":{"description":"`approve: true` on the review page completes the sign-in and `redirect_to` carries `code` and `state`. `approve: false`, on review or any details page, is Cancel (`error=access_denied`).","operationId":"reviewFlow","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowReview"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/FlowSessionRequired"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"invalid_step","message":"The flow is at another step (the message names the allowed ones)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `invalid_step`: the flow is at another step (the message names the allowed ones)\n- `requirements_missing`: the app requires a detail the account lacks (`details.missing`); add it, then retry\n- `account_changed`: the browser is now signed in as a different account than the flow's","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_step","requirements_missing","account_changed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"sessionCookie":[]}],"summary":"Approve or cancel the sign-in","tags":["Sign-in"]}},"/v1/flows/{id}/signup":{"post":{"description":"Needs the flow cookie and the `sa_signup` cookie of the same browser. Creates the Carbon (or finishes an imported one, keeping its uuid), signs the browser in and moves on, usually to the first details page.","operationId":"completeFlowSignup","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowSignup"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Set-Cookie":{"description":"The browser session `sa_session` (and `sa_signup` cleared).","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"signup_not_allowed","message":"The app takes no new accounts (allow_signup: false)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `signup_not_allowed`: the app takes no new accounts (`allow_signup: false`)\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `signup_not_bound`: the sign-up belongs to another browser\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["signup_not_allowed","flow_not_bound","signup_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"id_taken","details":{"suggestions":["c:saket-2","c:saket-3","c:saket-4"]},"hint":"Pick another id, for example c:saket-2, c:saket-3, c:saket-4.","message":"c:saket is taken by another account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `id_taken`: another account has it; `details.suggestions` lists free ones\n- `id_reserved`: it was changed away from recently and is held for 10 days (`details.reserved_until`)\n- `signup_already_completed`: this sign-up already created an account; sign in instead","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["id_taken","id_reserved","signup_already_completed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app\n- `signup_expired`: sign-ups last 48 hours; verify the address again","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired","signup_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_id","message":"Not a valid c:/si: id, or the wrong kind; details.reason is invalid or reserved_word."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_id","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"signupCookie":[]}],"summary":"Create the account","tags":["Sign-in"]}},"/v1/flows/{id}/signup/photo":{"post":{"description":"The photo picked on the sign-up page, before the account exists. Same rules as `POST /v1/me/photo`; 20 per sign-up per hour. Replaces the sign-up's earlier upload.","operationId":"uploadFlowSignupPhoto","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"image/gif":{"schema":{"format":"binary","type":"string"}},"image/jpeg":{"schema":{"format":"binary","type":"string"}},"image/png":{"schema":{"format":"binary","type":"string"}},"image/webp":{"schema":{"format":"binary","type":"string"}}},"description":"The raw image: PNG, JPEG, WebP or GIF, at most 2 MB, 8192 px a side, 50 megapixels.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupPhotoUpload"}}},"description":"Uploaded.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/SignupNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app\n- `signup_expired`: sign-ups last 48 hours; verify the address again","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired","signup_expired"]},"413":{"content":{"application/json":{"example":{"error":{"code":"photo_too_large","message":"Over 2 MB."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Payload too large.\n\n- `photo_too_large`: over 2 MB\n- `payload_too_large`: the body is over the route's limit (`details.limit_bytes`: 64 KB by default)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["photo_too_large","payload_too_large"]},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"content":{"application/json":{"example":{"error":{"code":"empty_photo","message":"An empty body."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `empty_photo`: an empty body\n- `invalid_image`: the bytes aren't a readable PNG, JPEG, WebP or GIF\n- `photo_type_mismatch`: the bytes are another format than `Content-Type` says (`details.detected_content_type`)\n- `photo_dimensions_too_large`: over 8192 px a side or 50 megapixels","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["empty_photo","invalid_image","photo_type_mismatch","photo_dimensions_too_large"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[],"signupCookie":[]}],"summary":"Upload the sign-up photo","tags":["Sign-in"]}},"/v1/flows/{id}/switch":{"post":{"description":"Forget the chosen account and go back to choose_method. At the signup step it ends that sign-up. The browser stays signed in. No body.","operationId":"switchFlowAccount","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"$ref":"#/components/responses/FlowNotBound"},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"flow_completed","message":"The flow ended; GET /v1/flows/{id} returns its redirect_to."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `flow_completed`: the flow ended; `GET /v1/flows/{id}` returns its `redirect_to`\n- `flow_failed`: the flow ended; `GET /v1/flows/{id}` returns its `redirect_to`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_completed","flow_failed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Not you? Choose another account","tags":["Sign-in"]}},"/v1/flows/{id}/verify":{"post":{"description":"A right code signs an existing account's browser in (`Set-Cookie: sa_session`), or starts a sign-up for a new address (`Set-Cookie: sa_signup`, 48 hours) and moves to signup. Wrong codes count per address across every flow, the CLI and the account site: 10 in a row lock the address for 60 seconds.","operationId":"verifyFlowCode","parameters":[{"$ref":"#/components/parameters/FlowId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowCode"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlowEnvelope"}}},"description":"The flow.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Set-Cookie":{"description":"The browser session (`sa_session`) or the sign-up session (`sa_signup`).","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"content":{"application/json":{"example":{"error":{"code":"signup_not_allowed","message":"The app takes no new accounts (allow_signup: false)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `signup_not_allowed`: the app takes no new accounts (`allow_signup: false`)\n- `email_domain_not_allowed`: the app accepts only some email domains\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["signup_not_allowed","email_domain_not_allowed","flow_not_bound","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"flow_not_found","message":"Unknown flow id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `flow_not_found`: unknown flow id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"code_already_used","message":"This code was already accepted."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `code_already_used`: this code was already accepted\n- `invalid_step`: the flow is at another step (the message names the allowed ones)\n- `account_unavailable`: the address belongs to an account that can't sign in\n- `flow_changed`: the flow moved on in another tab while this request ran, or the app changed its flow and the details page is gone: `GET /v1/flows/{id}` shows where it is now","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_already_used","invalid_step","account_unavailable","flow_changed"]},"410":{"content":{"application/json":{"example":{"error":{"code":"flow_expired","message":"Flows last 60 minutes; start again from the app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `flow_expired`: flows last 60 minutes; start again from the app\n- `code_expired`: older than 10 minutes, or replaced by a resend; send a new one","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_expired","code_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_code","details":{"remaining_attempts":9},"message":"That code is wrong; 9 more tries for a***@example.test before a 60 second cooldown."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_code`: wrong code (`details.remaining_attempts` for the address), or not 6 digits (not counted). The 10th wrong one in a row has `remaining_attempts: 0`, `details.locked_until` and `Retry-After`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_code","validation_failed"]},"423":{"$ref":"#/components/responses/Locked"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Check the sign-in code","tags":["Sign-in"]}},"/v1/ids/available":{"get":{"description":"An invalid id is a normal 200 answer with `reason: invalid`. Signed in, an id reserved for you is `available: true, reclaimable: true`; a custodian adds `for` to ask for one of its Silicons. 120 per minute per IP.","operationId":"checkIdAvailable","parameters":[{"description":"The full id with its prefix, like c:saket.","in":"query","name":"id","required":true,"schema":{"type":"string"}},{"description":"A Silicon you are custodian of (uuid or si:id).","in":"query","name":"for","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdAvailability"}}},"description":"The answer.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"content":{"application/json":{"example":{"error":{"code":"unauthenticated","message":"This endpoint needs a signed-in account: send Authorization: Bearer <access token>."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not authenticated. Besides the shared codes of `Unauthorized`:\n\n- `unauthenticated`: no credentials; sign in (`silicon-accounts login`) or send the app's Basic credentials","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unauthenticated"]},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Can this id be taken","tags":["Accounts"]}},"/v1/internal/apps":{"get":{"description":"Silicon Apps only. Every app except the first-party ones, by app_id.","operationId":"listInternalApps","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsRegistry"}}},"description":"The apps.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/InternalUnauthorized"},"403":{"$ref":"#/components/responses/InternalApiDisabled"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"internalToken":[]}],"summary":"Every app with its authors","tags":["Internal"],"x-internal":true}},"/v1/internal/apps/mail":{"post":{"description":"A private delivery bridge: contact details never leave Accounts. `mail.invite` invites a Carbon to author an app; `mail.report` forwards a Silicon Apps bug report. Needs an Idempotency-Key.","operationId":"sendInternalAppsMail","parameters":[{"description":"Required here: 1 to 200 visible ASCII characters.","in":"header","name":"Idempotency-Key","required":true,"schema":{"pattern":"^[\\x21-\\x7E]{1,200}$","type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsMailRequest"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsMailQueued"}}},"description":"Queued.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"idempotency_key_required","message":"This endpoint needs an Idempotency-Key header."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `idempotency_key_required`: this endpoint needs an `Idempotency-Key` header\n- `invalid_request`: the request is missing something it needs (the message names it)\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["idempotency_key_required","invalid_request","invalid_idempotency_key","invalid_json","invalid_content_type","unsupported_version"]},"401":{"$ref":"#/components/responses/InternalUnauthorized"},"403":{"$ref":"#/components/responses/InternalApiDisabled"},"409":{"content":{"application/json":{"example":{"error":{"code":"idempotency_key_reused","message":"The key was used for a different body on this endpoint; use a new key for a new request."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"verified_email_missing","message":"The invited Carbon has no verified email to deliver to."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `verified_email_missing`: the invited Carbon has no verified email to deliver to\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["verified_email_missing","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"internalToken":[]}],"summary":"Silicon Apps sends a message through Accounts","tags":["Internal"],"x-internal":true}},"/v1/internal/apps/sync":{"post":{"description":"Everything is validated first and applied in one transaction. An existing app keeps its app_id, users, sign-in setup and webhook. At most 5 MB.","operationId":"syncInternalApps","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsSyncRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppsSyncReport"}}},"description":"What happened to each app.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_body","message":"The body couldn't be read (connection broken mid-upload)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_body`: the body couldn't be read (connection broken mid-upload)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_body","invalid_json","invalid_content_type","unsupported_version"]},"401":{"$ref":"#/components/responses/InternalUnauthorized"},"403":{"$ref":"#/components/responses/InternalApiDisabled"},"409":{"content":{"application/json":{"example":{"error":{"code":"owner_email_conflict","message":"Silicon Apps sync: the owner can't be resolved."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `owner_email_conflict`: Silicon Apps sync: the owner can't be resolved\n- `owner_unavailable`: Silicon Apps sync: the owner can't be resolved","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["owner_email_conflict","owner_unavailable"]},"413":{"content":{"application/json":{"example":{"error":{"code":"payload_too_large","details":{"limit_bytes":65536},"message":"The body is over the route's limit (details.limit_bytes: 64 KB by default)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Payload too large.\n\n- `payload_too_large`: the body is over the route's limit (`details.limit_bytes`: 64 KB by default)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["payload_too_large"]},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once\n- `owner_not_found`: Silicon Apps sync: the owner can't be resolved","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed","owner_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"internalToken":[]}],"summary":"Silicon Apps upserts its apps","tags":["Internal"],"x-internal":true}},"/v1/me":{"delete":{"description":"Carbons only (a Silicon's custodian deletes it). In one step: the account becomes deleted, its id is reserved for 10 days, contacts and linked identities are removed, every session, sign-in and proof about it ends, and every app it signed into gets `account.deleted`.","operationId":"deleteMe","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteConfirmation"}}},"required":true},"responses":{"204":{"description":"Deleted. A cookie session's cookie is cleared.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"custodian_required","message":"A Silicon can't delete itself; its custodian does."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `custodian_required`: a Silicon can't delete itself; its custodian does\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_required","origin_not_allowed"]},"409":{"content":{"application/json":{"example":{"error":{"code":"custodian_of_silicons","message":"A Carbon who is custodian of Silicons can't be deleted (details.silicons); transfer or delete them first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `custodian_of_silicons`: a Carbon who is custodian of Silicons can't be deleted (`details.silicons`); transfer or delete them first","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_of_silicons"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"confirmation_required","message":"DELETE needs {\"confirm\": \"<current id>\"}."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `confirmation_required`: `DELETE` needs `{\"confirm\": \"<current id>\"}`\n- `confirmation_mismatch`: `confirm` isn't the account's current id; nothing was deleted\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["confirmation_required","confirmation_mismatch","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Delete your account","tags":["Accounts"]},"get":{"description":"Works for Carbons and Silicons. Carbons see their emails, phones and linked identities; Silicons see their custodian, webhook URL and when the STK last changed.","operationId":"getMe","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}},"description":"Your account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your account","tags":["Accounts"]},"patch":{"description":"Change `display_name`, `timezone`, `dob` (Carbons only) or `pfp_url`. Apps that can see a changed field get `account.updated`; a Silicon's own webhook gets `silicon.updated`.","operationId":"updateMe","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}},"description":"Your account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once\n- `dob_immutable`: a Silicon's date of birth is its creation day","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed","dob_immutable"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Change your profile","tags":["Accounts"]}},"/v1/me/app-verifications":{"get":{"description":"Retained App verification records issued by the apps you currently manage, from the portal, CLI or API, newest first. Being a receiving app grants no access.","operationId":"listManagedAppVerifications","parameters":[{"description":"Only this app (one you manage).","in":"query","name":"app_id","required":false,"schema":{"type":"string"}},{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["active","revoked","expired"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/ManagedAppVerification"},"type":"array"}},"type":"object"}]}}},"description":"Records.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ManagerForbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"verification_not_found","message":"No App verification history is available here for an app you manage."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `verification_not_found`: no App verification history is available here for an app you manage","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["verification_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"App verification records of apps you manage","tags":["Proofs"]}},"/v1/me/apps":{"get":{"description":"Most recently used first. The account site itself is not listed.","operationId":"listMyApps","parameters":[{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["active","access_removed","imported"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/MyApp"},"type":"array"}},"type":"object"}]}}},"description":"Your apps.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Apps you signed into","tags":["Accounts"]}},"/v1/me/apps/{app_id}":{"delete":{"description":"The app's tokens for you and the User verification proofs it issued about you are revoked, and the app gets `membership.access_removed`. Signing into the app again restores it.","operationId":"removeAppAccess","parameters":[{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed. Repeating it does nothing more.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"first_party_app","message":"The account site (silicon-accounts) can't lose access (400) or get a short-lived token (422)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `first_party_app`: the account site (`silicon-accounts`) can't lose access (400) or get a short-lived token (422)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["first_party_app","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"membership_not_found","message":"The account never signed into that app."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `membership_not_found`: the account never signed into that app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["membership_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove an app's access","tags":["Accounts"]}},"/v1/me/custodian-requests":{"get":{"description":"Pending requests addressed to your account or any verified email of yours: initial requests from self-created Silicons and transfers. Overdue requests expire the moment they are read.","operationId":"listCustodianRequests","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/CustodianRequest"},"type":"array"}},"type":"object"}]}}},"description":"The requests.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Requests waiting for you","tags":["Silicons"]}},"/v1/me/custodian-requests/{id}/accept":{"post":{"description":"Initial: the Silicon becomes active with you as custodian and gets `silicon.custodian.accepted`. Transfer: you become the custodian; the Silicon gets `silicon.custodian.changed` and its apps `silicon.custodian_changed`.","operationId":"acceptCustodianRequest","parameters":[{"$ref":"#/components/parameters/CustodianRequestId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Accepted.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_not_found","message":"No such request (or not addressed to you)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `custodian_request_not_found`: no such request (or not addressed to you)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_not_pending","details":{"status":"accepted"},"message":"This custodian request was already accepted at 2026-10-07T02:35:00.449Z; only pending requests can be accepted or declined."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `custodian_request_not_pending`: already accepted, declined, expired or cancelled (`details.status`)\n- `silicon_not_pending`: accepting an initial request for a Silicon that is no longer waiting\n- `silicon_not_active`: a transfer of a Silicon that isn't active\n- `already_custodian`: you already are its custodian\n- `transfer_stale`: the custodian changed after the transfer was requested","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_not_pending","silicon_not_pending","silicon_not_active","already_custodian","transfer_stale"]},"410":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_expired","message":"The 14 days ran out."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `custodian_request_expired`: the 14 days ran out","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Accept a custodian request","tags":["Silicons"]}},"/v1/me/custodian-requests/{id}/decline":{"post":{"description":"Initial: the Silicon is released (deleted, id free at once) and gets `silicon.custodian.declined`. Transfer: nothing changes.","operationId":"declineCustodianRequest","parameters":[{"$ref":"#/components/parameters/CustodianRequestId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Declined.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_not_found","message":"No such request (or not addressed to you)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `custodian_request_not_found`: no such request (or not addressed to you)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_not_pending","details":{"status":"accepted"},"message":"This custodian request was already accepted at 2026-10-07T02:35:00.449Z; only pending requests can be accepted or declined."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `custodian_request_not_pending`: already accepted, declined, expired or cancelled (`details.status`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_not_pending"]},"410":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_expired","message":"The 14 days ran out."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `custodian_request_expired`: the 14 days ran out","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_expired"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Decline a custodian request","tags":["Silicons"]}},"/v1/me/emails":{"get":{"description":"Every email address of your account (at most 10), primary first.","operationId":"listMyEmails","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"}},"type":"object"}]}}},"description":"Primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your email addresses","tags":["Accounts"]},"post":{"description":"Sends a 6-digit code; verify it with `POST /v1/me/emails/verify`. Every attempt counts before any refusal (20 per account and 30 per IP per 10 minutes), so the endpoint can't test which addresses have accounts.","operationId":"addMyEmail","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailAdd"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactChallenge"}}},"description":"A code was sent.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"409":{"content":{"application/json":{"example":{"error":{"code":"email_in_use","message":"It belongs to another account; an address belongs to one account only."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `email_in_use`: it belongs to another account; an address belongs to one account only\n- `email_already_added`: it is already on your account\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_in_use","email_already_added","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"email_limit_reached","message":"10 already; remove one first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `email_limit_reached`: 10 already; remove one first\n- `invalid_email`: the email address can't be read (the message says why)\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_limit_reached","invalid_email","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Add an email address","tags":["Accounts"]}},"/v1/me/emails/verify":{"post":{"description":"A new primary (the first of its kind) bumps `version` and sends `account.updated` to apps with that scope.","operationId":"verifyMyEmail","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeVerification"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"}},"type":"object"}]}}},"description":"The updated list, primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"challenge_not_found","message":"Unknown challenge_id (or one of another flow)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `challenge_not_found`: unknown `challenge_id` (or one of another flow)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["challenge_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"code_already_used","message":"This code was already accepted."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `code_already_used`: this code was already accepted\n- `email_in_use`: it belongs to another account; an address belongs to one account only\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_already_used","email_in_use","account_deleted","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"410":{"content":{"application/json":{"example":{"error":{"code":"code_expired","message":"Older than 10 minutes, or replaced by a resend; send a new one."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `code_expired`: older than 10 minutes, or replaced by a resend; send a new one","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_code","details":{"remaining_attempts":9},"message":"That code is wrong; 9 more tries for a***@example.test before a 60 second cooldown."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_code`: wrong code (`details.remaining_attempts` for the address), or not 6 digits (not counted). The 10th wrong one in a row has `remaining_attempts: 0`, `details.locked_until` and `Retry-After`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_code","validation_failed"]},"423":{"$ref":"#/components/responses/Locked"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Verify an added email address","tags":["Accounts"]}},"/v1/me/emails/{email}":{"delete":{"description":"The primary can't be removed: make another one primary first.","operationId":"removeMyEmail","parameters":[{"$ref":"#/components/parameters/EmailPath"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"}},"type":"object"}]}}},"description":"The updated list, primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"email_not_found","message":"Not on your account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `email_not_found`: not on your account","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"cannot_remove_primary","message":"Make another address primary first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `cannot_remove_primary`: make another address primary first","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["cannot_remove_primary"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove an email address","tags":["Accounts"]}},"/v1/me/emails/{email}/primary":{"post":{"description":"Only a verified address can be primary. Apps with the `email` scope get `account.updated`.","operationId":"setPrimaryEmail","parameters":[{"$ref":"#/components/parameters/EmailPath"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Email"},"type":"array"}},"type":"object"}]}}},"description":"The updated list, primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"email_not_found","message":"Not on your account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `email_not_found`: not on your account","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"email_not_verified","message":"Only a verified address can be primary."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `email_not_verified`: only a verified address can be primary","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["email_not_verified"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Make an email address primary","tags":["Accounts"]}},"/v1/me/history":{"get":{"description":"Everything that happened to the account, newest first. Rows written by someone else mask contact details and show `meta.ip: null`.","operationId":"listMyHistory","parameters":[{"description":"Only this kind.","in":"query","name":"kind","required":false,"schema":{"enum":["signin","id_change","custodian","proof","app_access","security"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/HistoryItem"},"type":"array"}},"type":"object"}]}}},"description":"History rows.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_history_kind","message":"kind isn't signin, id_change, custodian, proof, app_access or security."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_history_kind`: `kind` isn't `signin`, `id_change`, `custodian`, `proof`, `app_access` or `security`\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does\n- `invalid_query`: a query parameter is missing, has the wrong type or an unknown value (named)\n- `invalid_cursor`: `cursor` isn't a `next_cursor` from this list; pass it unchanged or omit it","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_history_kind","unsupported_version","invalid_query","invalid_cursor"]},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your account's history","tags":["Accounts"]}},"/v1/me/id":{"post":{"description":"The old id is reserved for you for 10 days. Apps get `account.id_changed` (they key on the uuid, so nothing breaks). At most 5 id changes per account in any 24 hours.","operationId":"changeMyId","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdChange"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}},"description":"Your account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"content":{"application/json":{"example":{"error":{"code":"id_taken","details":{"suggestions":["c:saket-2","c:saket-3","c:saket-4"]},"hint":"Pick another id, for example c:saket-2, c:saket-3, c:saket-4.","message":"c:saket is taken by another account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `id_taken`: another account has it; `details.suggestions` lists free ones\n- `id_reserved`: it was changed away from recently and is held for 10 days (`details.reserved_until`)\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["id_taken","id_reserved","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_id","message":"Not a valid c:/si: id, or the wrong kind; details.reason is invalid or reserved_word."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_id","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Change your id","tags":["Accounts"]}},"/v1/me/identities":{"get":{"description":"The Google and Apple accounts linked to your account. Linking happens in the browser, with POST /v1/me/identities/{provider}.","operationId":"listMyIdentities","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/LinkedIdentity"},"type":"array"}},"type":"object"}]}}},"description":"The linked identities.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your linked Google and Apple accounts","tags":["Accounts"]}},"/v1/me/identities/{provider}":{"post":{"description":"The account site's \"Connect Google\". Needs the browser session, not a token, because the provider sends that browser back. The callback links the account, adds its verified email without a code, and redirects to `return_to?linked=google&email_added=true|false` (or `?link_error=...`). 30 per account per hour.","operationId":"linkIdentity","parameters":[{"$ref":"#/components/parameters/Provider"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityLinkStart"}}},"required":false},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityLink"}}},"description":"Where to send the browser.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Set-Cookie":{"description":"`sa_flow=saf_...; HttpOnly; SameSite=Lax; Path=/; Max-Age=3600` (`__Host-sa_flow` in production).","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"browser_session_required","message":"Linking Google/Apple needs the account site's browser session, not a token."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `browser_session_required`: linking Google/Apple needs the account site's browser session, not a token\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["browser_session_required","invalid_json","invalid_content_type","unsupported_version"]},"401":{"$ref":"#/components/responses/CookieUnauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"method_not_enabled","message":"The app didn't enable that method (or no managed credentials exist)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `method_not_enabled`: the app didn't enable that method (or no managed credentials exist)\n- `carbon_only`: a Silicon called an endpoint for Carbons (emails, phones, custodian side…)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["method_not_enabled","carbon_only","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_provider","message":"The provider in the URL isn't google or apple."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `unknown_provider`: the provider in the URL isn't `google` or `apple`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_provider"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"sessionCookie":[]}],"summary":"Connect Google or Apple to your account","tags":["Sign-in"]}},"/v1/me/identities/{provider}/{subject}":{"delete":{"description":"Refused when it would leave no way to sign in (no email or phone).","operationId":"unlinkIdentity","parameters":[{"$ref":"#/components/parameters/Provider"},{"description":"The provider's account id, as `GET /v1/me/identities` lists it.","in":"path","name":"subject","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_provider","message":"The provider isn't google or apple."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_provider`: the provider isn't `google` or `apple`\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_provider","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"identity_not_found","message":"No such linked identity."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `identity_not_found`: no such linked identity","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["identity_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"last_sign_in_method","message":"Removing it would leave no way to sign in (no email or phone)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `last_sign_in_method`: removing it would leave no way to sign in (no email or phone)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["last_sign_in_method"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove a linked identity","tags":["Accounts"]}},"/v1/me/identity-tokens":{"post":{"description":"A signed-in Silicon gets an OpenID Connect ID token for one audience its custodian allows: AWS STS (`sts.amazonaws.com`), a Google Cloud workload identity provider, Microsoft Entra (`api://AzureADTokenExchange`). It is an RS256 JWT signed with this service's identity-token key (in `/.well-known/jwks.json` with its own `kid`), with `iss` (the public URL), `sub` (the Silicon's uuid), `aud`, `iat`, `nbf`, `exp`, `jti`, `kind: silicon`, `si_id`, `custodian` (the custodian's uuid) and `token_use: identity`. This API never accepts it as a bearer token (401 `identity_token_not_accepted`). Lives 60 to 3600 seconds (default 300). Each one is recorded in the Silicon's and the custodian's history (never the token). 60 per minute per Silicon.","operationId":"issueIdentityToken","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityTokenRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityToken"}}},"description":"The token.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"audience_not_allowed","message":"The Silicon's custodian hasn't allowed this audience (`details.allowed_audiences`)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `audience_not_allowed`: the Silicon's custodian hasn't allowed this audience (`details.allowed_audiences`)\n- `silicon_only`: a Carbon asked; identity tokens prove Silicons\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["audience_not_allowed","silicon_only","account_not_active","origin_not_allowed"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Get an identity token for an outside service","tags":["Silicons"]}},"/v1/me/owned-apps":{"get":{"description":"Newest first.","operationId":"listOwnedApps","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/OwnedApp"},"type":"array"}},"type":"object"}]}}},"description":"Your apps.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Apps you own or author","tags":["Apps"]}},"/v1/me/phones":{"get":{"description":"Every phone number of your account (at most 10), primary first.","operationId":"listMyPhones","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Phone"},"type":"array"}},"type":"object"}]}}},"description":"Primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your phone numbers","tags":["Accounts"]},"post":{"description":"Sends a 6-digit code by text message; verify it with `POST /v1/me/phones/verify`. Same limits as emails.","operationId":"addMyPhone","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhoneAdd"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactChallenge"}}},"description":"A code was sent.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"409":{"content":{"application/json":{"example":{"error":{"code":"phone_in_use","message":"It belongs to another account; an address belongs to one account only."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `phone_in_use`: it belongs to another account; an address belongs to one account only\n- `phone_already_added`: it is already on your account\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["phone_in_use","phone_already_added","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"phone_limit_reached","message":"10 already; remove one first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `phone_limit_reached`: 10 already; remove one first\n- `invalid_phone`: the phone number can't be read (the message says why)\n- `invalid_country`: `country` isn't an ISO 3166 country code\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["phone_limit_reached","invalid_phone","invalid_country","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Add a phone number","tags":["Accounts"]}},"/v1/me/phones/verify":{"post":{"description":"A new primary (the first of its kind) bumps `version` and sends `account.updated` to apps with the `phone` scope. 10 wrong codes in a row lock the number for 60 seconds.","operationId":"verifyMyPhone","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeVerification"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Phone"},"type":"array"}},"type":"object"}]}}},"description":"The updated list, primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"challenge_not_found","message":"Unknown challenge_id (or one of another flow)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `challenge_not_found`: unknown `challenge_id` (or one of another flow)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["challenge_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"code_already_used","message":"This code was already accepted."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `code_already_used`: this code was already accepted\n- `phone_in_use`: it belongs to another account; an address belongs to one account only\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_already_used","phone_in_use","account_deleted","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"410":{"content":{"application/json":{"example":{"error":{"code":"code_expired","message":"Older than 10 minutes, or replaced by a resend; send a new one."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `code_expired`: older than 10 minutes, or replaced by a resend; send a new one","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["code_expired"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_code","details":{"remaining_attempts":9},"message":"That code is wrong; 9 more tries for a***@example.test before a 60 second cooldown."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_code`: wrong code (`details.remaining_attempts` for the address), or not 6 digits (not counted). The 10th wrong one in a row has `remaining_attempts: 0`, `details.locked_until` and `Retry-After`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_code","validation_failed"]},"423":{"$ref":"#/components/responses/Locked"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Verify an added phone number","tags":["Accounts"]}},"/v1/me/phones/{phone}":{"delete":{"description":"The primary can't be removed: make another one primary first.","operationId":"removeMyPhone","parameters":[{"$ref":"#/components/parameters/PhonePath"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Phone"},"type":"array"}},"type":"object"}]}}},"description":"The updated list, primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"phone_not_found","message":"Not on your account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `phone_not_found`: not on your account","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["phone_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"cannot_remove_primary","message":"Make another address primary first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `cannot_remove_primary`: make another address primary first","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["cannot_remove_primary"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove a phone number","tags":["Accounts"]}},"/v1/me/phones/{phone}/primary":{"post":{"description":"Only a verified number can be primary. Apps with the `phone` scope get `account.updated`.","operationId":"setPrimaryPhone","parameters":[{"$ref":"#/components/parameters/PhonePath"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Phone"},"type":"array"}},"type":"object"}]}}},"description":"The updated list, primary first.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"phone_not_found","message":"Not on your account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `phone_not_found`: not on your account","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["phone_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"phone_not_verified","message":"Only a verified address can be primary."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `phone_not_verified`: only a verified address can be primary","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["phone_not_verified"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Make a phone number primary","tags":["Accounts"]}},"/v1/me/photo":{"delete":{"description":"The default photo is drawn by Iris from the uuid. Apps that see `profile` get `account.updated`.","operationId":"deleteMyPhoto","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}},"description":"Your account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Back to the default photo","tags":["Accounts"]},"post":{"description":"20 uploads per account per hour. Apps that see `profile` get `account.updated`.","operationId":"uploadMyPhoto","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"image/gif":{"schema":{"format":"binary","type":"string"}},"image/jpeg":{"schema":{"format":"binary","type":"string"}},"image/png":{"schema":{"format":"binary","type":"string"}},"image/webp":{"schema":{"format":"binary","type":"string"}}},"description":"The raw image with its Content-Type (`image/jpg` works too): at most 2 MB, 8192 px a side, 50 megapixels; the bytes must really be that format.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MePhotoUpload"}}},"description":"Uploaded and set.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"content":{"application/json":{"example":{"error":{"code":"photo_too_large","message":"Over 2 MB."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Payload too large.\n\n- `photo_too_large`: over 2 MB\n- `payload_too_large`: the body is over the route's limit (`details.limit_bytes`: 64 KB by default)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["photo_too_large","payload_too_large"]},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"content":{"application/json":{"example":{"error":{"code":"empty_photo","message":"An empty body."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `empty_photo`: an empty body\n- `invalid_image`: the bytes aren't a readable PNG, JPEG, WebP or GIF\n- `photo_type_mismatch`: the bytes are another format than `Content-Type` says (`details.detected_content_type`)\n- `photo_dimensions_too_large`: over 8192 px a side or 50 megapixels","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["empty_photo","invalid_image","photo_type_mismatch","photo_dimensions_too_large"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Upload your profile photo","tags":["Accounts"]}},"/v1/me/proofs":{"get":{"description":"Newest first. Unknown query parameters are refused.","operationId":"listMyProofs","parameters":[{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["active","revoked","expired"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/MyProof"},"type":"array"}},"type":"object"}]}}},"description":"Proofs.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"User verification proofs about you","tags":["Proofs"]}},"/v1/me/proofs/{proof_id}":{"delete":{"description":"The receiving app's next verification answers `valid: false`.","operationId":"revokeMyProof","parameters":[{"$ref":"#/components/parameters/ProofId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Revoked.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_proof_id","message":"Not a UUID."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_proof_id`: not a UUID\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_proof_id","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"proof_not_found","message":"Not a proof you can see."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `proof_not_found`: not a proof you can see","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["proof_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Revoke a proof about you","tags":["Proofs"]}},"/v1/me/sessions":{"get":{"description":"Browser sessions, CLI sign-ins (code, device, Silicon login) and developer-platform sign-ins, newest first. `current` marks the session making the request.","operationId":"listMySessions","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/SessionItem"},"type":"array"}},"type":"object"}]}}},"description":"Your sessions.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your sessions and first-party sign-ins","tags":["Accounts"]}},"/v1/me/sessions/{id}":{"delete":{"description":"That browser, CLI or developer-platform sign-in ends at once. An app's sign-in is removed with `DELETE /v1/me/apps/{app_id}` instead.","operationId":"revokeMySession","parameters":[{"description":"The session's id, as `GET /v1/me/sessions` lists it.","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Signed out.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"session_not_found","message":"Not a session of yours (an app's sign-in is removed with DELETE /v1/me/apps/{app_id})."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `session_not_found`: not a session of yours (an app's sign-in is removed with `DELETE /v1/me/apps/{app_id}`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["session_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Sign a session out","tags":["Accounts"]}},"/v1/me/short-lived-tokens":{"post":{"description":"How a Silicon (or a Carbon) signs into an app without its sign-in page: hand the `slt` to the app, which redeems it at `POST /v1/oauth/token`. Single use, 120 seconds, only at that app. A token minted by a sign-in from a trusted outside token (a CI job) carries that sign-in's end and trust: the app sign-in it starts ends no later than the CI sign-in, and removing the trust ends it.","operationId":"createShortLivedToken","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLivedTokenRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortLivedToken"}}},"description":"The token.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"app_disabled","message":"The app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `app_disabled`: the app is disabled\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `email_domain_not_allowed`: the app accepts only some email domains\n- `app_not_allowed`: the Silicon's custodian only lets it get short-lived tokens for the apps in `details.allowed_apps`\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_disabled","account_not_active","email_domain_not_allowed","app_not_allowed","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_app","message":"No app has this app_id."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_app"]},"409":{"content":{"application/json":{"example":{"error":{"code":"requirements_missing","details":{"missing":["phone"]},"message":"DM requires your phone number, which your account doesn't have yet."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `requirements_missing`: the app requires a detail the account lacks (`details.missing`); add it, then retry","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["requirements_missing"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"first_party_app","message":"The account site (silicon-accounts) can't lose access (400) or get a short-lived token (422)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `first_party_app`: the account site (`silicon-accounts`) can't lose access (400) or get a short-lived token (422)\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["first_party_app","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"A short-lived token for an app","tags":["Silicons"]}},"/v1/me/silicons":{"get":{"description":"Each Silicon as its custodian sees it, with any pending transfer.","operationId":"listMySilicons","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/SiliconView"},"type":"array"}},"type":"object"}]}}},"description":"Your Silicons.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Silicons you are custodian of","tags":["Silicons"]},"post":{"description":"Active at once. The STK and webhook secret are shown once (a retry with the same Idempotency-Key within 10 minutes returns the same ones).","operationId":"createSilicon","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconCreated"}}},"description":"Created.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"409":{"content":{"application/json":{"example":{"error":{"code":"id_taken","details":{"suggestions":["c:saket-2","c:saket-3","c:saket-4"]},"hint":"Pick another id, for example c:saket-2, c:saket-3, c:saket-4.","message":"c:saket is taken by another account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `id_taken`: another account has it; `details.suggestions` lists free ones\n- `id_reserved`: it was changed away from recently and is held for 10 days (`details.reserved_until`)\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["id_taken","id_reserved","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_id","message":"Not a valid c:/si: id, or the wrong kind; details.reason is invalid or reserved_word."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_id","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Create a Silicon with you as custodian","tags":["Silicons"]}},"/v1/me/silicons/{uuid}":{"delete":{"description":"Same effects as deleting an account. The Silicon's webhook is kept so events already queued still arrive.","operationId":"deleteMySilicon","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteConfirmation"}}},"required":true},"responses":{"204":{"description":"Deleted.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"confirmation_required","message":"DELETE needs {\"confirm\": \"<current id>\"}."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `confirmation_required`: `DELETE` needs `{\"confirm\": \"<current id>\"}`\n- `confirmation_mismatch`: `confirm` isn't the account's current id; nothing was deleted\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["confirmation_required","confirmation_mismatch","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Delete a Silicon","tags":["Silicons"]},"get":{"description":"The Silicon's account plus `pending_transfer`. Other Carbons' Silicons are never revealed (404).","operationId":"getMySilicon","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconView"}}},"description":"The Silicon.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One of your Silicons","tags":["Silicons"]},"patch":{"description":"The Silicon's webhook gets `silicon.updated`; apps that see a changed field get `account.updated`.","operationId":"updateMySilicon","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconUpdate"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconView"}}},"description":"The Silicon.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"dob_immutable","message":"A Silicon's date of birth is its creation day."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `dob_immutable`: a Silicon's date of birth is its creation day\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["dob_immutable","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Change a Silicon's profile","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/allowed-apps":{"get":{"operationId":"getSiliconAllowedApps","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowedApps"}}},"description":"The allow-list.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The apps a Silicon may get short-lived tokens for","tags":["Silicons"]},"put":{"description":"`null` allows every app; a list only those (an empty list none). Other apps get 403 `app_not_allowed` at `POST /v1/me/short-lived-tokens`. Sign-ins the Silicon already has stay.","operationId":"setSiliconAllowedApps","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowedAppsSet"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowedApps"}}},"description":"The allow-list.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once\n- `unknown_app`: no app has this app_id","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed","unknown_app"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Limit the apps a Silicon may get short-lived tokens for","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/apps":{"get":{"description":"Its memberships, most recently used first. `{uuid}` takes the si:id too.","operationId":"listSiliconApps","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"description":"`active`, `access_removed` or `imported`.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/SiliconApp"},"type":"array"}},"type":"object"}]}}},"description":"The apps.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The apps a Silicon signed into","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/apps/{app_id}":{"delete":{"description":"Its sign-ins at the app end, the User verification proofs about it are revoked, and the app gets `membership.access_removed`. Repeating it changes nothing.","operationId":"removeSiliconApp","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AppId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"first_party_app","message":"The account site (silicon-accounts) can't lose access (400) or get a short-lived token (422)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `first_party_app`: the account site (`silicon-accounts`) can't lose access (400) or get a short-lived token (422)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["first_party_app","unsupported_version"]},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)\n- `membership_not_found`: the account never signed into that app","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found","membership_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove a Silicon's access to an app","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/id":{"post":{"description":"Same rules as `POST /v1/me/id`: the old id is reserved for the Silicon for 10 days, at most 5 changes per 24 hours.","operationId":"changeSiliconId","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdChange"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconView"}}},"description":"The Silicon.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"id_taken","details":{"suggestions":["c:saket-2","c:saket-3","c:saket-4"]},"hint":"Pick another id, for example c:saket-2, c:saket-3, c:saket-4.","message":"c:saket is taken by another account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `id_taken`: another account has it; `details.suggestions` lists free ones\n- `id_reserved`: it was changed away from recently and is held for 10 days (`details.reserved_until`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["id_taken","id_reserved"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_id","message":"Not a valid c:/si: id, or the wrong kind; details.reason is invalid or reserved_word."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_id","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Change a Silicon's id","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/photo":{"post":{"description":"Same rules as POST /v1/me/photo: PNG, JPEG, WebP or GIF, at most 2 MB, 20 uploads per hour.","operationId":"uploadSiliconPhoto","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"image/gif":{"schema":{"format":"binary","type":"string"}},"image/jpeg":{"schema":{"format":"binary","type":"string"}},"image/png":{"schema":{"format":"binary","type":"string"}},"image/webp":{"schema":{"format":"binary","type":"string"}}},"description":"The raw image with its Content-Type (`image/jpg` works too): at most 2 MB, 8192 px a side, 50 megapixels; the bytes must really be that format.","required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconPhotoUpload"}}},"description":"Uploaded and set.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"409":{"$ref":"#/components/responses/Conflict"},"413":{"content":{"application/json":{"example":{"error":{"code":"photo_too_large","message":"Over 2 MB."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Payload too large.\n\n- `photo_too_large`: over 2 MB\n- `payload_too_large`: the body is over the route's limit (`details.limit_bytes`: 64 KB by default)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["photo_too_large","payload_too_large"]},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"422":{"content":{"application/json":{"example":{"error":{"code":"empty_photo","message":"An empty body."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `empty_photo`: an empty body\n- `invalid_image`: the bytes aren't a readable PNG, JPEG, WebP or GIF\n- `photo_type_mismatch`: the bytes are another format than `Content-Type` says (`details.detected_content_type`)\n- `photo_dimensions_too_large`: over 8192 px a side or 50 megapixels","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["empty_photo","invalid_image","photo_type_mismatch","photo_dimensions_too_large"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Upload a Silicon's photo","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/signins":{"get":{"description":"Newest first: the app, the method, the outcome, the address.","operationId":"listSiliconSignins","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/SiliconSignin"},"type":"array"}},"type":"object"}]}}},"description":"The sign-ins.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"A Silicon's sign-ins","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/stk":{"post":{"description":"`{}` generates one; `{\"stk\": \"stk-...\"}` sets yours. The old STK dies at once and every sign-in of the Silicon ends: its tokens answer 401 `token_revoked`, apps get `membership.signed_out` (`stk_rotated`), and the Silicon's webhook gets `silicon.stk_rotated`.","operationId":"rotateSiliconStk","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StkRotate"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StkRotation"}}},"description":"Rotated.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Rotate a Silicon's STK","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/transfer":{"delete":{"description":"The Silicon stays with you.","operationId":"cancelSiliconTransfer","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Cancelled.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)\n- `transfer_not_found`: no pending transfer to cancel","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found","transfer_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Cancel the pending transfer","tags":["Silicons"]},"post":{"description":"Nothing changes until they accept (14 days). One pending transfer at a time; 30 transfer requests per custodian per hour.","operationId":"requestSiliconTransfer","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustodianRequestEnvelope"}}},"description":"Requested.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)\n- `custodian_not_found`: no active Carbon has the c:id named as custodian or transfer target; name them by email instead","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found","custodian_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"transfer_pending","details":{"request_id":"01a11436-bf74-74fa-a716-6e431d8a9ed6"},"message":"One transfer at a time (details.request_id): cancel it first."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `transfer_pending`: one transfer at a time (`details.request_id`): cancel it first","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["transfer_pending"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"transfer_to_self","message":"A transfer must go to another Carbon."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `transfer_to_self`: a transfer must go to another Carbon\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["transfer_to_self","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Ask another Carbon to become custodian","tags":["Silicons"]}},"/v1/me/silicons/{uuid}/webhook":{"delete":{"description":"The Silicon stops getting events.","operationId":"removeSiliconWebhook","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove a Silicon's webhook (custodian)","tags":["Webhooks"]},"put":{"description":"A new secret each time, shown once.","operationId":"setSiliconWebhook","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUrl"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconWebhookSecret"}}},"description":"The webhook and its new secret.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Set a Silicon's webhook (custodian)","tags":["Webhooks"]}},"/v1/me/silicons/{uuid}/webhook/deliveries":{"get":{"description":"Newest first: the same list and fields as GET /v1/me/webhook/deliveries. After a transfer the new custodian has the deliveries.","operationId":"listSiliconWebhookDeliveries","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["pending","delivered","failed"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookDelivery"},"type":"array"}},"type":"object"}]}}},"description":"Deliveries.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"A Silicon's webhook deliveries (custodian)","tags":["Webhooks"]}},"/v1/me/silicons/{uuid}/webhook/deliveries/{id}":{"get":{"description":"Every attempt and the exact payload that was signed.","operationId":"getSiliconWebhookDelivery","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/SiliconDeliveryId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}}},"description":"The delivery.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)\n- `delivery_not_found`: no such webhook delivery for this app, or for this Silicon (`/v1/me/webhook/deliveries…`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found","delivery_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One of a Silicon's deliveries (custodian)","tags":["Webhooks"]}},"/v1/me/silicons/{uuid}/webhook/replay":{"post":{"description":"Each delivery goes back to pending with the same event_id and payload, to the current URL, signed with the current secret, with a fresh 72 hours of retries. With `status: failed`, call again (new Idempotency-Key) until `remaining` is 0.","operationId":"replaySiliconWebhookDeliveries","parameters":[{"$ref":"#/components/parameters/SiliconRef"},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayResult"}}},"description":"What was replayed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/CarbonOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"webhook_not_set","hint":"Set one first with PUT /v1/apps/{app_id}/webhook {\"url\":\"https://...\"}.","message":"The app 'briefcase' has no webhook URL, so there is nowhere to send events."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `webhook_not_set`: a test ping, secret rotation or replay without a webhook URL: set one first\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["webhook_not_set","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Replay a Silicon's deliveries (custodian)","tags":["Webhooks"]}},"/v1/me/webhook":{"delete":{"description":"The Silicon stops getting events. A delivery that falls due while no URL is set fails at once; replay it after setting one.","operationId":"removeMyWebhook","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed: no more events.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SiliconOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove your webhook (Silicon)","tags":["Webhooks"]},"put":{"description":"A new signing secret every time, shown once. The URL must be https and reach a public address.","operationId":"setMyWebhook","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUrl"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconWebhookSecret"}}},"description":"The webhook and its new secret.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SiliconOnly"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Set your webhook (Silicon)","tags":["Webhooks"]}},"/v1/me/webhook/deliveries":{"get":{"description":"Newest first.","operationId":"listMyWebhookDeliveries","parameters":[{"description":"Only this status.","in":"query","name":"status","required":false,"schema":{"enum":["pending","delivered","failed"],"type":"string"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookDelivery"},"type":"array"}},"type":"object"}]}}},"description":"Deliveries.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SiliconOnly"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Your webhook's deliveries (Silicon)","tags":["Webhooks"]}},"/v1/me/webhook/deliveries/{id}":{"get":{"description":"Every attempt and the exact payload that was signed. Nothing is withheld: every event of a Silicon's webhook is about the Silicon.","operationId":"getMyWebhookDelivery","parameters":[{"$ref":"#/components/parameters/SiliconDeliveryId"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}}},"description":"The delivery.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SiliconOnly"},"404":{"content":{"application/json":{"example":{"error":{"code":"delivery_not_found","message":"No such webhook delivery for this app, or for this Silicon (/v1/me/webhook/deliveries…)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `delivery_not_found`: no such webhook delivery for this app, or for this Silicon (`/v1/me/webhook/deliveries…`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["delivery_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"One delivery with its attempts (Silicon)","tags":["Webhooks"]}},"/v1/me/webhook/replay":{"post":{"description":"Each delivery goes back to pending with the same event_id and payload, to the current URL, signed with the current secret, with a fresh 72 hours of retries. With `status: failed`, call again (new Idempotency-Key) until `remaining` is 0. Test pings are never replayed (`test_ping`).","operationId":"replayMyWebhookDeliveries","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayResult"}}},"description":"What was replayed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SiliconOnly"},"409":{"content":{"application/json":{"example":{"error":{"code":"webhook_not_set","hint":"Set one first with PUT /v1/apps/{app_id}/webhook {\"url\":\"https://...\"}.","message":"The app 'briefcase' has no webhook URL, so there is nowhere to send events."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `webhook_not_set`: a test ping, secret rotation or replay without a webhook URL: set one first\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["webhook_not_set","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Send deliveries again (Silicon)","tags":["Webhooks"]}},"/v1/me/webhook/test":{"post":{"description":"Only the newest test ping is retried. 10 test pings per Silicon per hour.","operationId":"testMyWebhook","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconWebhookTest"}}},"description":"Queued.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/SiliconOnly"},"409":{"content":{"application/json":{"example":{"error":{"code":"webhook_not_set","hint":"Set one first with PUT /v1/apps/{app_id}/webhook {\"url\":\"https://...\"}.","message":"The app 'briefcase' has no webhook URL, so there is nowhere to send events."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `webhook_not_set`: a test ping, secret rotation or replay without a webhook URL: set one first","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["webhook_not_set"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Send yourself a test ping (Silicon)","tags":["Webhooks"]}},"/v1/meta":{"get":{"description":"Check it first when something answers unexpectedly.","operationId":"getMeta","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Meta"}}},"description":"The deployment.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Which deployment answered","tags":["Service"]}},"/v1/oauth/callback/{provider}":{"get":{"description":"Where Google and Apple send the browser back (register this URL with the provider when you bring your own credentials). Verifies the provider's answer and redirects to the flow's page; the next `GET /v1/flows/{id}` claims the outcome. Failures land on the flow as `error.code`.","operationId":"providerCallback","parameters":[{"$ref":"#/components/parameters/Provider"},{"description":"The provider's authorization code.","in":"query","name":"code","required":false,"schema":{"type":"string"}},{"description":"The state Silicon Accounts sent.","in":"query","name":"state","required":false,"schema":{"type":"string"}},{"description":"The provider's error.","in":"query","name":"error","required":false,"schema":{"type":"string"}},{"description":"The provider's error text.","in":"query","name":"error_description","required":false,"schema":{"type":"string"}},{"description":"Apple's form_post answer, carried over by the 303 of the POST.","in":"query","name":"ticket","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"302":{"description":"To `{PUBLIC_URL}/authorize/flow/{flow_id}`.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Location":{"description":"The flow's page.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_state","message":"A provider callback with a malformed state."}},"schema":{"$ref":"#/components/schemas/Error"}},"text/html":{"schema":{"type":"string"}}},"description":"A malformed `state`. Shown as a page (text/html) unless the request accepts JSON.\n\n- `invalid_state`: a provider callback with a malformed `state`\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_state","unsupported_version"]},"403":{"content":{"application/json":{"example":{"error":{"code":"flow_not_bound","message":"The request lacks this flow's sa_flow cookie: continue in the browser that started it."}},"schema":{"$ref":"#/components/schemas/Error"}},"text/html":{"schema":{"type":"string"}}},"description":"The answer came to another browser than the one that started the sign-in; it is discarded. Shown as a page unless the request accepts JSON.\n\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_bound"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_provider","message":"The provider in the URL isn't google or apple."}},"schema":{"$ref":"#/components/schemas/Error"}},"text/html":{"schema":{"type":"string"}}},"description":"The provider isn't google or apple. Shown as a page unless the request accepts JSON.\n\n- `unknown_provider`: the provider in the URL isn't `google` or `apple`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_provider"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Google or Apple returns here","tags":["Sign-in"]},"post":{"description":"Apple's `form_post` is a cross-site POST without cookies, so it is answered 303 to `GET /v1/oauth/callback/apple?ticket=...`, a same-site request that carries the binding cookie.","operationId":"providerCallbackPost","parameters":[{"$ref":"#/components/parameters/Provider"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"properties":{"code":{"type":"string"},"error":{"type":"string"},"id_token":{"type":"string"},"state":{"type":"string"},"user":{"type":"string"}},"type":"object"}}},"required":true},"responses":{"303":{"description":"To `GET /v1/oauth/callback/{provider}?ticket=...`.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Location":{"description":"The same-site callback URL.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_state","message":"A provider callback with a malformed state."}},"schema":{"$ref":"#/components/schemas/Error"}},"text/html":{"schema":{"type":"string"}}},"description":"A malformed `state`. Shown as a page (text/html) unless the request accepts JSON.\n\n- `invalid_state`: a provider callback with a malformed `state`\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_state","unsupported_version"]},"403":{"content":{"application/json":{"example":{"error":{"code":"flow_not_bound","message":"The request lacks this flow's sa_flow cookie: continue in the browser that started it."}},"schema":{"$ref":"#/components/schemas/Error"}},"text/html":{"schema":{"type":"string"}}},"description":"The answer came to another browser than the one that started the sign-in; it is discarded. Shown as a page unless the request accepts JSON.\n\n- `flow_not_bound`: the request lacks this flow's `sa_flow` cookie: continue in the browser that started it","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["flow_not_bound"]},"404":{"content":{"application/json":{"example":{"error":{"code":"unknown_provider","message":"The provider in the URL isn't google or apple."}},"schema":{"$ref":"#/components/schemas/Error"}},"text/html":{"schema":{"type":"string"}}},"description":"The provider isn't google or apple. Shown as a page unless the request accepts JSON.\n\n- `unknown_provider`: the provider in the URL isn't `google` or `apple`","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_provider"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"flowCookie":[]}],"summary":"Apple's form_post returns here","tags":["Sign-in"]}},"/v1/oauth/introspect":{"post":{"description":"Needs the app's own credentials (the public clients get 401 `invalid_client`). Only the calling app's tokens are ever reported active. Use it when you must know about a sign-out at once; a local JWT check can't see revocation.","operationId":"introspectToken","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntrospectRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/IntrospectRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Introspection"}}},"description":"The token's state.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/OAuthBadRequest"},"401":{"$ref":"#/components/responses/OAuthInvalidClient"},"413":{"$ref":"#/components/responses/OAuthPayloadTooLarge"},"500":{"$ref":"#/components/responses/OAuthServerError"},"503":{"$ref":"#/components/responses/OAuthUnavailable"}},"security":[{"oauthClient":[]}],"summary":"Is this token live (RFC 7662)","tags":["OAuth and OIDC"]}},"/v1/oauth/revoke":{"post":{"description":"Ends the sign-in behind a refresh or access token: the whole token family is revoked, and the app gets `membership.signed_out` (`app_revoked`). Always 200 once the client is authenticated.","operationId":"revokeToken","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/RevokeRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeResult"}}},"description":"Revoked, or nothing to revoke.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/OAuthBadRequest"},"401":{"$ref":"#/components/responses/OAuthInvalidClient"},"413":{"$ref":"#/components/responses/OAuthPayloadTooLarge"},"500":{"$ref":"#/components/responses/OAuthServerError"},"503":{"$ref":"#/components/responses/OAuthUnavailable"}},"security":[{"oauthClient":[]}],"summary":"Revoke a sign-in (RFC 7009)","tags":["OAuth and OIDC"]}},"/v1/oauth/token":{"post":{"description":"Exchange an authorization code, refresh a sign-in, redeem a Silicon's short-lived token, poll a device code, sign a Silicon in with a key-signed assertion (jwt-bearer, client_id silicon-accounts), or sign a Silicon in with an outside OIDC token it is trusted for (token-exchange, RFC 8693: `subject_token`, `subject_token_type`, `silicon`; `client_id` may be left out). A token exchange checks the token's signature against its issuer's JWKS, `iss`, `aud`, `exp`, `nbf`, `iat` (30 seconds of skew) and one trust's every condition, uses its `jti` once, and answers a sign-in that ends when the outside token expires, at least 30 minutes and at most 12 hours later (`TokenExchangeResponse`); every refusal is `invalid_grant` with the reason, the code in brackets (`invalid_federated_token`, `no_matching_trust`, `issuer_unavailable`), and 60 exchanges per minute per address answer 429 `rate_limited` with `Retry-After`. jwt-bearer shares the limit of `POST /v1/silicons/login`: 60 Silicon sign-in attempts per minute per address across both, then 429 `rate_limited` with `Retry-After`. A short-lived token minted by a sign-in from an outside token starts an app sign-in that ends no later than that sign-in (`refresh_token_expires_at`) and ends when its trust is removed; once the trust is removed or that sign-in has ended, the token is refused with `invalid_grant`. Authenticate with HTTP Basic or `client_id` + `client_secret` in the body, never both. Public clients send `client_id` alone: `silicon-accounts` (the CLI: refresh_token, device_code, jwt-bearer), `developer` (authorization_code with PKCE S256, refresh_token), and apps that turned on `device_flow` (device_code, refresh_token) or `public_client` (authorization_code with PKCE S256, slt, refresh_token). Every other app sends its secret to redeem a short-lived token. Every refresh rotates the refresh token; presenting a used one revokes the whole sign-in. Responses are `Cache-Control: no-store`.","operationId":"exchangeToken","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/TokenResponse"},{"$ref":"#/components/schemas/TokenExchangeResponse"}]}}},"description":"Tokens (a token exchange also says `issued_token_type`).","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/OAuthBadRequest"},"401":{"$ref":"#/components/responses/OAuthInvalidClient"},"413":{"$ref":"#/components/responses/OAuthPayloadTooLarge"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}},"description":"Too many token exchanges (60 per minute), or too many Silicon sign-in attempts (jwt-bearer: 60 per minute, shared with `POST /v1/silicons/login`), from this address. `{\"error\":\"rate_limited\",\"error_description\"}` with `Retry-After`.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"500":{"$ref":"#/components/responses/OAuthServerError"},"503":{"$ref":"#/components/responses/OAuthUnavailable"}},"security":[{"oauthClient":[]}],"summary":"Token endpoint (every grant)","tags":["OAuth and OIDC"]}},"/v1/openapi.json":{"get":{"description":"The OpenAPI 3.1 description of the whole API, served verbatim. Cacheable for 5 minutes.","operationId":"getOpenApiDocumentV1","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"The OpenAPI document.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`public, max-age=300`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"This OpenAPI document","tags":["Discovery"]}},"/v1/photos/{id}":{"get":{"description":"Immutable and cacheable for a year, with an `ETag` (304 on `If-None-Match`).","operationId":"getPhoto","parameters":[{"description":"The photo's id.","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"description":"An ETag you have.","in":"header","name":"If-None-Match","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"image/gif":{"schema":{"format":"binary","type":"string"}},"image/jpeg":{"schema":{"format":"binary","type":"string"}},"image/png":{"schema":{"format":"binary","type":"string"}},"image/webp":{"schema":{"format":"binary","type":"string"}}},"description":"The image.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Cache-Control":{"description":"`public, max-age=31536000, immutable`.","schema":{"type":"string"}},"ETag":{"description":"The photo's entity tag.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"304":{"description":"Not modified.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"content":{"application/json":{"example":{"error":{"code":"photo_not_found","message":"No such photo (or it was removed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `photo_not_found`: no such photo (or it was removed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["photo_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"An uploaded photo","tags":["Accounts"]}},"/v1/proofs/app-verification":{"post":{"description":"A proof of your app's identity for exactly one receiving app; issue one per app.","operationId":"issueAppVerification","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppVerificationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedProof"}}},"description":"The proof.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"unknown_receiving_app","message":"The receiving app doesn't exist (details.app_ids)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `unknown_receiving_app`: the receiving app doesn't exist (`details.app_ids`)\n- `invalid_receiving_app`: the issuer itself, or Silicon Accounts itself (`silicon-accounts`, `developer`)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unknown_receiving_app","invalid_receiving_app","invalid_json","invalid_content_type","unsupported_version","invalid_idempotency_key"]},"401":{"$ref":"#/components/responses/AppUnauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"receiving_app_disabled","message":"The receiving app is disabled."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `receiving_app_disabled`: the receiving app is disabled\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["receiving_app_disabled","app_disabled"]},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"app_verification_single_app","message":"An app verification request named apps in audiences: an app verification proof is for exactly one app; send {\"receiving_app\": \"…\"} once per app (details.field, details.apps)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `app_verification_single_app`: an app verification request named apps in `audiences`: an app verification proof is for exactly one app; send `{\"receiving_app\": \"…\"}` once per app (`details.field`, `details.apps`)\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["app_verification_single_app","validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]}],"summary":"Prove which app is calling","tags":["Proofs"]}},"/v1/proofs/refresh":{"post":{"description":"The issuing app only. Same proof_id, a new proof_token and a rotated refresh token. Presenting a used refresh token revokes the whole proof.","operationId":"refreshProof","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRefreshRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedProof"}}},"description":"The proof.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_proof_refresh_token","message":"Not a sapr_ token, or unknown (mistyped, another environment, or its proof ended over 30 days ago)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_proof_refresh_token`: not a `sapr_` token, or unknown (mistyped, another environment, or its proof ended over 30 days ago)\n- `proof_refresh_token_reused`: a used refresh token was presented: the proof is now revoked\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_proof_refresh_token","proof_refresh_token_reused","invalid_json","invalid_content_type","unsupported_version","invalid_idempotency_key"]},"401":{"$ref":"#/components/responses/AppUnauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"not_issuing_app","message":"Only the issuing app refreshes or revokes a proof."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `not_issuing_app`: only the issuing app refreshes or revokes a proof\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["not_issuing_app","app_disabled"]},"409":{"$ref":"#/components/responses/Conflict"},"410":{"content":{"application/json":{"example":{"error":{"code":"proof_expired","message":"Past the proof's lifetime."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Gone.\n\n- `proof_expired`: past the proof's lifetime\n- `proof_revoked`: the proof was revoked, or its User verification sign-in ended (`details.reason`, `revoked_at`)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["proof_expired","proof_revoked"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]}],"summary":"A new proof token","tags":["Proofs"]}},"/v1/proofs/revoke":{"post":{"description":"The issuing app only. Revoking a revoked proof is a no-op.","operationId":"revokeProof","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRevokeRequest"}}},"required":true},"responses":{"204":{"description":"Revoked.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_proof_id","message":"Not a UUID."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_proof_id`: not a UUID\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_proof_id","invalid_json","invalid_content_type","unsupported_version"]},"401":{"$ref":"#/components/responses/AppUnauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"not_issuing_app","message":"Only the issuing app refreshes or revokes a proof."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `not_issuing_app`: only the issuing app refreshes or revokes a proof\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["not_issuing_app","app_disabled"]},"404":{"content":{"application/json":{"example":{"error":{"code":"proof_not_found","message":"Not a proof you can see."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `proof_not_found`: not a proof you can see","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["proof_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]}],"summary":"Revoke a proof you issued","tags":["Proofs"]}},"/v1/proofs/user-verification":{"post":{"description":"Turns an access token your app received for an account into a proof another app can verify. Get the account's consent in your own interface first: Silicon Accounts shows no consent screen for proofs.","operationId":"issueUserVerification","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserVerificationRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedProof"}}},"description":"The proof.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"content":{"application/json":{"example":{"error":{"code":"invalid_subject_token","message":"The subject token isn't a live access token (details.reason: not_an_access_token, invalid, expired, revoked)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request.\n\n- `invalid_subject_token`: the subject token isn't a live access token (`details.reason`: `not_an_access_token`, `invalid`, `expired`, `revoked`)\n- `unknown_receiving_app`: the receiving app doesn't exist (`details.app_ids`)\n- `invalid_receiving_app`: the issuer itself, or Silicon Accounts itself (`silicon-accounts`, `developer`)\n- `invalid_json`: the body isn't valid JSON (line and column given)\n- `invalid_content_type`: a body was sent without `Content-Type: application/json` (or, for imports, `text/csv`)\n- `unsupported_version`: the `Accounts-Version` header names a version this server doesn't serve; `details.supported` lists the versions it does\n- `invalid_idempotency_key`: `Idempotency-Key` isn't 1 to 200 visible ASCII characters (no spaces)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_subject_token","unknown_receiving_app","invalid_receiving_app","invalid_json","invalid_content_type","unsupported_version","invalid_idempotency_key"]},"401":{"$ref":"#/components/responses/AppUnauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"subject_token_wrong_app","details":{"token_app":"dm"},"message":"subject_token was issued to the app 'dm', but 'briefcase' is asking for the proof."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `subject_token_wrong_app`: the subject token belongs to another app (`details.token_app`)\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `membership_inactive`: the account has no active membership with your app\n- `receiving_app_disabled`: the receiving app is disabled\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["subject_token_wrong_app","account_not_active","membership_inactive","receiving_app_disabled","app_disabled"]},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]}],"summary":"Prove which account your app acts for","tags":["Proofs"]}},"/v1/proofs/verify":{"post":{"description":"Called by the receiving app. Always 200: valid, or exactly `{\"valid\": false, \"expires_at\": null}`, so a caller learns nothing about proofs that aren't theirs. A malformed input adds an `x-accounts-hint` header describing it.","operationId":"verifyProof","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofVerifyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofVerification"}}},"description":"Valid or not.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"x-accounts-hint":{"description":"Only for a malformed input: what it looks like instead (for example a proof refresh token).","schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AppUnauthorized"},"403":{"$ref":"#/components/responses/AppDisabled"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appBasic":[]}],"summary":"Check a proof token you received","tags":["Proofs"]}},"/v1/reports":{"post":{"description":"Emailed to the Silicon Accounts maintainers, optionally with the pull request that fixes it. Signed-in reports name the account. 5 reports per IP per hour.","operationId":"createReport","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Report"}}},"description":"Queued.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{},{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Report a bug","tags":["Service"]}},"/v1/session":{"get":{"description":"The browser's signed-in account and its session. Cookie only: with a token, use GET /v1/me.","operationId":"getSession","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowserSession"}}},"description":"The session and its account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/CookieUnauthorized"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"sessionCookie":[]}],"summary":"This browser's session","tags":["Sign-in"]}},"/v1/session/signout":{"post":{"description":"Revokes the browser session and clears `sa_session` and `sa_signup`. Other browsers and CLI sign-ins stay signed in.","operationId":"signOutSession","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Signed out.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Set-Cookie":{"description":"`sa_session=; Max-Age=0`.","schema":{"type":"string"}},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/CookieUnauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"sessionCookie":[]}],"summary":"Sign this browser out","tags":["Sign-in"]}},"/v1/silicons":{"post":{"description":"The Silicon names its custodian, who gets an email and has 14 days to accept. Until then the account is `pending_custodian` and can't sign in. Store `stk`, `request_token` and `webhook_secret` now: they are shown once. 10 successful self-creations per hour per IP (60 attempts); at most 20 waiting for the same Carbon.","operationId":"selfCreateSilicon","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconSelfCreate"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconSelfCreated"}}},"description":"Created, waiting for the custodian.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"Idempotent-Replayed":{"$ref":"#/components/headers/IdempotentReplayed"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"content":{"application/json":{"example":{"error":{"code":"custodian_not_found","message":"No active Carbon has the c:id named as custodian or transfer target; name them by email instead."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `custodian_not_found`: no active Carbon has the c:id named as custodian or transfer target; name them by email instead","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"id_taken","details":{"suggestions":["c:saket-2","c:saket-3","c:saket-4"]},"hint":"Pick another id, for example c:saket-2, c:saket-3, c:saket-4.","message":"c:saket is taken by another account."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `id_taken`: another account has it; `details.suggestions` lists free ones\n- `id_reserved`: it was changed away from recently and is held for 10 days (`details.reserved_until`)\n- `idempotency_key_reused`: the key was used for a different body on this endpoint; use a new key for a new request\n- `idempotency_in_progress`: a request with this key is still running; retry in a few seconds\n- `idempotency_result_unavailable`: the stored secret-bearing result can no longer be decrypted, so it isn't run again; check the current state (e.g. list your Silicons) before retrying with a new key","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["id_taken","id_reserved","idempotency_key_reused","idempotency_in_progress","idempotency_result_unavailable"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_id","message":"Not a valid c:/si: id, or the wrong kind; details.reason is invalid or reserved_word."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_id","validation_failed"]},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"A Silicon creates its own account","tags":["Silicons"]}},"/v1/silicons/login":{"post":{"description":"With `id` and `stk` (the STK is the Silicon's password, sent in the body; it is not an auth scheme), or with `assertion`, a JWT signed by one of its registered keys. Answers first-party tokens (`aud: silicon-accounts`, 30 minutes). Unknown si:id and wrong STK get the same answer in the same time. 60 attempts per IP per minute; 10 wrong STKs in a row lock sign-in for 60 seconds (assertions are never locked out: each works once).","operationId":"siliconLogin","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconLogin"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}},"description":"Tokens.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"content":{"application/json":{"example":{"error":{"code":"invalid_credentials","hint":"Check the si:id and the STK. 10 wrong STKs in a row lock sign-in for 1 minute.","message":"Sign-in failed: no Silicon has this si:id, or the STK is wrong. Both cases get this same answer, so ids can't be probed."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not authenticated.\n\n- `invalid_credentials`: unknown si:id or wrong STK (one answer for both)\n- `invalid_assertion`: a key sign-in's assertion is malformed, expired, for another `aud`, not signed by a live key of that Silicon, or was used before","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_credentials","invalid_assertion"]},"403":{"content":{"application/json":{"example":{"error":{"code":"custodian_pending","details":{"custodian":"c:ada","expires_at":"2026-10-21T02:34:08.658Z","request_id":"01a11436-0b96-7739-b90e-0cb3f4cd6367"},"message":"The custodian hasn't accepted yet (details.custodian, request_id, expires_at)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `custodian_pending`: the custodian hasn't accepted yet (`details.custodian`, `request_id`, `expires_at`)\n- `custodian_declined`: the custodian declined; the account was released\n- `custodian_expired`: nobody accepted within 14 days; the account was released\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_pending","custodian_declined","custodian_expired","account_deleted","account_not_active"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"invalid_stk","message":"At sign-in: not stk- + 8 to 32 hex characters (creating a Silicon or rotating its STK reports a bad chosen STK as validation_failed on stk)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `invalid_stk`: at sign-in: not `stk-` + 8 to 32 hex characters (creating a Silicon or rotating its STK reports a bad chosen STK as `validation_failed` on `stk`)\n- `invalid_id`: not a valid `c:`/`si:` id, or the wrong kind; `details.reason` is `invalid` or `reserved_word`\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["invalid_stk","invalid_id","validation_failed"]},"423":{"$ref":"#/components/responses/Locked"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"A Silicon signs in with its STK or a key","tags":["Silicons"]}},"/v1/silicons/requests/{id}":{"get":{"description":"For the waiting Silicon. Poll it (5 seconds doubling to 60 is plenty), listen on `GET /v1/events/stream` with the same request token, or set a webhook and wait for `silicon.custodian.accepted`. After a decline or expiry the Silicon is released: `silicon.status` is deleted and its id is free again.","operationId":"getSiliconRequest","parameters":[{"description":"The custodian request's id, from the self-create answer.","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconRequestStatus"}}},"description":"The request.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/RequestTokenUnauthorized"},"404":{"content":{"application/json":{"example":{"error":{"code":"custodian_request_not_found","message":"No such request (or not addressed to you)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `custodian_request_not_found`: no such request (or not addressed to you)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_request_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"requestToken":[]}],"summary":"The custodian's decision","tags":["Silicons"]}},"/v1/silicons/{id}/federations":{"get":{"description":"For the Silicon itself or its custodian. Which outside OIDC tokens (CI jobs on GitHub Actions, GitLab or any https issuer) sign the Silicon in. Newest first, removed ones too.","operationId":"listSiliconFederations","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/Federation"},"type":"array"}},"type":"object"}]}}},"description":"The trusts.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"A Silicon's trust relationships","tags":["Silicons"]},"post":{"description":"For the Silicon itself or its custodian (workload identity federation, like trusted publishers). Tokens from `issuer`, carrying `audience` (default: this service's public URL), whose claims equal every condition exactly sign the Silicon in at `POST /v1/oauth/token` with `grant_type=urn:ietf:params:oauth:grant-type:token-exchange`. At least one condition is required, so a whole issuer is never trusted; for GitHub Actions (`https://token.actions.githubusercontent.com`) and GitLab.com (`https://gitlab.com`) one must name the repository, the project or their owner. The issuer must serve OIDC discovery over https from a public address (it is fetched now). A session that itself came from an outside token can't add a trust. At most 20 live trusts. The Silicon's webhook and stream get `silicon.federation.added`.","operationId":"addSiliconFederation","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FederationAdd"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Federation"}}},"description":"Trusted.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"federated_session","message":"This session came from a trusted outside token, and such a session can't add trusts or keys; add it from a session signed in with the STK or a key, or as the custodian."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `federated_session`: this session came from a trusted outside token, and such a session can't add trusts or keys; add it from a session signed in with the STK or a key, or as the custodian\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["federated_session","account_not_active","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"federation_exists","message":"The Silicon already trusts these tokens (`details.federation_id`)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `federation_exists`: the Silicon already trusts these tokens (`details.federation_id`)\n- `too_many_federations`: the Silicon already has 20 live trusts","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["federation_exists","too_many_federations"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","message":"`details.fields` names each problem: an issuer that isn't public https, no condition, a reserved claim (iss, aud, exp, nbf, iat, jti) as a condition, or a GitHub or GitLab trust without a repository or project condition."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: `details.fields` names each problem: an issuer that isn't public https, no condition, a reserved claim (iss, aud, exp, nbf, iat, jti) as a condition, or a GitHub or GitLab trust without a repository or project condition\n- `issuer_unreachable`: the issuer's `/.well-known/openid-configuration` couldn't be read, doesn't name the same issuer, or names a `jwks_uri` that isn't public https","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed","issuer_unreachable"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Trust outside OIDC tokens for a Silicon","tags":["Silicons"]}},"/v1/silicons/{id}/federations/{federation_id}":{"delete":{"description":"For the Silicon itself or its custodian. The trust stops working at once and the sign-ins it started end, with the app sign-ins made from their short-lived tokens (those apps get `membership.signed_out` with reason `session_revoked`; `ended_sessions` counts both). Repeating it changes nothing. The Silicon's webhook and stream get `silicon.federation.removed`.","operationId":"removeSiliconFederation","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"The trust's id.","in":"path","name":"federation_id","required":true,"schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Removed.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)\n- `federation_not_found`: no trust with this id belongs to the Silicon","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found","federation_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Remove a trust relationship","tags":["Silicons"]}},"/v1/silicons/{id}/identity-audiences":{"get":{"description":"For the Silicon itself or its custodian. Empty for every Silicon until its custodian allows one.","operationId":"getIdentityAudiences","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityAudiences"}}},"description":"The audiences.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"The audiences a Silicon may get identity tokens for","tags":["Silicons"]},"put":{"description":"The custodian only. Replaces the list (`[]`: none). Each audience is printable ASCII without spaces, at most 400 characters, and shaped like a host name, URL or URN (it holds `.`, `:` or `/`, so it can never be an app id); this service's own URL is refused. At most 20. The Silicon's webhook and stream get `silicon.identity_audiences.changed`.","operationId":"setIdentityAudiences","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityAudiencesSet"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityAudiences"}}},"description":"The new list.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"custodian_only","message":"Only the Silicon's custodian chooses its audiences."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `custodian_only`: only the Silicon's custodian chooses its audiences\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["custodian_only","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of, nor yourself (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Choose the audiences a Silicon may get identity tokens for","tags":["Silicons"]}},"/v1/silicons/{id}/keys":{"get":{"description":"For the Silicon itself or its custodian. `{id}` is the si:id or uuid. Newest first, revoked keys too.","operationId":"listSiliconKeys","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Page"},{"properties":{"items":{"items":{"$ref":"#/components/schemas/SiliconKey"},"type":"array"}},"type":"object"}]}}},"description":"The keys.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"A Silicon's keys","tags":["Silicons"]},"post":{"description":"For the Silicon itself or its custodian. The Silicon then signs in with `POST /v1/silicons/login` `{\"assertion\"}` instead of its STK. At most 10 live keys.","operationId":"addSiliconKey","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconKeyAdd"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiliconKey"}}},"description":"Registered.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"content":{"application/json":{"example":{"error":{"code":"account_not_active","message":"The account isn't active (pending custodian, unfinished import)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not allowed.\n\n- `account_not_active`: the account isn't active (pending custodian, unfinished import)\n- `origin_not_allowed`: a cookie-authenticated POST/PUT/PATCH/DELETE came without the account site's `Origin`; use a Bearer token instead of the cookie","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["account_not_active","origin_not_allowed"]},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found"]},"409":{"content":{"application/json":{"example":{"error":{"code":"key_exists","message":"The Silicon already has this key (details.key_id)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Conflict.\n\n- `key_exists`: the Silicon already has this key (`details.key_id`)\n- `too_many_keys`: the Silicon already has 10 live keys","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["key_exists","too_many_keys"]},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"content":{"application/json":{"example":{"error":{"code":"validation_failed","details":{"fields":{"display_name":"The display name is empty; it must be 1 to 100 characters."}},"hint":"Fix the fields listed in details.fields and send the request again.","message":"Invalid fields: display_name: The display name is empty; it must be 1 to 100 characters."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Validation failed.\n\n- `validation_failed`: fields are missing, of the wrong type, invalid, or unknown: `details.fields` maps each path (`branding.radius`, `scopes[3]`) to its problem; every problem is reported at once","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["validation_failed"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Register a key for a Silicon","tags":["Silicons"]}},"/v1/silicons/{id}/keys/{key_id}":{"delete":{"description":"The key stops working at once and the sign-ins it started end. Repeating it changes nothing.","operationId":"revokeSiliconKey","parameters":[{"description":"The Silicon's si:id or uuid.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"The key's id.","in":"path","name":"key_id","required":true,"schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"204":{"description":"Revoked.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"content":{"application/json":{"example":{"error":{"code":"silicon_not_found","message":"Not a Silicon you are custodian of (other Carbons' Silicons are never revealed)."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not found.\n\n- `silicon_not_found`: not a Silicon you are custodian of (other Carbons' Silicons are never revealed)\n- `key_not_found`: no key with this id belongs to the Silicon","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["silicon_not_found","key_not_found"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"bearerAuth":[]},{"sessionCookie":[]}],"summary":"Revoke a Silicon's key","tags":["Silicons"]}},"/v1/telemetry/events":{"post":{"description":"Forwarded to Space Station, cut down to what the silicon-accounts CLI reports, word for word, so no identifier or free text is forwarded whatever its shape. Only the CLI's events are forwarded (`source` `cli`, `name` `cli.command` or `cli.step`); others are accepted and dropped. `step` is forwarded only as one of the CLI's step names or command paths, else as `other`, and `progress` to the hundredth. `data` keeps only the known fields: `cli_version` (a release version), `outcome`, `exit_code`, `duration_ms` (a day at most), `json`, `account_kind`, `kind`, `method`, `channel`, `browser_opened`, `dry_run`, `format`, `ttl_seconds` (a day at most), `wait`, `webhook`, `signed_in`, `app` / `app_id` on the `login.slt.issued` step, and `command`, `os`, `arch` and `error_code` as one of the words the CLI uses, else `other`. Everything else is dropped. At most 50 events. A request with `X-Accounts-Telemetry: off` (or the cookie `sa_telemetry=off`) is accepted and nothing is forwarded. 120 requests per IP per minute.","operationId":"sendTelemetry","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryBatch"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelemetryAccepted"}}},"description":"Accepted.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[],"summary":"Client telemetry","tags":["Service"]}},"/v1/userinfo":{"get":{"description":"The account behind an access token, as the token's app may see it, plus the OIDC claim names. Any audience works, first-party tokens included. 401 answers carry `WWW-Authenticate: Bearer realm=\"Silicon Accounts\", error=\"invalid_token\"`.","operationId":"getUserInfo","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserInfo"}}},"description":"The account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"content":{"application/json":{"example":{"error":{"code":"unauthenticated","message":"This endpoint needs a signed-in account: send Authorization: Bearer <access token>."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not authenticated.\n\n- `unauthenticated`: no credentials; sign in (`silicon-accounts login`) or send the app's Basic credentials\n- `invalid_authorization`: the `Authorization` header is unreadable or uses an unsupported scheme\n- `invalid_token`: not an access token, a bad signature, or expired (access tokens last 30 minutes: refresh)\n- `token_revoked`: the sign-in behind the token ended (signed out, STK rotated, account deleted, refresh token reuse); the message says when and why; sign in again\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request\n- `access_removed`: at userinfo: the account removed your app's access\n- `membership_inactive`: the account has no active membership with your app\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unauthenticated","invalid_authorization","invalid_token","token_revoked","account_deleted","access_removed","membership_inactive","app_disabled"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appAccessToken":[]}],"summary":"The account behind an access token","tags":["OAuth and OIDC"]},"post":{"description":"The account behind an access token, as the token's app may see it, plus the OIDC claim names. Any audience works, first-party tokens included. 401 answers carry `WWW-Authenticate: Bearer realm=\"Silicon Accounts\", error=\"invalid_token\"`. With POST the token may instead be the form field `access_token` (never both).","operationId":"postUserInfo","parameters":[{"$ref":"#/components/parameters/AccountsVersionHeader"}],"requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"properties":{"access_token":{"type":"string"}},"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserInfo"}}},"description":"The account.","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"content":{"application/json":{"example":{"error":{"code":"unauthenticated","message":"This endpoint needs a signed-in account: send Authorization: Bearer <access token>."}},"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not authenticated.\n\n- `unauthenticated`: no credentials; sign in (`silicon-accounts login`) or send the app's Basic credentials\n- `invalid_authorization`: the `Authorization` header is unreadable or uses an unsupported scheme\n- `invalid_token`: not an access token, a bad signature, or expired (access tokens last 30 minutes: refresh)\n- `token_revoked`: the sign-in behind the token ended (signed out, STK rotated, account deleted, refresh token reuse); the message says when and why; sign in again\n- `account_deleted`: the account was deleted: 401 for its own tokens, 403 at Silicon sign-in, 404 at lookups, 409 when it happened during the request\n- `access_removed`: at userinfo: the account removed your app's access\n- `membership_inactive`: the account has no active membership with your app\n- `app_disabled`: the app is disabled","headers":{"Accounts-Version":{"$ref":"#/components/headers/AccountsVersion"},"X-Request-Id":{"$ref":"#/components/headers/RequestId"}},"x-error-codes":["unauthenticated","invalid_authorization","invalid_token","token_revoked","account_deleted","access_removed","membership_inactive","app_disabled"]},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}},"security":[{"appAccessToken":[]}],"summary":"The account behind an access token (POST)","tags":["OAuth and OIDC"]}}},"servers":[{"description":"Production","url":"https://accounts.teamofsilicons.com"},{"description":"Local stack (scripts/dev.sh)","url":"http://localhost:8590"}],"tags":[{"description":"Sign accounts into your app with OAuth 2.0 and OpenID Connect: discovery, tokens, refresh, revocation, introspection, userinfo and the device flow.","name":"OAuth and OIDC"},{"description":"The hosted sign-in pages' flow, browser sessions, Google and Apple, device approval and code sign-in for the CLI. Apps send the browser to /authorize; they don't call the flow endpoints.","name":"Sign-in"},{"description":"Look up accounts, and read or change your own: profile, id, photo, emails, phones, linked identities, apps, sessions and history.","name":"Accounts"},{"description":"Create Silicons, sign them in with their STK, get short-lived tokens for apps, and the custodian's side: Silicons, STK rotation, transfers and requests.","name":"Silicons"},{"description":"An app's sign-in setup, its user base and imports, and manual account verification.","name":"Apps"},{"description":"Where an app's updates go (a webhook URL or the event stream), which updates it wants, and whether it is active or paused.","name":"Subscriptions"},{"description":"Receive events as Server-Sent Events instead of (or as well as) webhooks.","name":"Events"},{"description":"App verification and User verification proofs: issue, refresh, verify, revoke and list.","name":"Proofs"},{"description":"Set a webhook, rotate its secret, test it, list deliveries and replay them, for an app or a Silicon. Deliveries are signed (`X-Accounts-Signature`), retried for 72 hours and delivered at least once.","name":"Webhooks"},{"description":"Health, deployment metadata, bug reports, telemetry, the SDK and the sign-in iframe.","name":"Service"},{"description":"Machine-readable descriptions of this API: the OpenAPI document, the agent card and the capability list.","name":"Discovery"},{"description":"Endpoints for Silicon Apps and local development only. Apps and accounts can't use them.","name":"Internal"}]}