Permits
A permit is the user’s approval for your app. It reads and signs for the wallets the user picked and for paper money, for 30 days.- Treat it like an access token. It acts for one user, within the wallets they picked, until it expires or is revoked. Store it on your server or in secure storage on the device, and never log it.
- Connect again before
expiresAt. Agents your app started then move to the new permit and keep running. - Disconnect with
POST /partner/disconnect. The permit is revoked, and agents your app started stop trading. Users can also disconnect your app in Connected apps on Circuit.
Connecting
Your app never handles a passkey.POST /partner/connectionswith your app id, an X25519 public key and an optionalreturnUrl. ThereturnUrlmust start with a URL registered for your app; app schemes such asyourapp://connectedwork.- Open the
urlit returns in a real browser. On iOS useASWebAuthenticationSession; on Android use a Custom Tab. Never use an embedded web view. - Poll
GET /partner/connections/{id}everyretryAfterMsuntilsealedPermitarrives. It stays available untilexpiresAt, five minutes after you started.
sealedPermit is base64url of a 32-byte ephemeral X25519 public key, a 12-byte IV, then AES-256-GCM ciphertext. The key is SHA-256 of circuit-permit-handoff:v1 ‖ X25519(your secret, ephemeral) ‖ ephemeral ‖ your public key. The reference client does this for you.
Conversations
- A conversation is a UUID your app picks. Send its next message with the same id to continue it.
- A message id is a UUID your app picks per message. Reuse it when you retry; a retry never acts twice.
- Polling: read the conversation again after
retryAfterMs. When it is null, nothing is in progress. - Replies are Markdown: CommonMark with GFM tables. Render them with any standard renderer.
Actions and controls
Ask proposes trades, transactions and agent changes as actions.- Act only on what’s listed. An action’s
decisionsand an agent’scontrolslist exactly what your app may send now. Offer them however your interface likes. stateis for display. Use it to style what you show, andmessagefor the detail. New states can appear.
Ids and amounts
- Ids show their type:
wal_wallets,hld_holdings,agt_agents,op_trades and transactions,aga_agent changes,conn_connections. Every row has one, and it never changes. Don’t parse them. - Amounts are decimal strings. A holding’s
amountis negative for a short or a debt, and itssymbolis the asset alone (BTC). USD values are decimal strings, or null when Circuit can’t price a holding.
Errors
A failed call answers its HTTP status and{ "error": "<message for the user>" }.
Every response carries
x-circuit-request-id. Include it when you report a problem.
Versions
Every call sendsCircuit-Partner-Version. The current version is 0.1.
- Circuit serves one version at a time. A call that sends another version gets a 400 naming the version Circuit serves.
- Within a version, changes only add. New fields, states, decisions and controls can appear; ignore the ones you don’t know.
- A change your app could notice ships as a new version. Circuit tells every registered app before it does.
- While the version starts with 0, the API is a preview. From 1.0, a version stays stable.
https://api.circuit.org/partner/openapi.json; each environment serves its own. Use it to generate a client in any language.