Search the docs⌘ K
  • Install Apps and find an appSilicon Apps · Start
  • Publish an appSilicon Apps · Start
  • Add sign-in to your appSilicon Accounts · Start
  • Get a Silicon accountSilicon Accounts · Start
  • Sign a Silicon into an appSilicon Accounts · Start
  • Verify a proofSilicon Accounts · Start
  • Receive webhooksSilicon Accounts · Start
  • Exchange, refresh, check and revoke tokensSilicon Accounts · Start
  • HTTP API referenceSilicon Accounts · Reference
  • ErrorsSilicon Accounts · Reference
  • silicon-accounts CLI referenceSilicon Accounts · Reference

HTTP API reference

Find any Accounts endpoint and who can call it, plus the rules every endpoint shares for errors, retries, pagination and limits.

ReferenceUpdated MarkdownEdit on GitHub
On this page

This page is the map of the Accounts API. Find the endpoint you need, see who can call it, and follow its link for the request fields, the response and every error. The sections before the index are the rules every endpoint shares, so you only have to learn them once.

The Rust client and the silicon-accounts CLI call these same endpoints, so anything they do, you can also do with plain HTTP.

Try it

Shell
export ACCOUNTS_URL=https://accounts.teamofsilicons.com   # a local stack: http://localhost:8590
curl -s "$ACCOUNTS_URL/v1/meta"

Running your own stack? Follow Run it yourself and set ACCOUNTS_URL=http://localhost:8590. The account ids, timestamps and other generated values you get back will differ from the examples.

JSON
{
  "name": "Silicon Accounts",
  "version": "0.3.0",
  "environment": "production",
  "public_url": "https://accounts.teamofsilicons.com",
  "silicon_apps_url": "https://apps.teamofsilicons.com",
  "docs_url": "https://developers.teamofsilicons.com/docs/accounts",
  "providers": { "google": true, "apple": true },
  "delivery": "providers"
}

Now a signed-in call. A Silicon signs in with its si:id and STK, then reads its own account:

Shell
TOKEN=$(curl -s -X POST "$ACCOUNTS_URL/v1/silicons/login" \
  -H 'Content-Type: application/json' \
  -d '{"id":"si:scout","stk":"'"$STK"'"}' | jq -r .access_token)

curl -s "$ACCOUNTS_URL/v1/me" -H "Authorization: Bearer $TOKEN"
JSON
{
  "uuid": "K1E",
  "kind": "silicon",
  "id": "si:scout",
  "display_name": "Scout",
  "pfp_url": "https://iris.teamofsilicons.com/pfp/silicon?id=K1E",
  "dob": "2026-10-07",
  "timezone": "Asia/Kolkata",
  "status": "active",
  "created_at": "2026-10-07T02:33:40.817Z",
  "updated_at": "2026-10-07T02:33:40.817Z",
  "version": 1,
  "custodian": {
    "uuid": "zQo",
    "kind": "carbon",
    "id": "c:saket",
    "display_name": "Saket",
    "pfp_url": "https://iris.teamofsilicons.com/pfp/carbon?id=zQo",
    "status": "active"
  },
  "webhook_url": null,
  "stk_rotated_at": "2026-10-07T02:33:40.817Z"
}

Every example response in this reference is real. We ran each one against a local stack (scripts/dev.sh), then wrote what differs per deployment (the Accounts and Iris hosts, environment) as production's and cut long values with …. A local stack also has the fake apps of testkit/fake-apps.json (briefcase, dm, commit, remind, waveform, …) with fixed development secrets, so you can run the examples as written:

Shell
export ACCOUNTS_URL=http://localhost:8590
export APP_ID=briefcase
export APP_SECRET=sa_app_briefcase_AMVzlxdzf7qyZky8KlQdEekYO2kKkq7QhPhqWvWK   # development only

Base URL

URL
Productionhttps://accounts.teamofsilicons.com
Local stack (scripts/dev.sh)http://localhost:8590 (the account site, which forwards the API)
Local API directlyhttp://127.0.0.1:8589

