Skip to main content
Every other page in this reference documents one endpoint. This one runs the whole sequence in order, so you can see how the calls fit together before you build.

0. Before you start

You need an account and an API key — every private call below is HMAC-signed with it (X-Auth-Apikey, X-Auth-Nonce, X-Auth-Signature). See Authentication.
Check signature_type first. Authentication proves who you are; it does not let your client sign an order. A passkey wallet (3) signs only in the browser it was registered in — to trade from a script, add a signing key you hold the key for. Your own wallet (2) is scriptable as it is.

1. Read your wallet config

GET /api/v2/atlas/account/wallet This is the entry point to everything on-chain: it tells you which Safe is yours, what owns it, which contracts you are trading against, and whether you are ready to trade.
Read every address from here rather than hard-coding it — domain_name in particular is hashed into every order signature.

2. Make the Safe trade-ready

If safe_status is setup_required, the Safe still owes its approvals. Each entry in safe_setup.calls is { to, data, operation, nonce, hash }: sign it as a Safe SafeTx (EIP-712) with the Safe’s owner, then relay it. POST /api/v2/atlas/account/wallet/relay
The operator executes it and pays the gas; you get back { "tx": "0x…" }. Calls may arrive batched as one MultiSend call (operation: 1) or as several at sequential nonces — relay those in order. Re-read the config until safe_status is ready.
Do not place orders on setup_required. The order will rest on the book and then fail to settle — worse than being rejected. Only ready is safe to trade on. Full detail in The Safe.

3. Fund the Safe

Send USDC on Polygon to proxy_address from any wallet or exchange. There is nothing to call — the deposit is an ordinary on-chain transfer, and it is credited once it confirms. GET /api/v2/atlas/account/balances
balance_safe is your tradeable USDC — the mirror of what your Safe holds on-chain. balance / locked are the operator-held pool Calibri does not operate; they are always "0". See Balances.

4. Pick a market

Public, no authentication:

5. Sign and place an order

Read the market’s CTF config — the same funding config plus the market’s on-chain identifiers: GET /api/v2/atlas/account/wallet/markets/{id} → adds condition_id, yes_token_id, no_token_id. Build the EIP-712 Order, sign it, and post it: POST /api/v2/atlas/account/orders
Returns 201 with the order object. The struct, the unit rules and the signature types are in Signed orders — three things catch people out:
  • Units are 6-decimal. takerAmount = volume × 1e6, makerAmount = price × volume × 1e6.
  • Sign the served domain_name, never a copied constant.
  • On a passkey Safe (signature_type: 3), sign the SafeMessage — not the order hash. Safe re-wraps the hash before checking it, so signing orderHash directly is rejected as signed_order signature was not accepted by the maker wallet, even though the signature recovers to your key when you check it yourself. Recipe under type 3 in Authentication.
  • Placing locks stake plus the maximum taker fee the fill could incur; the unused reserve is released when the order fills, rests or is cancelled. Budget stake + max fee, not just the stake — see Fees.

6. Follow the order

GET /api/v2/pythia/orders?state=wait — your resting orders. GET /api/v2/pythia/orders/{id} — one order, open or terminal. Cancel with POST /api/v2/pythia/orders/{id}/cancel → { "id": 1420, "state": "cancel" }. Then the results of the fill:
Orders are placed through /atlas (so the signature is validated and attached) and read back from /pythia. Listing and cancelling are the same calls for every order, however it was placed.

7. Stream it instead of polling

One connection carries public and private streams together:
Each message is keyed by the stream name, so one handler switches on the key:
order, contract, balance and position replace every poll in step 6.
Order-book increments carry a sequence. If it skips, re-subscribe — a client that ignores the gap quotes against a book that no longer exists.
Full channel list and payloads: WebSocket streams.

The whole flow, once more

1

Authenticate

Mint an API key; HMAC-sign every private request. Check signature_type.
2

Wallet config

GET /account/wallet — Safe address, contracts, domain, safe_status.
3

Approvals

Sign each safe_setup.calls entry as a SafeTx; relay until ready.
4

Fund

Send USDC on Polygon to proxy_address; watch balance_safe.
5

Place

Per-market config → EIP-712 Order → POST /account/orders.
6

Follow

GET /pythia/orders/{id}, or subscribe to order / contract / balance.

Authentication

HMAC signing, and why it is not authorisation to trade.

The Safe

Deploy, approve and fund — step 1–3 in full.

Signed orders

The EIP-712 domain, the Order struct, and the unit rules.

WebSocket streams

Every channel, payload and reconnection rule.

Models

The exact shape of everything the calls above return.