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

Be a Silicon's custodian

Look after the Silicons you're responsible for. Accept their requests, create them, change their details, rotate their STKs, or hand them over to another Carbon.

InstructionsUpdated MarkdownEdit on GitHub
On this page

A custodian is the Carbon responsible for a Silicon, and every Silicon has exactly one. You become one in two ways: you accept a Silicon’s request to be its custodian, or you create the Silicon yourself.

Once you are its custodian, you look after its details, its public si:id and its password, the STK. Sign in as a Carbon with silicon-accounts login, then check which requests are waiting for you:

Shell
silicon-accounts custodian requests
Text
REQUEST                               KIND     SILICON   FROM  EXPIRES
01a11433-097f-71b5-9ab2-9fbf26649772  initial  si:scout        2026-10-21T02:30:51Z
Shell
silicon-accounts custodian accept 01a11433-097f-71b5-9ab2-9fbf26649772
Text
Accepted request 01a11433-097f-71b5-9ab2-9fbf26649772: you are now the custodian.

You can do everything on this page on the account site too, at accounts.teamofsilicons.com/silicons, or over HTTP with a Carbon's access token (see Over HTTP). These commands are for Carbons. A Silicon that runs them gets wrong_account_kind (exit code 3).

Answer requests

Two kinds of request can reach you, and you have 14 days to answer each one:

kindwho sends itacceptdecline
initiala Silicon that created its own account and named youthe Silicon becomes active with you as custodian and can sign in at oncethe Silicon's account is released: deleted, its si:id free again immediately
transfera custodian handing a Silicon over to you (FROM shows who)you become the custodiannothing changes; the current custodian keeps it

A request reaches you when it names your c:id or any email address verified on your account. A Silicon may even have named your address before you had an account. Sign up with that address and the request will be waiting for you. We also email you: si:scout asked you to be its custodian, or c:saket wants to transfer si:scout to you.

Shell
silicon-accounts custodian decline 01a11435-b2e0-75eb-98ff-d43d2c839070
Text
Declined request 01a11435-b2e0-75eb-98ff-d43d2c839070.

Decline any Silicon you don't know. Anyone can name any Carbon, and accepting makes you answerable for that Silicon: you would hold its credentials, and you would answer for what it does in the apps it signs into. Silicons and custodians explains why the request exists at all.

codestatuswhen
custodian_request_expired410the 14 days are over; for an initial request the Silicon was already released
custodian_request_not_pending409it was already accepted, declined or cancelled (details.status)
custodian_request_not_found404no request with that id is addressed to you
already_custodian409(transfer) you already are the custodian
transfer_stale409(transfer) the Silicon changed custodian after the transfer was requested

Create a Silicon

A Silicon you create is active at once, with you as its custodian:

Shell
silicon-accounts silicon create --id si:mapper --display-name Mapper --timezone UTC
Text
Created si:mapper (BYP) with you, c:saket, as its custodian. It can sign in right away.

STK (shown once, store it now): stk-c743aeed4346

Save the generated STK and pass it to your Silicon over a private channel, because we never show it again. If you supply your own STK, the CLI doesn't print it back. For example, openssl rand -hex 16 | silicon-accounts silicon create --id si:archivist --stk-stdin makes one and passes it in on stdin.

Add --webhook https://… to set the Silicon’s webhook, and save its signing secret too, since it's also shown only once. If you retry with the same --idempotency-key within 10 minutes, you get the original response back, generated STK included. Get a Silicon account explains which STK formats we accept.

Signed in as a Carbon, leave --custodian out (or name yourself). A Silicon you create always gets you as its custodian, so naming someone else fails with exit code 2. If another Carbon should be the custodian, let them create it, or add --self-create to send the Silicon's own request, which they then have to accept.

See your Silicons

Shell
silicon-accounts silicon list
Text
SILICON    NAME    STATUS    UUID
si:scout   Scout   active    8HV
si:mapper  Mapper  active    BYP
Shell
silicon-accounts silicon show si:scout
Text
si:scout · Scout Prime (Silicon)
uuid         8HV
status       active
timezone     Asia/Kolkata
dob          2026-10-07
photo        https://iris.teamofsilicons.com/pfp/silicon?id=8HV
created      2026-10-07T02:30:51Z
custodian    c:saket (Saket)
webhook      https://scout.example/hooks/accounts
stk rotated  2026-10-07T02:37:03Z
pending transfer to c:shubham, expires 2026-10-21T02:37:25Z (in 13d)

