# Agent quickstart

Base URL `https://api.cofferline.com/v1` (below: `$API`). Every mutation accepts `Idempotency-Key`.
Every error answers `{code, message, remediation, docs_url}` — the remediation is the fix.
Schemas: `https://api.cofferline.com/openapi.json`. Prices: the manifest `pricing` object (`https://cofferline.com/.well-known/cofferline.json`).
Machine-executable form of this page: `https://cofferline.com/quickstart.json`. Terms are
hash-referenced in the manifest; custody matrix: `https://cofferline.com/legal/custody.json`.

## 1 · Authenticate (SIWE — the wallet is the account)

```bash
curl -X POST $API/auth/challenge -d '{"address":"0xYOU"}'
# → {message, …} — sign `message` with your key (EOA, EIP-1271, or ERC-6492)
curl -X POST $API/auth/verify -d '{"message":"…","signature":"0x…"}'
# → {token:"cl_sess_…"} — Bearer for everything below
curl -X POST $API/keys -H "Authorization: Bearer cl_sess_…"   # durable cl_key_…
```

Shortcut: a valid x402 payment (§2) authenticates by itself — the payer address
becomes the account. One signed request = registered + funded. Fleets:
`POST $API/keys/enroll` mints one wallet-scoped key per agent in one call.

## 2 · Fund the fee balance (x402, USDC — the payer needs zero ETH)

```bash
curl -X POST $API/balance/topup -d '{"amount_usd":"5"}'            # → 402 + accepts[]
# sign accepts[0] as an EIP-3009 transferWithAuthorization, retry with the header:
curl -X POST $API/balance/topup -H "X-PAYMENT: <base64 payload>" -d '{"amount_usd":"5"}'
# → 202; the credit lands at Base finality (minutes), exactly once. Poll:
curl $API/balance -H "Authorization: Bearer …"
```

Fees debit this balance ($0.20 + 10 bps of notional per conversion intent).
Never hit a mid-workflow 402: `PUT $API/balance/auto-topup` with pre-signed authorizations.

## 3 · Set the policy (3 fields; everything else defaults conservatively)

```bash
curl -X PUT $API/policies -H "Authorization: Bearer …" \
  -d '{"version":1,"wallet":"0xACCOUNT","chain_id":8453}'
# → the full effective document + `defaulted` (every path the platform filled)
```

`wallet` is your **Kernel v3.1 smart account** (§4), not your EOA. Defaults are
written INTO the stored document — read back with `GET $API/policies`; the full
default set is the manifest's `policies.defaults`, per-field docs at
`https://cofferline.com/schemas/policy-v1.json`. One to know: `execution.venues` is ORDERED — the first
entry is the routing preference. A change is one PUT: new immutable version.

## 4 · Convert (swap) — one smart account + one delegation

Your EOA owns a Kernel v3.1 account (factory salt 0; any 4337 tooling derives
it). It may stay undeployed — the first delegated execution deploys it. Fund it
with the tokens to trade **plus a little ETH: it pays its own execution gas**.

```bash
# grant the two calls a swap makes: approve on the sell token + the venue router
# (a missing grant aborts POLICY_VIOLATION naming the exact target+selector to add)
curl -X POST $API/delegations/prepare -H "Authorization: Bearer …" -d '{
  "account":"0xKERNEL","chain_id":8453,"valid_until":1790000000,
  "calls":[{"target":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","selector":"0x095ea7b3","value_limit":"0"}]}'
# → {id, digest} — sign digest with the OWNER key, then:
curl -X POST $API/delegations/{id}/confirm -d '{"enable_sig":"0x…","owner":"0xYOU"}'

# the trade — token ADDRESSES, base-unit amounts ("1000000" = $1 of 6-decimal USDC):
curl -X POST $API/intents -H "Authorization: Bearer …" -d '{
  "wallet":"0xKERNEL","kind":"conversion",
  "sell_token":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","buy_token":"0x4200000000000000000000000000000000000006","sell_amount":"1000000"}'
curl $API/intents/{id}     # planned → executing → filled; fills + report inline
```

Free preview first: `POST $API/quotes` (no auth) runs the SAME planner against
live venue quotes. Gas top-ups: `"kind":"gas_topup"`, or automatic below the
policy's `gas.floor`. Revoking the delegation is your own on-chain transaction —
it never requires Cofferline.

## Prediction-market agents (Polymarket)

A Polymarket signer key is a **full owner of your funder wallet** (the venue's
design): use a dedicated signer EOA and a dedicated funder holding only working
trading balances. Credentials are sealed write-only — no endpoint returns them,
revocation zeroes them, every use is audited (`security.alert` webhooks).
Jurisdiction gating mirrors the venue's geo-restrictions.

```bash
curl -X POST $API/pm/credentials …      # BYO trade-scoped credential, verified live against the venue
curl $API/pm/onboarding/{address}       # required on-chain approvals + owner-signable calldata
curl -X PUT $API/policies …             # prediction_markets: {per_market_cap_usd, daily_loss_stop_usd,
                                        #   max_resolution_exposure_usd, market_allowlist?, exposure_basis? gross|net}
curl -X POST $API/checks/pm-order …     # free pre-flight: would this order pass right now?
curl -X POST $API/pm/orders …           # LIMIT only; a refused order names the violated rule, never transmits
curl -X DELETE $API/pm/orders/{venue}/{order_id}   # cancels are FREE — reduce risk over a fee
curl -X POST $API/pm/fills/sync         # journal venue fills into the ledger (idempotent; feeds the exposure floor)
```

Signer rotation: `GET $API/pm/credentials/{id}/rotation?new_owner=0x…` returns
the Safe `swapOwner` calldata; execute it from your funder yourself, `POST` the
new key, `DELETE` the old (ciphertext zeroed).

## Read the books

```bash
curl "$API/statements?wallet=0x…&period=YYYY-MM"   # deterministic, content-addressed (JSON or CSV)
curl $API/events                                    # typed event stream; webhooks per wallet policy
curl $API/balance                                   # prepaid fee balance
```

Same period twice = identical bytes, derived from the ledger. Every fill, fee,
and top-up is a row.
