> ## Documentation Index
> Fetch the complete documentation index at: https://docs.circuit.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Concepts

> Permits, polling, actions, ids, errors and versions.

## 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.

1. `POST /partner/connections` with your app id, an X25519 public key and an optional `returnUrl`. The `returnUrl` must start with a URL registered for your app; app schemes such as `yourapp://connected` work.
2. Open the `url` it returns in a real browser. On iOS use `ASWebAuthenticationSession`; on Android use a Custom Tab. Never use an embedded web view.
3. Poll `GET /partner/connections/{id}` every `retryAfterMs` until `sealedPermit` arrives. It stays available until `expiresAt`, 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](https://docs.circuit.org/apps-client.md) 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 `decisions` and an agent's `controls` list exactly what your app may send now. Offer them however your interface likes.
* **`state` is for display.** Use it to style what you show, and `message` for 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 `amount` is negative for a short or a debt, and its `symbol` is 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>" }`.

| Status | Means | Do |
| - | - | - |
| 400 | Circuit couldn't do this | Show `error` |
| 401 | The permit expired or was revoked | Connect again |
| 403 | The permit doesn't allow this, such as money leaving the user's accounts | Show `error` |
| 404 | Not found, or not visible to your app | Refresh what you show |
| 409 | It already changed | Read it again |
| 429, 503 | Busy | Retry after `Retry-After` seconds; resend a write only with the same message id |
| 500 | Circuit failed | Show `error` and report the request id |

Every response carries `x-circuit-request-id`. Include it when you report a problem.

## Versions

Every call sends `Circuit-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.

The whole contract is an OpenAPI 3.1 document at `https://api.circuit.org/partner/openapi.json`; each environment serves its own. Use it to generate a client in any language.

## Changelog

**0.1:** the first version: connecting, account, conversations, actions, agent controls and disconnect.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.