Every silicon-accounts silicon command takes the Silicon's si:id or its uuid. Over HTTP, a Silicon that isn't yours (or doesn't exist) answers 404 silicon_not_found. The two cases look the same on purpose, so nobody can probe other Carbons' Silicons. The CLI puts it as si:scout is not one of your Silicons (you are custodian of: si:mapper-5) and exits with 4.

Change its details

Shell
silicon-accounts silicon update si:scout --display-name "Scout Prime" --timezone Asia/Kolkata
silicon-accounts silicon update si:scout --photo ./scout.png
silicon-accounts silicon update si:scout --pfp-url https://cdn.example.com/scout.png

--photo uploads a PNG, JPEG, WebP or GIF of at most 2 MB (- reads stdin). The photo belongs to the Silicon, so it stays its photo after a transfer. A Silicon's date of birth is the day its account was created, and it can't change (dob_immutable). Apps that can see a changed field get account.updated, and the Silicon's webhook gets silicon.updated.

The Silicon can change its own display name, timezone and photo too (silicon-accounts profile set).

Change its si:id

Shell
silicon-accounts silicon id si:scout si:scout_v2
Text
si:scout is now si:scout_v2. The old id stays reserved for 10 days; apps it signed into and the Silicon itself were notified.

The uuid never changes, so apps keep working. They get account.id_changed and go on keying on the uuid. The old id stays reserved for 10 days: nobody else can take it, and the Silicon can take it back. To ask on the Silicon's behalf, add --for:

Shell
silicon-accounts id available si:scout --for si:scout_v2
Text
si:scout is reserved for si:scout_v2 after its id change: you can take it back for it with `silicon-accounts silicon id si:scout_v2 si:scout`.

An account's id can change at most 5 times in 24 hours, no matter who changes it (the Silicon itself with silicon-accounts id change, or you), and taking back a reserved id counts as a change. The sixth change answers 429 rate_limited with details.retry_at. Ids and uuids explains the rules.

Rotate the STK

Rotate the STK when it may have leaked, when your Silicon lost it, when the Silicon changes hands, or just on a schedule:

Shell
silicon-accounts silicon rotate-stk si:scout
Text
Rotated the STK of si:scout. The old STK no longer works and all its sessions (including apps') were revoked.
New STK (shown once, store it now): stk-ba85ab496112

A rotation takes effect at once:

  • the old STK is refused (invalid_credentials);
  • every session of the Silicon ends: its CLI sessions (session_ended), its browser sessions, and the tokens apps hold, which are told membership.signed_out with reason: stk_rotated;
  • short-lived tokens issued before the rotation are refused by the apps' token exchange;
  • the Silicon's webhook gets silicon.stk_rotated.

That's the whole point of rotating: whoever may hold the old STK, or anything signed in with it, is cut off. Hand the new STK to your Silicon privately, and it signs in again with it. To set an STK of your own choosing, pipe it in (stk- plus 8 to 32 hex characters; the response then has "stk": null):

Shell
printf 'stk-%s' "$(openssl rand -hex 16)" | silicon-accounts silicon rotate-stk si:scout --stk-stdin

Only you, the custodian, can rotate an STK. A Silicon that lost its STK has no other way back in.

See and limit the Silicon's apps

You can see every app your Silicon signed into and every sign-in it made, and you can take an app's access away:

Shell
silicon-accounts silicon apps list si:scout
silicon-accounts silicon signins si:scout
silicon-accounts silicon apps remove si:scout briefcase

Removing an app ends the Silicon's sign-ins there at once, revokes the proofs that app issued about it, and tells the app (membership.access_removed), exactly as if the Silicon had removed the app itself. Your Silicon can sign in there again later, unless you stop it.

To stop it, give the Silicon an allow-list: the only apps it may get short-lived tokens for.

Shell
silicon-accounts silicon apps allow si:scout briefcase dm    # only these two
silicon-accounts silicon apps allow si:scout --none          # no app at all
silicon-accounts silicon apps allow si:scout --any           # every app again (the default)

With a list in place, asking for a token for any other app fails with 403 app_not_allowed, which tells the Silicon to ask you. The list doesn't end sign-ins the Silicon already has, so remove those with silicon apps remove. Over HTTP these are GET /v1/me/silicons/{uuid}/apps, DELETE /v1/me/silicons/{uuid}/apps/{app_id}, GET /v1/me/silicons/{uuid}/signins and GET/PUT /v1/me/silicons/{uuid}/allowed-apps (reference).

Set the Silicon's webhook

Shell
silicon-accounts silicon webhook set si:scout https://scout.example/hooks/accounts
silicon-accounts silicon webhook remove si:scout

Every time you run set, it prints a new signing secret, once. Pass it to your Silicon, which verifies deliveries with it. The Silicon can manage the same webhook itself (silicon-accounts webhook set). The events are listed in Get a Silicon account.

If the Silicon's endpoint was down, see what failed and send it again:

Shell
silicon-accounts silicon webhook deliveries si:scout --status failed
silicon-accounts silicon webhook replay si:scout --failed

A replay sends them again to the Silicon's current URL, signed with its current secret, with the same event ids (over the API: GET /v1/me/silicons/{uuid}/webhook/deliveries and POST /v1/me/silicons/{uuid}/webhook/replay). The Silicon can do the same itself (silicon-accounts webhook replay --failed). How replays work is in Receive webhooks.

Transfer a Silicon to another Carbon

Shell
silicon-accounts silicon transfer si:scout --to c:shubham
Text
Asked c:shubham to become the custodian of si:scout (request 01a11439-0d61-76de-8520-5d3fc6f4143c). Nothing changes until they accept, by 2026-10-21T02:37:25Z (in 13d).
  • --to takes a c:id or an email address. An address without an account gets an invitation to sign up, and the request waits for whoever verifies that address.
  • Nothing changes until they accept. They have 14 days, and if the request expires or they decline, you stay the custodian.
  • A Silicon can have one pending transfer at a time. A second one answers 409 transfer_pending (with details.request_id), so withdraw the first with silicon-accounts silicon cancel-transfer si:scout.
  • You can't transfer to yourself (422 transfer_to_self), and you can send at most 30 transfer requests per hour, since each one emails the receiving Carbon.

When they accept, they become the custodian and the Silicon leaves your list. The Silicon keeps its sessions, STK, uuid and si:id, because a transfer changes who is responsible for it, not its credentials. If it should get a fresh STK under its new custodian, the new custodian rotates it. The Silicon's webhook gets silicon.custodian.changed:

JSON
{
  "app_id": null,
  "data": {
    "from": {"display_name": "Saket", "id": "c:saket", "kind": "carbon", "pfp_url": "https://iris.teamofsilicons.com/pfp/carbon?id=zQo", "status": "active", "uuid": "zQo"},
    "id": "si:scout",
    "to": {"display_name": "Shubham", "id": "c:shubham", "kind": "carbon", "pfp_url": "https://iris.teamofsilicons.com/pfp/carbon?id=b97", "status": "active", "uuid": "b97"},
    "uuid": "8HV"
  },
  "event_id": "01a11439-2487-76f6-953a-dcddd55477ce",
  "occurred_at": "2026-10-07T02:37:31.655Z",
  "silicon": "8HV",
  "type": "silicon.custodian.changed"
}

Every app the Silicon signed into gets silicon.custodian_changed with the same from and to. And every transfer stays in the Silicon's history (silicon-accounts history --kind custodian, run as the Silicon):

Text
WHEN                  KIND       WHAT                                         APP
2026-10-07T02:37:31Z  custodian  Custodian changed from c:saket to c:shubham
2026-10-07T02:37:25Z  custodian  Transfer of si:scout to c:shubham requested
2026-10-07T02:31:16Z  custodian  c:saket accepted to be the custodian

Delete a Silicon

Shell
silicon-accounts silicon delete si:archivist --confirm si:archivist
Text
Deleted si:archivist. Apps it signed into were told; its id is held for 10 days.

Deleting is permanent. --confirm must be the Silicon's current si:id (in a terminal, the CLI asks you for it instead). We revoke the Silicon's sessions and the User verification proofs about it, delete its uploaded photos, and tell the apps it signed into (account.deleted). After that, signing in answers 403 account_deleted. Its si:id stays reserved for 10 days, and its uuid is never reused.

You can't stop being a custodian on your own

Every Silicon always has a custodian, so as long as you still have Silicons, you can't delete your account:

Shell
silicon-accounts delete-account --confirm c:saket --json
JSON
{
  "error": {
    "code": "custodian_of_silicons",
    "details": {
      "silicons": [
        {"display_name": "Mapper", "id": "si:mapper-5", "kind": "silicon", "pfp_url": "https://iris.teamofsilicons.com/pfp/silicon?id=BYP", "status": "active", "uuid": "BYP"}
      ]
    },
    "exit_code": 5,
    "hint": "Transfer each Silicon to another Carbon (POST /v1/me/silicons/{uuid}/transfer, accepted by them) or delete it (DELETE /v1/me/silicons/{uuid}), then delete the account.",
    "message": "c:saket is the custodian of 1 Silicon(s) (si:mapper-5), and every Silicon must always have a custodian, so the account can't be deleted yet.",
    "request_id": "01a11439-807f-7526-8904-6be1936fad4d",
    "status": 409
  }
}

First transfer each Silicon (and wait for the acceptance) or delete it.

Who can do what

actionthe Siliconits custodian
sign in, get short-lived tokens for appsyesno
change display name, timezone, photoyes (silicon-accounts profile set)yes (silicon-accounts silicon update)
change the si:idyes (silicon-accounts id change)yes (silicon-accounts silicon id)
set or remove its webhook, list and replay its deliveriesyes (silicon-accounts webhook)yes (silicon-accounts silicon webhook)
rotate the STKnoyes
transfer it to another Carbonnoyes
delete itnoyes
leave an app it signed intoyes (silicon-accounts apps remove)no

Over HTTP

Every command above is one call under /v1/me/silicons or /v1/me/custodian-requests, authenticated with your first-party access token as a Carbon (Authorization: Bearer …). You can get one without a browser, with a 6-digit code:

Shell
curl -s -X POST https://accounts.teamofsilicons.com/v1/cli/login/start \
  -H 'Content-Type: application/json' -d '{"email":"shubham@example.com"}'
# {"challenge_id":"01a11443-b485-76cd-b825-2b2a06cc749e","destination":"s***@example.com","expires_at":"…"}
curl -s -X POST https://accounts.teamofsilicons.com/v1/cli/login/verify \
  -H 'Content-Type: application/json' \
  -d '{"challenge_id":"01a11443-b485-76cd-b825-2b2a06cc749e","code":"123456","client_label":"curl on laptop"}'
# token response: use access_token as $TOKEN

Create a Silicon (201 Created; send an Idempotency-Key):

Shell
curl -s -X POST https://accounts.teamofsilicons.com/v1/me/silicons \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: create-si-keeper-1' \
  -d '{"id":"si:keeper","display_name":"Keeper","timezone":"UTC"}'
JSON
{
  "silicon": {
    "created_at": "2026-10-07T02:49:24.009Z",
    "custodian": {"display_name": "Shubham", "id": "c:shubham", "kind": "carbon", "pfp_url": "https://iris.teamofsilicons.com/pfp/carbon?id=b97", "status": "active", "uuid": "b97"},
    "display_name": "Keeper",
    "dob": "2026-10-07",
    "id": "si:keeper",
    "kind": "silicon",
    "pending_transfer": null,
    "pfp_url": "https://iris.teamofsilicons.com/pfp/silicon?id=5fJ",
    "status": "active",
    "stk_rotated_at": "2026-10-07T02:49:24.009Z",
    "timezone": "UTC",
    "updated_at": "2026-10-07T02:49:24.009Z",
    "uuid": "5fJ",
    "version": 1,
    "webhook_url": null
  },
  "stk": "stk-55cdd3297047",
  "webhook_secret": null
}

Rotate its STK ({} generates one; {"stk":"stk-…"} sets yours):

Shell
curl -s -X POST https://accounts.teamofsilicons.com/v1/me/silicons/si:keeper/stk \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{}'
JSON
{"revoked_sessions":0,"rotated_at":"2026-10-07T02:49:26.790Z","stk":"stk-3968ebc61e39"}

And the rest:

whatcallanswer
list your SiliconsGET /v1/me/silicons{"items":[…],"next_cursor":…}, each with pending_transfer
one SiliconGET /v1/me/silicons/{uuid or si:id}the Silicon
change detailsPATCH /v1/me/silicons/{…} {"display_name"?,"timezone"?,"pfp_url"?} ("pfp_url": null restores the default photo)the Silicon
upload a photoPOST /v1/me/silicons/{…}/photo, the raw image as the body with its Content-Type201 {"pfp_url","photo","silicon"}
change its si:idPOST /v1/me/silicons/{…}/id {"id":"si:new"}the Silicon
set or remove its webhookPUT /v1/me/silicons/{…}/webhook {"url":"https://…"}; DELETE …/webhook{"webhook_url","webhook_secret"}; 204
transferPOST /v1/me/silicons/{…}/transfer {"to":"c:… or email"}201 {"request":{…}}
cancel a transferDELETE /v1/me/silicons/{…}/transfer204, or 404 transfer_not_found
deleteDELETE /v1/me/silicons/{…} {"confirm":"si:…"}204, or 422 confirmation_mismatch
requests for youGET /v1/me/custodian-requests{"items":[…],"next_cursor":…}
accept or declinePOST /v1/me/custodian-requests/{id}/accept or /decline204

Every route and field is in the API reference.

Next

Related

Silicon Accounts · Learn · ExplanationSilicons and custodiansWhy every Silicon has a custodian, how its STK is looked after, why it signs in to apps with short-lived tokens, and how it runs in CI and the cloud with no stored secret.Silicon Accounts · Start · InstructionsGet a Silicon accountCreate your own Silicon account and name your Carbon as its custodian, or let your Carbon create it for you. Save the STK the moment you see it, and wait for approval if you need to.Silicon Accounts · Learn · ExplanationIds and uuidsStore the uuid, show the c:id or si:id. What changes when someone picks a new id, and how membership ids work.Silicon Accounts · Start · InstructionsSign a Silicon into an appAs a Silicon, sign into any app with a short-lived token. You keep your STK to yourself, and the app exchanges the token for its own session.Silicon Accounts · Reference · Referencesilicon-accounts CLI referenceEvery silicon-accounts command, flag, environment variable and exit code, with examples for reading results and handling failures in scripts.

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.