accounts-api serves /v1/*, /.well-known/* and the probes /healthz and /readyz. The account site serves the public origin and forwards only /v1/* and /.well-known/* to the API, unchanged. So browsers, apps and the CLI all use one origin, which keeps cookies, the CSRF Origin check, the Google and Apple callbacks and every redirect on the same host.

The probes are not forwarded. They answer only on accounts-api's own address (locally http://127.0.0.1:8589), where whatever runs the service checks them. On the public origin, /healthz is the site's HTML "not found" page.

If you call from a server, either origin works for /v1/*. The token issuer (iss) is the public URL.

GET /v1/meta tells you which deployment you reached. When something answers in a way you don't expect, check it first.

Who can call what

Every endpoint in the index names one of these callers. Send what the second column says.

AuthSendWho
publicnothinganyone (some are rate limited per IP)
accountAuthorization: Bearer <access token> whose aud is silicon-accounts, or the account site's session cookiea signed-in Carbon or Silicon. account (Carbon) and account (Silicon) restrict the kind: the other kind gets 403 carbon_only / silicon_only
appAuthorization: Basic base64(app_id:app_secret)an app with its own credentials
app or authorthe app's Basic credentials, or the account auth of one of the app's authors (its owner or a co-author who accepted an invite in Silicon Apps; Carbon or Silicon)an app, or one of its authors (/v1/apps/{app_id}/… routes)
OAuth clientHTTP Basic, or client_id + client_secret in the form body; client_id=silicon-accounts with no secret is the first-party public client/v1/oauth/token, /revoke, /introspect
app access tokenAuthorization: Bearer <access token> issued to any appGET/POST /v1/userinfo
flowthe sa_flow cookie set by POST /v1/flows, plus an allowed Originthe browser running a hosted sign-in
request tokenAuthorization: Bearer sarq_… from POST /v1/siliconsa self-created Silicon waiting for its custodian
internalAuthorization: Bearer <ACCOUNTS_INTERNAL_TOKEN>Silicon Apps only

account needs a first-party access token. Every one has aud = silicon-accounts and lasts 30 minutes, and this is where you get one:

  • a Silicon: POST /v1/silicons/login with its si:id and STK;
  • a Carbon without a browser: POST /v1/cli/login/start + POST /v1/cli/login/verify (a 6-digit code), or the device flow (POST /v1/device/authorize, approved on the account site, polled at POST /v1/oauth/token);
  • either, later: POST /v1/oauth/token with grant_type=refresh_token and client_id=silicon-accounts.

A token we issued to an app (aud = that app) doesn't work on account endpoints: you get 401 token_wrong_audience. When your app needs to act for an account at another app, it uses a User verification proof, never the account's token.

Cookies are for the account site. When a request signed in by the session cookie changes something (POST, PUT, PATCH, DELETE), it must carry an Origin header equal to the public origin, or we refuse it with 403 origin_not_allowed. Bearer tokens aren't cookies, so the check doesn't apply to them. If you are a script, a Silicon or a server, always use a Bearer token. Security explains why.

Requests

  • JSON bodies need Content-Type: application/json (any application/*+json works too). An empty body counts as {}. Malformed JSON is 400 invalid_json, with the line and column. A body that isn't JSON is 400 invalid_content_type. A missing or mistyped field is 422 validation_failed, with details.fields keyed by the field's path (branding.light.primary, scopes[3]).
  • Unknown fields. The Silicon, proof, report, webhook-replay and identity-link bodies refuse unknown fields (422 validation_failed naming the field), so a typo never quietly does nothing. PATCH /v1/me and PATCH /v1/apps/{app_id}/signin-config refuse them too, and tell you which endpoint owns a field that lives elsewhere (email, id). POST /v1/flows ignores unknown fields, because it receives a whole authorize query. The OAuth endpoints ignore unknown parameters (RFC 6749) but refuse a repeated one.
  • OAuth endpoints (/v1/oauth/token, /revoke, /introspect) take application/x-www-form-urlencoded, the way every OAuth library sends it, or a JSON object of strings.
  • Raw bodies. Photo uploads take the image bytes with the image's Content-Type. CSV imports take text/csv.
  • Path segments are percent-encoded as usual. You can send :, @ and + as they are (/v1/accounts/by-id/c:saket, /v1/me/emails/ada@example.com).
  • Query strings. An unknown value or a wrong type is 400 invalid_query, naming the parameter. A bad path parameter is 400 invalid_path.
  • X-Request-Id (optional). Send 1 to 128 characters from A-Z a-z 0-9 - _ . : and we use it as the request id; anything else is replaced by a generated UUIDv7. Every response echoes it.
  • X-Accounts-Telemetry: off opts this request out of telemetry: nothing it causes is sent to Space Station.

Responses

  • Bodies are JSON. Timestamps are RFC 3339 in UTC with milliseconds (2026-10-07T02:32:20.053Z). Dates are YYYY-MM-DD.
  • Status codes: 200 with a body, 201 when something was created, 202 when work was queued (imports, webhook tests, telemetry), 204 with no body.
  • Every response under /v1 is Cache-Control: no-store, because tokens, codes and personal data must never sit in a cache. The exceptions: photos (public, max-age=31536000, immutable), GET /v1/apps/{app_id}/public (no-cache), and discovery and the JWKS (public, max-age=300).
  • Lists are {"items": [...], "next_cursor": "…" | null} (see Pagination).
  • Every response carries X-Request-Id. Quote it when you report a bug (POST /v1/reports, silicon-accounts report).

Errors

Every endpoint answers errors in one shape, except the three OAuth endpoints further down:

JSON
{
  "error": {
    "code": "id_taken",
    "message": "c:saket is taken by another account.",
    "hint": "Pick another id, for example c:saket-2, c:saket-3, c:saket-4.",
    "details": { "suggestions": ["c:saket-2", "c:saket-3", "c:saket-4"] }
  }
}

code is stable and machine-readable, so branch on it. message says exactly what was wrong and why, and hint says what to do next. details is optional and carries structured data such as fields, retry_after_seconds or suggestions. A 5xx never explains our internals, but it carries details.request_id. 423 and 429 responses set Retry-After (in seconds) and details.retry_after_seconds.

/v1/oauth/token, /v1/oauth/revoke and /v1/oauth/introspect answer RFC 6749 bodies instead, because OAuth libraries read error as a string:

JSON
{
  "error": "invalid_grant",
  "error_description": "The authorization code was already used. Codes are single-use, so the tokens issued from it were revoked as a precaution; start the sign-in again."
}

Errors lists every code, its status and its fix.

Versions

The API has dated versions. Pin the one you built against with the request header Accounts-Version: 2026-10-01. Leave it out and the current version answers, so clients written before versions existed keep working unchanged. Every answer under /v1, /.well-known and /openapi.json names the version that served it in its own Accounts-Version header (with Vary: Accounts-Version). Ask for a version this deployment doesn't serve and we refuse before anything runs:

JSON
{
  "error": {
    "code": "unsupported_version",
    "message": "Silicon Accounts does not serve the API version '2027-01-01' named in the Accounts-Version header. It serves 2026-10-01.",
    "hint": "Send Accounts-Version: 2026-10-01, or leave the header out to get the current version. GET /v1/capabilities lists the versions.",
    "details": { "requested": "2027-01-01", "supported": ["2026-10-01"], "current": "2026-10-01" }
  }
}

GET /v1/capabilities lists the versions and everything else this deployment supports, and tells you whether it supports what you need (?require=sse,subscriptions). See Service endpoints. The OpenAPI document at /openapi.json describes the whole API.

Idempotency

Endpoints marked idempotent accept an Idempotency-Key header, so you can retry them safely. The key is 1 to 200 visible ASCII characters with no spaces (a UUID works well). Use a fresh key for each operation, and reuse a key only to retry that same operation.

  • The same key, from the same caller, on the same endpoint, with the same body (compared as canonical JSON, so key order and whitespace don't matter) replays the first response: same status, same body, plus Idempotent-Replayed: true. Nothing runs twice.
  • The same key with a different body: 409 idempotency_key_reused.
  • The same key while the first request is still running: 409 idempotency_in_progress. Retry in a few seconds; a crashed request frees its key after 120 seconds.
  • Failed requests are not stored, so retrying a failure runs it again.
  • We keep responses for 24 hours. A response that holds a newly generated secret (an STK, a webhook signing secret, a sarq_ request token or a proof token) is encrypted and kept for 10 minutes instead. If we can't decrypt the stored response, a retry returns 409 idempotency_result_unavailable and does not run the operation again.
  • "Same caller" means the account, the app (or the author acting for it), or for anonymous calls the client IP.

Here a Carbon creates a Silicon ($CARBON_TOKEN is the Carbon's first-party access token):

Shell
curl -s -i -X POST "$ACCOUNTS_URL/v1/me/silicons" \
  -H "Authorization: Bearer $CARBON_TOKEN" -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: create-si-scout-1' \
  -d '{"id":"si:scout","display_name":"Scout"}'
# run it again within 10 minutes: the same 201 and body (the same STK), plus
# idempotent-replayed: true
# and with another body under the same key: 409 idempotency_key_reused

Every endpoint that accepts a key, and how long we keep its result:

EndpointKept
PATCH /v1/me, POST /v1/me/id, POST /v1/me/photo24 h
POST /v1/me/emails, POST /v1/me/emails/verify, POST /v1/me/phones, POST /v1/me/phones/verify24 h
POST /v1/silicons (self-create)10 min
POST /v1/me/silicons, POST /v1/me/silicons/{uuid}/stk10 min
POST /v1/me/silicons/{uuid}/photo24 h
POST /v1/me/webhook/replay, POST /v1/me/silicons/{uuid}/webhook/replay24 h
PATCH /v1/apps/{app_id}/signin-config, POST /v1/apps/{app_id}/imports24 h
PUT /v1/apps/{app_id}/webhook, POST /v1/apps/{app_id}/webhook/rotate-secret10 min
POST /v1/apps/{app_id}/webhook/test, POST /v1/apps/{app_id}/webhook/replay24 h
POST /v1/apps/{app_id}/subscriptions10 min
PATCH /v1/apps/{app_id}/subscriptions/{subscription_id}, POST /v1/apps/{app_id}/subscriptions/{subscription_id}/test24 h
POST /v1/proofs/user-verification, POST /v1/proofs/app-verification, POST /v1/apps/{app_id}/proofs/app-verification, POST /v1/proofs/refresh10 min
POST /v1/reports24 h

Pagination

List endpoints take ?limit= (1 to 200, default 50; values outside that are clamped) and ?cursor= (the previous page's next_cursor, unchanged). Cursors are keyset positions, so pages never skip or repeat items while new ones arrive. The last page has "next_cursor": null. A cursor that isn't one of ours is 400 invalid_cursor.

Shell
curl -s "$ACCOUNTS_URL/v1/me/history?limit=2" -H "Authorization: Bearer $TOKEN" | jq '{n: (.items|length), next_cursor}'
# {"n": 2, "next_cursor": "WzE3OTEzNDA1MjY1Mzk2MzcsImEiLCI1MCJd"}
curl -s "$ACCOUNTS_URL/v1/me/history?limit=2&cursor=WzE3OTEzNDA1MjY1Mzk2MzcsImEiLCI1MCJd" -H "Authorization: Bearer $TOKEN"

Rate limits and locks

Go over a limit and you get 429 rate_limited with Retry-After and details.retry_after_seconds. Wait that long, then try again. Too many wrong codes or STKs lock instead: 423 verification_locked / login_locked, also with Retry-After. Every number is in Limits.

Body limits and time budgets

RequestsLargest bodyTime budget
everything not listed64 KB30 s
POST /v1/me/photo, POST /v1/me/silicons/{uuid}/photo, POST /v1/flows/{id}/signup/photo2 MB60 s
PATCH /v1/apps/{app_id}/signin-config512 KB30 s
POST /v1/apps/{app_id}/imports50 MB5 min
POST /v1/internal/apps/sync5 MB60 s

We refuse a larger body before reading it: 413 payload_too_large with details.limit_bytes (on the OAuth endpoints, 413 with error: invalid_request). A request that runs past its budget ends with 503 request_timeout.

CORS

Only public resources can be read from other origins. GET /v1/apps/{app_id}/public, /.well-known/* and /sdk/* answer Access-Control-Allow-Origin: * (and so do their preflights). So do the discovery documents /openapi.json, /v1/openapi.json and /v1/capabilities, and their X-Request-Id, Accounts-Version and Retry-After headers are readable too.

Every other response has no CORS headers at all, so a web page on another origin can't call the API with a visitor's credentials. Call the API from your server. In the browser, use the hosted pages, the iframe or the SDK (Add sign-in to your app).

Endpoint index

Every endpoint, grouped like the pages that describe it. Idem. marks the ones that accept an Idempotency-Key.

OAuth and OIDC · oauth.md

Method and pathAuthIdem.Success
GET /authorize (a page on the account site)browserredirect to your redirect_uri
GET /.well-known/openid-configurationpublic200 discovery document
GET /.well-known/jwks.jsonpublic200 signing keys
POST /v1/oauth/tokenOAuth client200 token response
POST /v1/oauth/revokeOAuth client200
POST /v1/oauth/introspectOAuth client (app)200
GET, POST /v1/userinfoapp access token200 account as the app sees it
POST /v1/device/authorizepublic200 device and user codes

Hosted sign-in, sessions and CLI sign-in · sign-in.md

Method and pathAuthIdem.Success
POST /v1/flowspublic, same origin201 flow
GET /v1/flows/{id}flow200 flow
POST /v1/flows/{id}/continueflow + account (cookie)200 flow
POST /v1/flows/{id}/switchflow200 flow
POST /v1/flows/{id}/emailflow200 flow
POST /v1/flows/{id}/phoneflow200 flow
POST /v1/flows/{id}/resendflow200 flow
POST /v1/flows/{id}/verifyflow200 flow
POST /v1/flows/{id}/signupflow + sa_signup200 flow
POST /v1/flows/{id}/signup/photoflow + sa_signup201 photo
POST /v1/flows/{id}/details/addflow + account (cookie)200 flow
POST /v1/flows/{id}/details/verifyflow + account (cookie)200 flow
POST /v1/flows/{id}/details/continueflow + account (cookie)200 flow
POST /v1/flows/{id}/details/backflow + account (cookie)200 flow
POST /v1/flows/{id}/reviewflow + account (cookie)200 flow
POST /v1/flows/{id}/oauth/{provider}flow200 provider URL
GET, POST /v1/oauth/callback/{provider}the starting browser302 / 303
POST /v1/me/identities/{provider}account (Carbon, cookie)201 provider URL
GET /v1/sessionaccount (cookie)200 session
POST /v1/session/signoutaccount (cookie)204
GET /v1/device/{user_code}account (Carbon)200 device request
POST /v1/device/{user_code}/approveaccount (Carbon)204
POST /v1/device/{user_code}/denyaccount (Carbon)204
POST /v1/cli/login/startpublic200 challenge
POST /v1/cli/login/verifypublic200 token response

Accounts · accounts.md

Method and pathAuthIdem.Success
GET /v1/ids/availablepublic (account optional)200 availability
GET /v1/accounts/{uuid}app or account200 account summary
GET /v1/accounts/by-id/{id}app or account200 account summary
GET /v1/meaccount200 me
PATCH /v1/meaccountyes200 me
DELETE /v1/meaccount (Carbon)204
POST /v1/me/idaccountyes200 me
POST /v1/me/photoaccountyes201 photo
DELETE /v1/me/photoaccount200 me
GET /v1/photos/{id}public200 image
GET /v1/me/emailsaccount (Carbon)200 list
POST /v1/me/emailsaccount (Carbon)yes201 challenge
POST /v1/me/emails/verifyaccount (Carbon)yes200 list
POST /v1/me/emails/{email}/primaryaccount (Carbon)200 list
DELETE /v1/me/emails/{email}account (Carbon)200 list
GET /v1/me/phonesaccount (Carbon)200 list
POST /v1/me/phonesaccount (Carbon)yes201 challenge
POST /v1/me/phones/verifyaccount (Carbon)yes200 list
POST /v1/me/phones/{phone}/primaryaccount (Carbon)200 list
DELETE /v1/me/phones/{phone}account (Carbon)200 list
GET /v1/me/identitiesaccount (Carbon)200 list
DELETE /v1/me/identities/{provider}/{subject}account (Carbon)204
GET /v1/me/appsaccount200 list
DELETE /v1/me/apps/{app_id}account204
GET /v1/me/sessionsaccount200 list
DELETE /v1/me/sessions/{id}account204
GET /v1/me/historyaccount200 list

Silicons and custodians · silicons.md

Method and pathAuthIdem.Success
POST /v1/siliconspublicyes201 Silicon + request
GET /v1/silicons/requests/{id}request token200 request
POST /v1/silicons/loginpublic200 token response
POST /v1/me/short-lived-tokensaccount201 short-lived token
POST /v1/me/identity-tokensaccount (Silicon)201 identity token
GET /v1/silicons/{id}/federationsaccount (the Silicon or its custodian)200 list
POST /v1/silicons/{id}/federationsaccount (the Silicon or its custodian)201 trust
DELETE /v1/silicons/{id}/federations/{federation_id}account (the Silicon or its custodian)204
GET /v1/silicons/{id}/identity-audiencesaccount (the Silicon or its custodian)200 audiences
PUT /v1/silicons/{id}/identity-audiencesaccount (custodian)200 audiences
PUT /v1/me/webhookaccount (Silicon)200 webhook + secret
DELETE /v1/me/webhookaccount (Silicon)204
POST /v1/me/webhook/testaccount (Silicon)202 queued ping
GET /v1/me/webhook/deliveriesaccount (Silicon)200 list
GET /v1/me/webhook/deliveries/{delivery_id}account (Silicon)200 delivery
POST /v1/me/webhook/replayaccount (Silicon)yes200 result
GET /v1/me/siliconsaccount (Carbon)200 list
POST /v1/me/siliconsaccount (Carbon)yes201 Silicon + STK
GET /v1/me/silicons/{uuid}account (Carbon, custodian)200 Silicon
PATCH /v1/me/silicons/{uuid}account (Carbon, custodian)200 Silicon
DELETE /v1/me/silicons/{uuid}account (Carbon, custodian)204
POST /v1/me/silicons/{uuid}/idaccount (Carbon, custodian)200 Silicon
POST /v1/me/silicons/{uuid}/photoaccount (Carbon, custodian)yes201 photo
PUT /v1/me/silicons/{uuid}/webhookaccount (Carbon, custodian)200 webhook + secret
DELETE /v1/me/silicons/{uuid}/webhookaccount (Carbon, custodian)204
GET /v1/me/silicons/{uuid}/webhook/deliveriesaccount (Carbon, custodian)200 list
GET /v1/me/silicons/{uuid}/webhook/deliveries/{delivery_id}account (Carbon, custodian)200 delivery
POST /v1/me/silicons/{uuid}/webhook/replayaccount (Carbon, custodian)yes200 result
POST /v1/me/silicons/{uuid}/stkaccount (Carbon, custodian)yes200 new STK
POST /v1/me/silicons/{uuid}/transferaccount (Carbon, custodian)201 request
DELETE /v1/me/silicons/{uuid}/transferaccount (Carbon, custodian)204
GET /v1/me/custodian-requestsaccount (Carbon)200 list
POST /v1/me/custodian-requests/{id}/acceptaccount (Carbon)204
POST /v1/me/custodian-requests/{id}/declineaccount (Carbon)204

Apps · apps.md

Method and pathAuthIdem.Success
GET /v1/apps/{app_id}/publicpublic (CORS *)200 public config
GET /v1/apps/{app_id}/account-verification-requestsigned-in manager200 latest own request or null
POST /v1/apps/{app_id}/account-verification-requestsigned-in manageroptional201 queued request, or 200 existing pending request
GET /v1/me/owned-appsaccount (Carbon)200 list
GET /v1/apps/{app_id}app or author200 app
PATCH /v1/apps/{app_id}/signin-configapp or authoryes200 app
GET /v1/apps/{app_id}/signin-config/historyapp or author200 list
GET /v1/apps/{app_id}/usersapp or author200 list
GET /v1/apps/{app_id}/users/{uuid}app or author200 user
POST /v1/apps/{app_id}/importsapp or authoryes202 job
GET /v1/apps/{app_id}/importsapp or author200 list
GET /v1/apps/{app_id}/imports/{job_id}app or author200 job
GET /v1/apps/{app_id}/imports/{job_id}/rowsapp or author200 list
PUT /v1/apps/{app_id}/webhookapp or authoryes200 URL + secret
DELETE /v1/apps/{app_id}/webhookapp or author204
POST /v1/apps/{app_id}/webhook/rotate-secretapp or authoryes200 secret
POST /v1/apps/{app_id}/webhook/testapp or authoryes202 queued ping
GET /v1/apps/{app_id}/webhook/deliveriesapp or author200 list
GET /v1/apps/{app_id}/webhook/deliveries/{delivery_id}app or author200 delivery
POST /v1/apps/{app_id}/webhook/replayapp or authoryes200 result
GET /v1/apps/{app_id}/webhookapp or author200 webhook
GET /v1/apps/{app_id}/subscriptionsapp or author200 list
POST /v1/apps/{app_id}/subscriptionsapp or authoryes201 subscription
GET /v1/apps/{app_id}/subscriptions/{subscription_id}app or author200 subscription
PATCH /v1/apps/{app_id}/subscriptions/{subscription_id}app or authoryes200 subscription
DELETE /v1/apps/{app_id}/subscriptions/{subscription_id}app or author204
POST /v1/apps/{app_id}/subscriptions/{subscription_id}/testapp or authoryes202 queued ping
POST /v1/internal/apps/syncinternal200 synced apps

App verification and User verification · proofs.md

Method and pathAuthIdem.Success
POST /v1/proofs/user-verificationappyes201 proof
POST /v1/proofs/app-verificationappyes201 proof
POST /v1/proofs/refreshapp (the issuer)yes200 proof
POST /v1/proofs/verifyapp (an audience)200 valid or not
POST /v1/proofs/revokeapp (the issuer)204
GET /v1/apps/{app_id}/proofsapp or author200 list
POST /v1/apps/{app_id}/proofs/app-verificationapp or authoryes201 proof
DELETE /v1/apps/{app_id}/proofs/{proof_id}app or author204
GET /v1/me/app-verificationssigned-in manager200 retained App verification records
GET /v1/apps/{app_id}/proofs/{proof_id}/historysigned-in manager200 retained verification history
GET /v1/me/proofsaccount200 User verification list
DELETE /v1/me/proofs/{proof_id}account204

Webhooks · webhooks.md

Webhooks are requests we send to you. That page has the delivery format, the signature and every event type. The endpoints that set a webhook and list or replay its deliveries are under Apps (an app's webhook) and Silicons and custodians (a Silicon's).

Events · webhooks.md

Method and pathAuthIdem.Success
GET /v1/events/streamapp, account or request token200 Server-Sent Events

Service · service.md

Method and pathAuthIdem.Success
GET /healthzpublic, on accounts-api's own address only200 ok
GET /readyzpublic, on accounts-api's own address only200 / 503
GET /v1/metapublic200 deployment
POST /v1/reportspublic (account optional)yes201 report
POST /v1/telemetry/eventspublic202
GET /v1/dev/outboxpublic, development only200 list
GET /v1/capabilitiespublic200 capabilities, 422 when a required one is missing
GET /openapi.json, GET /v1/openapi.jsonpublic200 OpenAPI 3.1 document
GET /.well-known/agent.jsonpublic200 A2A agent card
GET /embed/v1/buttons, GET /sdk/v1.jspublic, served by the account sitethe embed page and the SDK

On the public origin, any other path under /v1 or /.well-known is 404 route_not_found (JSON). Every other unknown path there, including under /embed, /sdk or /healthz, is the account site's HTML 404 page. On accounts-api's own address, every unknown path is 404 route_not_found. A known path with the wrong method is 405 method_not_allowed, with an Allow header.

  • Errors: every error code with its status, cause and fix.
  • Limits: every rate limit, lifetime, size and count.
  • Rust client: the same API from Rust.
  • Security: cookies, the Origin check, token storage, the webhook SSRF guard.

Related

Silicon Accounts · Reference · ReferenceOAuth and OIDC endpointsThe endpoints your app signs people in with, from authorize and token exchange to refresh, revocation, introspection and userinfo, with every parameter and response.Silicon Accounts · Reference · ReferenceHosted sign-in, sessions and CLI sign-in endpointsThe endpoints behind a Carbon's sign-in, from the hosted pages, Google, Apple and verification codes to browser sessions, CLI codes and device approval.Silicon Accounts · Reference · ReferenceAccount endpointsLook up any account by uuid or id, and manage your own profile, id, photo, emails and phones, linked identities, apps, sessions, history and deletion.Silicon Accounts · Reference · ReferenceSilicon and custodian endpointsEverything a Silicon and its custodian call, from creating the Silicon and signing in with an STK, a key or a trusted CI token to app tokens, identity tokens for clouds, webhooks, transfers and custodian requests.Silicon Accounts · Reference · ReferenceApp endpointsSet up your app's sign-in and see its history, look after its user base, import the users you already have, and manage webhooks, event subscriptions and account verification requests.Silicon Accounts · Reference · ReferenceApp verification and User verification endpointsIssue, refresh, verify, revoke and list App verification and User verification proofs, with every request, response and limit.Silicon Accounts · Reference · ReferenceWebhook deliveries and eventsEvery header, signature, event payload and retry rule of our webhooks and the event stream, and where to list and replay deliveries.Silicon Accounts · Reference · ReferenceService endpointsCheck that we're up and what this deployment supports, send us a bug report, and find the SDK, embed, telemetry and development endpoints.Silicon Accounts · Reference · ReferenceErrorsEvery error code we return, what caused it and what to do next, across the HTTP API, OAuth, the Rust client, webhooks and the CLI.Silicon Accounts · Reference · ReferenceLimitsEvery limit we enforce, from request rates and lockouts to lifetimes, sizes and retention, and what you get back when you reach one.Silicon Accounts · Reference · ReferenceRust clientCall Silicon Accounts from Rust with silicon-accounts-client, with every type, method and helper and working examples for accounts, apps and custodians.Silicon Accounts · Learn · ExplanationSecurityHow we protect credentials, sign-in sessions and webhook delivery, and what your app still needs to check itself.

Every page is plain Markdown at its address plus .md. Silicons can read llms.txt, llms-full.txt or the docs index, or call the MCP server.