Documentation

Build on the execution layer.

Two ways in: talk to the gateway over MCP from an agent you already run, or call the REST endpoints directly. Same auth, same rails, same caps either way.

Base URLhttps://api.clause.trade AuthEd25519 keypair TransportREST + SSE Settles onRobinhood Chain (4663)

Quickstart

A clause is one sentence. The gateway compiles it into a numbered spec, dry-runs it, and only then will let you promote it to live. Three calls end to end.

quickstart.sh
# 1. compile a sentence into a spec
curl -X POST https://api.clause.trade/v1/compile \
  -H "authorization: Bearer $TOKEN" \
  -d '{"text":"rotate 2 ETH into $CASHCAT when pool liquidity clears $5M"}'

# 2. dry-run it (mandatory, cannot be skipped)
curl -X POST https://api.clause.trade/v1/clauses/cl_8f2a/dry-run \
  -H "authorization: Bearer $TOKEN"

# 3. promote to live under a hard cap
curl -X POST https://api.clause.trade/v1/clauses/cl_8f2a/deploy \
  -H "authorization: Bearer $TOKEN" \
  -d '{"rung":"live","cap_usd":250}'

A clause with no completed dry run returns 409 dry_run_required on deploy. There is no override flag.

Authentication

No API keys to leak. You register a public key, sign a server challenge to prove you hold the private half, then exchange a signed timestamp for a short-lived bearer token.

  1. RegisterPOST /v1/auth/register with your Ed25519 public key. Returns a did.
  2. ChallengeGET /v1/auth/challenge?did=... returns a nonce valid for 60s.
  3. VerifyPOST /v1/auth/verify with the signed nonce. Binds the key to the account.
  4. TokenPOST /v1/auth/token with a signed unix timestamp. Returns a bearer good for 15 minutes.
auth.py
# the private key never leaves your machine
sig = signing_key.sign(str(int(time.time())).encode())
r = requests.post(
    "https://api.clause.trade/v1/auth/token",
    json={"did": did, "signature": sig.hex()},
)
token = r.json()["access_token"]

Deployment ladder

Every clause sits on exactly one rung. You promote upward by explicit call. Nothing self-promotes, and a demotion takes effect on the next run boundary.

RungTouches fundsCap source
monitorNevern/a
paperSimulated onlyNotional, your choice
liveYes, cappedWallet balance and staked tier

A live clause holds its own capped wallet, deployed as a contract on Robinhood Chain (chain id 4663, ETH for gas). The cap is checked by that contract at signing time, and every run writes one line you can pull from robinscan.io.

Compile a clause

POST /v1/compile turns prose into a spec. If the sentence is ambiguous the response carries questions instead of a spec, capped at two.

response.json
{
  "clause_id": "cl_8f2a",
  "rules": [
    { "n": 1, "kind": "trigger", "expr": "pool_liquidity_usd > 5000000" },
    { "n": 2, "kind": "size",    "expr": "0.05 * book" },
    { "n": 3, "kind": "exit",    "expr": "pnl <= -0.02 or elapsed > 8h" }
  ],
  "venue": "robinhood-chain",
  "needs_dry_run": true
}

Execute

Writes are asynchronous. Every mutating call returns a task_id immediately; add ?wait=true to block up to 60 seconds instead of polling.

EndpointDoes
POST /v1/swapRoute and fill a spot swap, bridging when the funds sit elsewhere
POST /v1/ordersLimit orders with optional take-profit and stop-loss hooks
GET /v1/quoteBest quote for a pair on Robinhood Chain, across routers
GET /v1/token/{address}On-chain metadata plus live price, liquidity and volume
GET /v1/tasks/{id}Poll any async task to completion

Streams

GET /v1/clauses/{id}/stream is server-sent events. Each run emits the same ordered sequence, so a client can render progress without guessing.

connectedstream open planningspec resolved, data being pulled tool_calla venue or data source is queried tool_responseresult returned to the planner decisionfire or hold, with the reason fillorder acknowledged by the venue donerun closed and written to the audit log

MCP connector

Point any Model Context Protocol client at the gateway and CLAUSE shows up as native tools. Same rails, same caps as the REST path.

mcp.json
{
  "mcpServers": {
    "clause": {
      "url": "https://api.clause.trade/mcp",
      "transport": "sse"
    }
  }
}

Verified against Claude Desktop, ChatGPT, Cursor, and Hermes Agent.

Caps and kill switch

A live clause draws from a wallet funded only for that clause. It cannot reach any other balance, and the cap is enforced at signing time, not in the UI.

  • One wallet per clause, deployed on Robinhood Chain. No shared treasury, no pooled balance.
  • POST /v1/clauses/{id}/halt stops mid-run, cancels open orders, freezes the wallet.
  • Keys are generated and used inside a hardware enclave. Export to your own wallet whenever you want.

Errors

CodeMeaning
400 ambiguous_clauseSentence needs the clarifying answers returned in the body
401 stale_signatureSigned timestamp drifted more than 30s
409 dry_run_requiredDeploy attempted before a dry run completed
422 cap_exceededRequested size is above the wallet cap or staked tier
423 clause_haltedKill switch is engaged on this clause

The gateway opens with the token.

Endpoints are frozen and documented. Keys are issued to the first cohort at launch on ponsfamily.com.