# Clear API

Hand Clear a signed transaction to deliver and track through its on-chain outcome. Set a deadline when timing matters; re-sign if the bytes expire. Non-custodial: you sign, Clear relays the bytes, never your keys.

You are helping a user call this API. This document is the complete
contract: every endpoint, its parameters and request body, the auth, and
the MCP surface. Generate runnable `curl`/TypeScript/Python on demand
using the values below; replace the placeholder key with the user's real
`k256_live_` key.

- Base URL: `https://api.k256.xyz`
- Data plane: `https://api.k256.xyz/v1/clear`
- OpenAPI: `https://api.k256.xyz/clear/api/spec.json`
- MCP (for agents): `https://api.k256.xyz/clear/mcp` (server name `k256-gateway`) — the same operations as 1:1 tools.
- MCP writes need one extra argument: every tool whose `Action` below is `write` requires `confirm_mcp_write: true`. Reads take no such argument.
- Auth: every request needs `Authorization: Bearer <YOUR_API_KEY>`. Never put the key in a URL query string.

Clear delivers and tracks caller-signed Solana transactions non-custodially. Inclusion is not guaranteed. HOSTS — every SEND goes to https://clear-<cluster>.k256.xyz; GET https://api.k256.xyz/v1/clear/endpoints lists the configured per-cluster send hosts. Endpoint availability does not establish that the Solana cluster is progressing. Use devnet for tests without spending mainnet SOL. Every READ, status poll, and cancel goes to https://api.k256.xyz. Two ways in, same engine: (1) Structured: POST https://clear-<cluster>.k256.xyz/v1/clear/intents/send with signed bytes (v1, v0, or legacy) — blockhash, last_valid_block_height and idempotency_key are all OPTIONAL (derived from the bytes; idempotency defaults to the tx signature). Returns an intent_id. Read it once at GET https://api.k256.xyz/v1/clear/intents/:id, then follow it LIVE on GET https://api.k256.xyz/v1/clear/events — one route, three renderings: SSE (Accept: text/event-stream, resume with Last-Event-ID), JSON long-poll (resume with ?cursor=<seq>), or WebSocket (resume with ?after=<seq>; browsers mint a 30s ?token= at GET /v1/clear/events/ws-token). No query = your whole workspace feed; ?id=<lc_… or bn_…> = that one execution. Every frame is {seq, event, payload} — seq is the delivery cursor (the same integer on every transport), payload.version is the lifecycle clock (apply an event only when its version is newer than the snapshot you hold). k256.ready marks replay complete; k256.gap means history rotated out — refetch the canonical GET and resume. (2) Drop-in RPC: POST https://clear-<cluster>.k256.xyz is a Solana JSON-RPC endpoint (the hostname IS the RPC URL — no path or cluster field needed; /v1/clear/rpc/<cluster> also works). sendTransaction answers the standard {jsonrpc, result: <base58 signature>, id}; parameters, structural errors, and preflight errors match agave. With skipPreflight:true, Clear validates locally, begins delivery, durably accepts the exact bytes, and returns the standard signature without waiting for continued landing. Bytes that fail validation are never broadcast and are recorded as terminal status invalid at X-Clear-Status-Url. With preflight enabled, Clear waits for the requested simulation and returns its error before sending. sendTransaction's own maxRetries is HONORED as a give-up bound: absent (the default) Clear drives your bytes for their whole validity life; set it for a delivery budget of min((maxRetries + 1) x 4, 512) slots, so maxRetries:0 permits 4 slots — settling the intent as canceled with reason leader_budget_exhausted (visible at X-Clear-Status-Url and in callbacks). Every other method keeps standard Solana JSON-RPC behavior. Migrate by changing only your RPC URL (auth via Authorization: Bearer <key> or key-in-path /k/<key>). Accepted sends can add X-Clear-Intent-Id, X-Clear-Status-Url, X-Clear-Cluster, X-Clear-Signature, X-Clear-Commitment, X-Clear-Dedup, X-Clear-Reference-Id, and X-Clear-Hint response headers. Identity & idempotency: on the drop-in, identical bytes ALWAYS collapse to one durable intent within a cluster because the transaction signature is the identity. Send X-Clear-Reference-Id (or Idempotency-Key) to tag the intent; the intent API additionally takes an explicit idempotency_key of your own, so a retry collapses even when you did not keep the signature. That key is bound to the bytes it first accepted: resending the SAME bytes replays the existing intent, while different bytes under the same key are refused (409 idempotency_key_reused) rather than silently collapsed — two different transactions must never become one send. To replace expired bytes on an intent you already have, re-sign it by passing its intent_id, not by reusing the key. Look an intent up by signature at GET https://api.k256.xyz/v1/clear/intents/<signature>?cluster=<cluster>, or by your reference at GET https://api.k256.xyz/v1/clear/feed?search=<your-reference-id>. Clear continues delivery while the signed bytes remain valid and no landing has been observed. Prefer to stop sooner? Set give_up_after_slots on the structured send (or maxRetries on the drop-in): if it has not landed within your bound, Clear settles it canceled with reason leader_budget_exhausted and the canceled callback tells you — ideal for swaps priced for the next slot or two. The intent timeline records every accepted send and every terminal outcome, including locally rejected invalidity. BUNDLES — POST https://clear-<cluster>.k256.xyz/v1/clear/bundles coordinates several signed transactions as one tracked bundle. `mode` is required: `sequential` (each step starts only after the prior reaches the commitment target), `parallel` (all at once), or `dag` (a step starts when every index in its `after` array has landed). Up to 20 transactions. `on_failure` is `stop` (freeze the remaining steps) or `continue` (run independent work anyway); a failed step always blocks its own descendants. A bundle is NOT atomic — a step that lands cannot be un-landed, and each child keeps its own intent lifecycle and evidence. Bundles send immediately; `release` is not accepted. Poll GET https://api.k256.xyz/v1/clear/bundles/:id; terminal status is completed, completed_with_failures, stopped, or canceled. Cancel with POST https://api.k256.xyz/v1/clear/bundles/:id/cancel — never-started steps freeze, and a step already on the wire can still land. CALLBACKS — set `callback: {url, on: [...]}` on a send or a bundle and Clear POSTs each subscribed transition. CREATE A SIGNING SECRET FIRST (POST https://api.k256.xyz/v1/clear/callback-secret, shown once) — a send carrying a callback is REJECTED 400 without one. Verify each delivery from X-Clear-Signature: t=<unix_seconds>,v1=<hex>, where v1 = hex(hmac_sha256(secret, `<t>.<raw body>`)). Deliveries retry for ~24h then dead-letter; re-arm one with POST /v1/clear/intents/:id/callbacks/:delivery_id/resend. Callback failure never holds up landing. RECOVERY — `needs_resign` is NOT terminal: the signed bytes expired (blockhash lapsed or the durable nonce moved) and Clear cannot legally retry them. Sign the SAME action again and POST it to /v1/clear/intents/send with the SAME intent_id — Clear continues that intent instead of creating a new one. The status read names exactly what to re-sign. REFERENCE INTEGRATION — https://github.com/quiknode-labs/k256-clear-nextjs-example is a plain-HTTP Next.js example for wallet signing, server-side API-key custody, reload-safe watching, re-signing, and cancellation. It uses no k256 SDK. Scope: it demonstrates the SINGLE-SEND path only and does not show bundles, callbacks, fee quotes, or /v1/clear/events, so use this reference for those endpoints rather than that repository. V1 TRANSACTIONS — Prefer v1 when your signer and target cluster support it. Set explicit computeUnitLimit and loadedAccountsDataSizeLimit before signing: omitted v1 limits mean zero, not legacy defaults. v1 signs a total priority fee in lamports, not a per-CU rate. Clear preserves the version you signed; it never converts signed bytes. The anonymous devnet demo builds v1 by default. CLEAR FEES — GET https://clear-<cluster>.k256.xyz/v1/clear/fees/quote needs no key and takes no query parameters. The host selects the cluster and the answer echoes it. Authenticated POST on the same URL accepts {} or optional `urgency`, `writable_accounts`, `transaction`, `cu_limit`, and `max_spend_lamports`, and returns a `quote_id`. Every 200 carries `recent_blockhash` and `last_valid_block_height`; if `pay` is false, omit SetComputeUnitPrice. A send may carry `quote_id` to correlate the quote with that send. It is optional metadata and never participates in admission or landing. Re-quote after `re_quote_after_ms` if you have not sent yet. LANDING CONTROLS — landing is automatic: Clear decides the fastest safe way to deliver your transaction; you don't configure it. Your TWO controls are outcome-shaped: (1) the avoid list: GET/POST /v1/clear/avoid-list — validators, AS networks, countries, and client software families Clear will never send your transactions through (block-only by design: there is no require-list; saved changes take time to apply and do not affect transactions already sent); and (2) the per-send give-up bound: give_up_after_slots on a structured send, or maxRetries on the drop-in RPC — land within your bound or settle as canceled (reason leader_budget_exhausted) so you can decide your next action. Cancellation stops future delivery attempts; it does not invalidate signed bytes or prevent a later landing. Everything else is Clear's job.

## Endpoints

### `POST /v1/clear/intents/send` — Send a transaction
- Action: `write` · MCP tool: `clear.intents_send`
- Base URL for THIS endpoint: `https://clear-{cluster}.k256.xyz` — Clear's send endpoint — geo-routed to the nearest location for the fastest submission; it serves the whole send path. Reads, status, and cancel stay on https://api.k256.xyz. — `{cluster}` = `mainnet` | `devnet` | `testnet` (default `mainnet`; selects the `cluster` in this base URL — the host you send to)
- Hands Clear your signed transaction bytes (legacy or v0) and durably drives them to landing at your commitment gate (default confirmed). Non-custodial — Clear relays the signed bytes, never your key. Pass intent_id with freshly-signed bytes of the same action to re-sign an intent whose blockhash expired, instead of creating a new one. The acknowledgement returns the known signature and intent id immediately; poll status_url for the complete lifecycle and outcome.
- Request body (JSON, required):
  - `intent_id` — string — RE-SIGN an existing intent: pass its id with freshly-signed bytes of the SAME action (only the blockhash may differ) and Clear continues that intent — no new record. Omit to create.
  - `signed_tx_base64` — string (required) — The fully-signed transaction (feature-active v1, v0, or legacy), base64 wire bytes. Clear never sees your key — only these signed bytes.
  - `blockhash` — string — Optional — derived from the signed bytes when omitted; cross-checked against them when supplied.
  - `last_valid_block_height` — integer — Optional expiry height from getLatestBlockhash — lets Clear declare needs_resign precisely instead of probing.
  - `cluster` — "mainnet" | "devnet" | "testnet" — Optional cross-check. The clear-<cluster>.k256.xyz hostname selects the cluster; omit this field for the simplest direct call. If supplied, it must match that host. Explorer and MCP calls use it to choose a host and default to mainnet. Ignored on re-sign because the intent already has a cluster.
  - `idempotency_key` — string — Optional dedup key (unique per workspace): a retry with the same key returns the existing intent instead of double-sending. Defaults to the transaction signature when omitted — so a plain retry of the identical signed bytes is already dedup-safe (it collapses to the same intent, never a double-send). The key binds to the bytes it first accepted: DIFFERENT bytes under the same key are refused (409 `idempotency_key_reused`) rather than collapsed, because two different transactions must never become one send. That binding is retained for at least 72 hours after the intent settles — long enough to cover a paused job or a queue drained the next working day; a retry arriving after it ages out is treated as a NEW operation, so a retry loop that may outlive that window should carry the original `intent_id` rather than rely on the key. To replace expired bytes on an intent you already have, pass its `intent_id` to re-sign — do not reuse the key.
  - `origin` — object — Where this came from — a label for the console feed, an optional return_url for re-signing at the source, and an opaque context echoed back.
  - `client_reference_id` — string — Your own id for this action — searchable in the feed and echoed in callbacks.
  - `give_up_after_slots` — integer — Opt-in give-up bound, in slots from your send (~0.4s each; one leader turn is 4). If the transaction has not landed once this many slots pass, Clear stops driving it and settles it as canceled with reason leader_budget_exhausted — the canceled callback fires and you decide what to do next (typically re-quote and send fresh bytes). Useful when the action goes stale fast, e.g. a swap priced for the next slot or two. Omit for the default: Clear drives the whole validity life of your signed bytes. On the drop-in RPC, Solana's own maxRetries maps to this bound ((maxRetries+1) x 4 slots).
  - `consumer` — string — The app/label you set on create — the console feed groups by it.
  - `kind` — string — Your own free-form classification for this send, echoed back on reads.
  - `commitment_target` — "confirmed" | "finalized" — The landing gate — when Clear considers it LANDED and applies your effect. Default CONFIRMED (~0.4-2s, supermajority-voted but theoretically reversible); choose finalized to wait for irreversibility (~15s). The same default applies on every door, including the drop-in RPC. processed is not offered: it can be rolled back and is never safe to act on. Clear always watches through finalized either way, whichever gate you pick.
  - `not_before` — integer — Execute NO EARLIER than this unix-ms — a lower bound, not an exact time. A future value holds it as a scheduled release; a past value means 'now' and lands immediately. Beyond the blockhash life minus landing margin (~48s at today's 400ms slots) it must be signed against a durable nonce.
  - `window_until` — integer — Landing window: broadcast now and keep trying until this unix-ms passes (then canceled if it never landed). Beyond the blockhash life (~60s at today's 400ms slots) it requires a durable nonce.
  - `trigger_spec` — any — Arm on a trigger: hold durably until you POST /intents/:id/fire (or arm_expires_at passes). Requires a durable nonce. The spec is yours — Clear stores it verbatim.
  - `arm_expires_at` — integer — TTL for an armed intent (unix-ms): if never fired by then, it cancels cleanly — nothing broadcast.
  - `collect_expires_at` — integer — How long a MULTISIG waits for its remaining signatures (unix-ms deadline). Optional — a partially-signed transaction defaults to 1 hour, and if the signatures never arrive it cancels cleanly with reason collecting_expired, nothing broadcast. Set it when your signing ceremony needs more (or less) time; the maximum is 24 hours. Ignored for a fully-signed transaction.
  - `callback` — object — Callbacks: Clear POSTs each subscribed transition to this URL, HMAC-signed with your workspace callback secret (rotate one first), retried ~24h. Deliveries fire in commit order but each retries independently — a retrying one does not hold later ones back, so key on the payload's event, not arrival order. Verify each delivery from its X-Clear-Signature header `t=<unix_seconds>,v1=<hex>`: v1 must equal hex(hmac_sha256(secret, `<t>.<raw body>`)).
  - `urgency` — "instant" | "standard" | "flexible" — Optional — how urgently you want this landed, independent of the priority fee (the fee lives in your signed bytes). "standard" (default) and "instant" prioritize speed; "flexible" is for non-time-critical work (settlement, batch) — Clear queues these for smoother delivery instead of rejecting when you're near the rate limit (a 200 instead of a 429). On the drop-in RPC path (raw bytes, no body field) the same choice rides the `X-Clear-Urgency` header.
  - `quote_id` — string — Optional — the `quote_id` from a keyed fee quote, to correlate that quote with this send. Correlation metadata only: never looked up, never part of admission or landing, and an unknown, expired, or malformed id never blocks the send. The drop-in RPC path (raw bytes, no body field) carries the same value in the `X-Clear-Quote-Id` header.
- Response (JSON):
  - `intent_id` — string — The durable Clear intent id. Poll status_url for the complete lifecycle and outcome.
  - `signature` — string | null — The transaction signature Clear accepted. Null only for a multisig transaction that is still collecting signatures.
  - `status` — "submitted" | "collecting" | "scheduled" | "armed" | "invalid" — The state at acknowledgement time. invalid means Clear durably recorded a rejected transaction and did not broadcast it; otherwise read status_url once and follow subsequent transitions live on GET /v1/clear/events?id=<intent_id>.
  - `status_url` — string — The absolute GET URL for the complete lifecycle, attempts, events, and final outcome.

### `POST /v1/clear/fees/quote` — Priority-fee quote
- Action: `read` · MCP tool: `clear.fees_quote`
- Base URL for THIS endpoint: `https://clear-{cluster}.k256.xyz` — Clear's send endpoint — geo-routed to the nearest location for the fastest submission; it serves the whole send path. Reads, status, and cancel stay on https://api.k256.xyz. — `{cluster}` = `mainnet` | `devnet` | `testnet` (default `mainnet`; selects the `cluster` in this base URL — the host you send to)
- The priority fee to put in SetComputeUnitPrice, priced from priority fees that recently landed on this cluster. The same answer hands you a fresh blockhash to build against and a quote_id to pass when you send, so quoting and sending are one step.

Send an empty body for a standard quote; add your writable accounts (and cu_limit) to price against the accounts your transaction write-locks — `pricing_scope` tells you which you got. A priority fee is one input to landing, never a guarantee of it.

When pay is false, omit the SetComputeUnitPrice instruction entirely rather than setting it to 0 — but read confidence first: "low" means Clear priced from limited or absent live data, not that the market is free.
- Request body (JSON, required):
  - `urgency` — "instant" | "standard" | "flexible" — Optional. Same vocabulary as Clear send. Defaults to "standard". Picks how far up the range of recently landed priority fees this answer is priced: instant prices highest, flexible lowest, standard between them. On this endpoint it changes the price and nothing else — it buys no promise about whether or when your transaction lands.
  - `writable_accounts` — string[] — Optional. Base58 pubkeys the transaction write-locks — the sharpest input. Supplying them makes the quote transaction-specific when Clear holds live per-account market signal for them; otherwise the quote stays network-wide and `sharpen` says so. Omitting them always prices network-wide. Unioned with any `transaction` writables.
  - `transaction` — string — Optional. Base64 legacy, v0, or feature-active v1 transaction/message. Clear extracts static writable keys and the declared compute limit. For v0 lookup-table addresses, pass the resolved writable keys in `writable_accounts`; this endpoint does not resolve lookup tables.
  - `cu_limit` — integer — Optional. The compute-unit limit (1..1_400_000). Enables the exact lamports estimate and `max_spend_lamports` cap math. Derived from `transaction` when it declares one.
  - `max_spend_lamports` — integer — Optional. Caps the total priority-fee estimate. Requires a resolvable `cu_limit` (explicit or declared in the transaction). When it binds, the response carries `constraint: "your_cap"`.
- Response (JSON):
  - `cluster` — string — The Solana cluster that was priced — mainnet | devnet | testnet. Echoed from the host so you can verify which network answered (the body never sends it).
  - `slot_context` — number — Scalar u64. The host cluster's observed chain tip when this answer was built. Not an object, not quote validity, not a promise of a future landing slot — just the tip the price was computed against. Present on every 200 (a 503 is returned rather than a guessed slot when the chain head can't be read).
  - `recent_blockhash` — string — A current recent blockhash for the same cluster, so you can build immediately without a separate getLatestBlockhash (legacy, v0, and v1). It is at CONFIRMED commitment (the freshest usable) — if you send it right away with preflight ENABLED, set preflightCommitment:"confirmed" (or skipPreflight:true), otherwise a not-yet-finalized blockhash fails preflight with -32002 BlockhashNotFound.
  - `last_valid_block_height` — number — The blockhash-validity bound paired with `recent_blockhash` (block-height expiry). This is blockhash validity, NOT fee validity.
  - `cu_price_micro_lamports` — number — Quoted micro-lamports per CU. For legacy/v0 use SetComputeUnitPrice; for v1 use est_priority_fee_lamports as the signed total priority fee after specifying your compute limit. Zero is an observed fee quote, not a landing guarantee.
  - `pay` — boolean — false exactly when cu_price_micro_lamports is 0 — then omit the SetComputeUnitPrice instruction entirely rather than setting it to 0. Read `confidence` before acting on it: "low" (with or without constraint: "degraded_data") means Clear priced from limited or absent live data, NOT that the market is currently free. It states the prices Clear observed, never whether your transaction will land.
  - `est_priority_fee_lamports` — number | null — Quoted total priority fee: ceil(cu_price_micro_lamports * cu_limit / 1_000_000). For v1, sign this value as priorityFeeLamports; do not put the micro-lamport rate in the total-fee field. Present only when cu_limit is known; null otherwise. A quote is not proof of a charge or landing.
  - `quote_id` — string — Opaque quote id ("fq_"+hex), returned by the KEYED POST only (the keyless GET omits it). Pass it into a Clear send as body.quote_id or the X-Clear-Quote-Id header to correlate the quote with that send. It is optional metadata and never participates in admission or landing; unknown, expired, or malformed ids never block a send.
  - `pricing_scope` — "transaction_specific" | "network_wide" — Whether this estimate is sized to your specific transaction's accounts ("transaction_specific", the sharpest) or to the network as a whole ("network_wide"). Supplying writable_accounts yields "transaction_specific" only when Clear holds live per-account market signal for them — otherwise the answer is honestly network-wide and `sharpen` names what would sharpen it.
  - `confidence` — "high" | "medium" | "low" — How much live data this answer rests on — nothing else. Not a probability, and not a statement about whether your transaction lands. "low" means Clear priced from limited data: cold or missing live facts (paired with constraint: "degraded_data"), thin history on the accounts you supplied, or too little live fee activity on this cluster to price it confidently (constraint may be null). Never a silent fallback.
  - `constraint` — "your_cap" | "capped_for_safety" | "degraded_data" | null — Single-valued reason the answer was bounded, or null. your_cap = your max_spend_lamports clamped it; capped_for_safety = Clear capped it to keep you from overpaying; degraded_data = priced conservatively from limited data (paired with confidence: "low").
  - `sharpen` — object | null — At most one hint naming the input that would sharpen this answer, or null when the answer is already at its best scope.
    - `field` — string — The optional request field that would improve this exact answer (e.g. "writable_accounts").
    - `reason` — string — Why it would help (e.g. "improves_precision").
  - `re_quote_after_ms` — number — Ask again after this many ms if you have not sent yet. It is a refresh cadence: nothing expires when it elapses, and your transaction's real deadline is `last_valid_block_height`.

### `POST /v1/clear/intents/{id}/sign` — Add a signature
- Action: `write` · MCP tool: `clear.intents_sign`
- Base URL for THIS endpoint: `https://clear-{cluster}.k256.xyz` — Clear's send endpoint — geo-routed to the nearest location for the fastest submission; it serves the whole send path. Reads, status, and cancel stay on https://api.k256.xyz. — `{cluster}` = `mainnet` | `devnet` | `testnet` (default `mainnet`; selects the `cluster` in this base URL — the host you send to)
- For a multisig transaction: each co-signer signs the same transaction and submits the bytes here. Clear merges each signature and, once every required signature is present, lands it. Non-custodial — Clear collects signatures, it never signs. Retrying the exact co-sign that completed release is safe: Clear returns the existing intent and continues driving it without adding another lifecycle event.
- Path param `id` (string, required) — The intent's id (lc_…) — from the send receipt or the feed.
- Request body (JSON, required):
  - `signed_tx_base64` — string (required) — The SAME transaction with this co-signer's signature added — base64 wire bytes. Signatures merge; only the blockhash and message must match the collecting intent.
  - `cluster` — "mainnet" | "devnet" | "testnet" — The intent's cluster — resolves the clear-<cluster>.k256.xyz send door this call is routed to. Defaults to mainnet.
- Response (JSON):
  - `intent_id` — string
  - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
  - `status` — string — The lifecycle state — follow it live on GET /v1/clear/events. Held before broadcast: building (momentary, at create) · collecting (multisig — awaiting the remaining signatures) · scheduled (waiting on a future not_before / window) · armed (waiting on a trigger — POST /intents/:id/fire, or arm_expires_at). Live once broadcast, in order: submitted → processed → confirmed → finalized. Your effect applies (and the landed callback fires) when it reaches your commitment_target; Clear then keeps watching through finalized. Terminal: finalized (landed), invalid (rejected before broadcast — see `error`), failed (landed but rejected on chain — see `error`), or canceled (you stopped it — see the final event's reason). needs_resign is a RECOVERABLE stop, not terminal: the signed bytes expired and the intent waits — `resign_hint` carries the exact re-sign call.
  - `consumer` — string — The app/label you set on create — the console feed groups by it.
  - `kind` — string | null — Your optional free-text action label from create (e.g. "swap", "withdraw"); null when unset.
  - `cluster` — string — The Solana cluster this intent lives on — mainnet | devnet | testnet.
  - `commitment_target` — string — The landing gate you chose — confirmed | finalized. Clear applies your effect and fires the landed callback when the transaction reaches it, then always keeps watching through finalized.
  - `client_reference_id` — string | null — Your own id from create — searchable in the feed (?search=) and echoed in callbacks; null when you sent none.
  - `give_up_after_slots` — integer — Your opt-in give-up bound in slots from the send, when you set one — absent otherwise. When it fires the intent settles as canceled with reason leader_budget_exhausted.
  - `idempotency_key` — string — The dedup key for this intent (your idempotency_key, else the tx signature) — a resend under it collapses to this one record instead of double-sending, for at least 72 hours after this intent settles.
  - `bundle_id` — string | null — The bundle this intent belongs to, or null for a standalone send.
  - `shape` — "single" | "scheduled" — single = broadcast at create; scheduled = held or windowed at create (any not_before, window_until, or trigger). The exact release kind is in `release`.
  - `submitted_via` — string — How it entered Clear — api (structured /intents/send) | rpc (drop-in sendTransaction) | direct (submitted straight to Clear's send endpoint).
  - `signature` — string | null — The transaction signature from the accepted wire bytes. When the chain has observed an attempt this is that observed signature; otherwise it is the latest accepted attempt, including held, expired, invalid, or canceled-before-broadcast transactions. Null only while a multisig transaction is still collecting signatures or no attempt exists.
  - `explorer_url` — string | null — A ready-to-open block-explorer link when the signature was broadcast and may have a chain record. Null before broadcast and for transactions known not to have landed, including invalid and needs_resign intents.
  - `origin` — any — The origin object you sent on create (label, optional return_url, opaque context), echoed back verbatim; null when you sent none.
  - `origin_geo` — object | null — Where the create request came from (network + GeoIP). `ip` is visible only to the intent's owner. Null until the geo write lands.
    - `country` — string | null
    - `continent` — string | null
    - `city` — string | null
    - `region` — string | null
    - `lat` — number | null
    - `lon` — number | null
    - `timezone` — string | null
    - `asn` — number | null
    - `as_org` — string | null
    - `ip` — string | null
  - `resolution` — object | null — Where and how it landed — the slot, the commitment reached, and the validator that included it. Null until landed.
    - `landed_slot` — number | null — The slot the transaction landed in; null until landed.
    - `sent_slot` — number | null — The slot the network was in when Clear admitted the transaction — the SEND end of slot latency. Absent on rows predating this field.
    - `landed_commitment` — string | null — The deepest commitment the landing reached (processed | confirmed | finalized); null until landed. A landed-but-program-rejected transaction can report processed — the failure gate commits before deeper commitments are recorded.
    - `landed_attempt_id` — string | null — Which attempt (see `attempts[]`) actually landed; null until landed.
    - `leader` — object | null — The validator that included the transaction — its identity, client software, stake and geo (all publicly verifiable on-chain). Null before landing; geo/client/stake null when not known.
      - `identity` — string
      - `country` — string | null
      - `city` — string | null
      - `asn` — number | null
      - `as_org` — string | null
      - `lat` — number | null
      - `lon` — number | null
      - `client` — object | null — The validator's declared client software (agave | frankendancer | …); null when no version is known.
      - `stake` — number | null — Activated stake (lamports) of the validator that included the tx — null when not known.
  - `attempts[]` — object[] — Every signed version of this action Clear has driven — one per create / re-sign / bump, newest last. Each carries its own signature and blockhash so you can trace exactly which bytes were on the wire.
    - `attempt_no` — number — 1-based attempt index — bumped by each re-sign / bump.
    - `signature` — string — This attempt's transaction signature.
    - `blockhash` — string — The blockhash (or durable-nonce value) these bytes were signed against.
    - `last_valid_block_height` — number | null — The height past which this attempt's blockhash expires. Null when Clear could not resolve it — a blockhash older than the window the box tracks, which is typical of bytes a client has been retrying for a while; the attempt is still driven normally.
    - `status` — string — in_flight while the intent is live; a landed attempt carries its reached commitment (processed | confirmed | finalized). Once the intent terminalizes, an attempt that never landed tells the truth instead: superseded (a re-sign/bump replaced it, or another attempt landed) | invalid (Clear rejected the bytes before broadcast) | failed (the chain rejected this signature) | canceled (future re-broadcasts stopped) | expired (the bytes died — see resign_hint.reason).
  - `events[]` — object[] — The ordered transition timeline (oldest first) — every status change with its observation time and, where recorded, its reason. This is the audit trail behind the current `status`.
    - `at` — number — Unix-ms when Clear OBSERVED this transition — observation time, never the on-chain time (that lives in result.block_time). Same-second neighbors are real: e.g. a transaction accepted with an already-expired blockhash shows submitted and needs_resign within the same second.
    - `status` — string — The status this transition moved the intent INTO — the same vocabulary as the top-level `status`, plus result_recorded — the on-chain outcome enrichment recorded after landing.
    - `reason` — string — Why this transition happened, when recorded — needs_resign: blockhash_expired | nonce_advanced; canceled: caller_requested | leader_budget_exhausted (your give_up_after_slots bound fired) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled.
  - `resign_hint` — object — Present ONLY while status is needs_resign: why it didn't land + the exact re-sign call with this intent's real id. The needs_resign callback payload embeds the same object.
    - `reason` — string — Why the signed bytes died: blockhash_expired | nonce_advanced.
    - `action` — string — The one next action, in plain words.
    - `send` — object — A ready-to-send re-sign call, prefilled with this intent's real id.
      - `method` — string
      - `url` — string — The ABSOLUTE re-sign endpoint — the intent's own cluster send door, https://clear-<cluster>.k256.xyz/v1/clear/intents/send.
      - `body` — object
    - `retry_collapse` — string — How retries collapse onto this intent, in the ingress door's own vocabulary (API/direct: intent_id + the client_reference_id/idempotency_key body fields; drop-in RPC: the X-Clear-Reference-Id header).
  - `fee_posture` — object — How this transaction's priority fee sat against the live fee market when Clear accepted it — deliberately coarse. Snapshotted once at acceptance, so create and every later read return the SAME value. ABSENT when the fee wasn't classified at acceptance (and bundle members carry no posture) — never guessed.
    - `level` — "none" | "low" | "typical" | "high" — The create-time price band: none (no priority fee set) | low | typical | high, relative to observed network demand when Clear accepted the transaction.
    - `note` — string — A factual description of that create-time price band.
  - `decoded` — any | null — The decoded transaction message (fee payer, instructions, account keys, address-lookup-table resolution) — a read-only view of the bytes you signed. Null before decode.
  - `result` — any | null — The on-chain outcome once landed — slot, block_time, fee (lamports), compute units consumed, balance/token deltas, and program logs. Null until landed.
  - `error` — any — The exact failure detail when status is invalid (pre-broadcast validation) or failed (the chain's error plus a plain-words reading); null otherwise.
  - `not_before` — number | null — The earliest unix-ms this intent may broadcast (the not_before you set), or null for an immediate send.
  - `collect_expires_at` — number — When this multisig stops waiting for its remaining signatures (unix-ms) and cancels with reason collecting_expired — nothing is broadcast. Present only while a collection is open; defaults to 1 hour after create unless you set collect_expires_at.
  - `release` — object — The release axis — WHEN the bytes broadcast, orthogonal to `shape`.
    - `kind` — string — The release mechanism — immediate (broadcast at create) | scheduled (held for not_before) | window (broadcast now, keep trying until window_until) | triggered (armed; broadcasts on /fire).
    - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
    - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release — cancels cleanly if never fired; null otherwise.
    - `armed` — boolean — True while a triggered intent is held awaiting /fire.
    - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only) — Clear stores it opaquely and never interprets it. Null on every other release kind.
  - `created_at` — number — When Clear created this intent (unix-ms).
  - `updated_at` — number — When this intent last changed (unix-ms).
  - `terminal_at` — number | null — When the intent reached a terminal state (finalized | invalid | failed | canceled); null while still live or in needs_resign.

### `POST /v1/clear/intents/{id}/fire` — Fire (release now)
- Action: `write` · MCP tool: `clear.intents_fire`
- Base URL for THIS endpoint: `https://clear-{cluster}.k256.xyz` — Clear's send endpoint — geo-routed to the nearest location for the fastest submission; it serves the whole send path. Reads, status, and cancel stay on https://api.k256.xyz. — `{cluster}` = `mainnet` | `devnet` | `testnet` (default `mainnet`; selects the `cluster` in this base URL — the host you send to)
- Releases an intent you armed in advance (signed against a durable nonce, held for a trigger) — Clear broadcasts it now and drives it to landing. 409 if the intent isn't armed.
- Path param `id` (string, required) — The intent's id (lc_…) — from the send receipt or the feed.
- Request body (JSON, required):
  - `cluster` — "mainnet" | "devnet" | "testnet" — The intent's cluster — resolves the clear-<cluster>.k256.xyz send door this call is routed to. Defaults to mainnet.
- Response (JSON):
  - `intent_id` — string
  - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
  - `status` — string — The lifecycle state — follow it live on GET /v1/clear/events. Held before broadcast: building (momentary, at create) · collecting (multisig — awaiting the remaining signatures) · scheduled (waiting on a future not_before / window) · armed (waiting on a trigger — POST /intents/:id/fire, or arm_expires_at). Live once broadcast, in order: submitted → processed → confirmed → finalized. Your effect applies (and the landed callback fires) when it reaches your commitment_target; Clear then keeps watching through finalized. Terminal: finalized (landed), invalid (rejected before broadcast — see `error`), failed (landed but rejected on chain — see `error`), or canceled (you stopped it — see the final event's reason). needs_resign is a RECOVERABLE stop, not terminal: the signed bytes expired and the intent waits — `resign_hint` carries the exact re-sign call.
  - `consumer` — string — The app/label you set on create — the console feed groups by it.
  - `kind` — string | null — Your optional free-text action label from create (e.g. "swap", "withdraw"); null when unset.
  - `cluster` — string — The Solana cluster this intent lives on — mainnet | devnet | testnet.
  - `commitment_target` — string — The landing gate you chose — confirmed | finalized. Clear applies your effect and fires the landed callback when the transaction reaches it, then always keeps watching through finalized.
  - `client_reference_id` — string | null — Your own id from create — searchable in the feed (?search=) and echoed in callbacks; null when you sent none.
  - `give_up_after_slots` — integer — Your opt-in give-up bound in slots from the send, when you set one — absent otherwise. When it fires the intent settles as canceled with reason leader_budget_exhausted.
  - `idempotency_key` — string — The dedup key for this intent (your idempotency_key, else the tx signature) — a resend under it collapses to this one record instead of double-sending, for at least 72 hours after this intent settles.
  - `bundle_id` — string | null — The bundle this intent belongs to, or null for a standalone send.
  - `shape` — "single" | "scheduled" — single = broadcast at create; scheduled = held or windowed at create (any not_before, window_until, or trigger). The exact release kind is in `release`.
  - `submitted_via` — string — How it entered Clear — api (structured /intents/send) | rpc (drop-in sendTransaction) | direct (submitted straight to Clear's send endpoint).
  - `signature` — string | null — The transaction signature from the accepted wire bytes. When the chain has observed an attempt this is that observed signature; otherwise it is the latest accepted attempt, including held, expired, invalid, or canceled-before-broadcast transactions. Null only while a multisig transaction is still collecting signatures or no attempt exists.
  - `explorer_url` — string | null — A ready-to-open block-explorer link when the signature was broadcast and may have a chain record. Null before broadcast and for transactions known not to have landed, including invalid and needs_resign intents.
  - `origin` — any — The origin object you sent on create (label, optional return_url, opaque context), echoed back verbatim; null when you sent none.
  - `origin_geo` — object | null — Where the create request came from (network + GeoIP). `ip` is visible only to the intent's owner. Null until the geo write lands.
    - `country` — string | null
    - `continent` — string | null
    - `city` — string | null
    - `region` — string | null
    - `lat` — number | null
    - `lon` — number | null
    - `timezone` — string | null
    - `asn` — number | null
    - `as_org` — string | null
    - `ip` — string | null
  - `resolution` — object | null — Where and how it landed — the slot, the commitment reached, and the validator that included it. Null until landed.
    - `landed_slot` — number | null — The slot the transaction landed in; null until landed.
    - `sent_slot` — number | null — The slot the network was in when Clear admitted the transaction — the SEND end of slot latency. Absent on rows predating this field.
    - `landed_commitment` — string | null — The deepest commitment the landing reached (processed | confirmed | finalized); null until landed. A landed-but-program-rejected transaction can report processed — the failure gate commits before deeper commitments are recorded.
    - `landed_attempt_id` — string | null — Which attempt (see `attempts[]`) actually landed; null until landed.
    - `leader` — object | null — The validator that included the transaction — its identity, client software, stake and geo (all publicly verifiable on-chain). Null before landing; geo/client/stake null when not known.
      - `identity` — string
      - `country` — string | null
      - `city` — string | null
      - `asn` — number | null
      - `as_org` — string | null
      - `lat` — number | null
      - `lon` — number | null
      - `client` — object | null — The validator's declared client software (agave | frankendancer | …); null when no version is known.
      - `stake` — number | null — Activated stake (lamports) of the validator that included the tx — null when not known.
  - `attempts[]` — object[] — Every signed version of this action Clear has driven — one per create / re-sign / bump, newest last. Each carries its own signature and blockhash so you can trace exactly which bytes were on the wire.
    - `attempt_no` — number — 1-based attempt index — bumped by each re-sign / bump.
    - `signature` — string — This attempt's transaction signature.
    - `blockhash` — string — The blockhash (or durable-nonce value) these bytes were signed against.
    - `last_valid_block_height` — number | null — The height past which this attempt's blockhash expires. Null when Clear could not resolve it — a blockhash older than the window the box tracks, which is typical of bytes a client has been retrying for a while; the attempt is still driven normally.
    - `status` — string — in_flight while the intent is live; a landed attempt carries its reached commitment (processed | confirmed | finalized). Once the intent terminalizes, an attempt that never landed tells the truth instead: superseded (a re-sign/bump replaced it, or another attempt landed) | invalid (Clear rejected the bytes before broadcast) | failed (the chain rejected this signature) | canceled (future re-broadcasts stopped) | expired (the bytes died — see resign_hint.reason).
  - `events[]` — object[] — The ordered transition timeline (oldest first) — every status change with its observation time and, where recorded, its reason. This is the audit trail behind the current `status`.
    - `at` — number — Unix-ms when Clear OBSERVED this transition — observation time, never the on-chain time (that lives in result.block_time). Same-second neighbors are real: e.g. a transaction accepted with an already-expired blockhash shows submitted and needs_resign within the same second.
    - `status` — string — The status this transition moved the intent INTO — the same vocabulary as the top-level `status`, plus result_recorded — the on-chain outcome enrichment recorded after landing.
    - `reason` — string — Why this transition happened, when recorded — needs_resign: blockhash_expired | nonce_advanced; canceled: caller_requested | leader_budget_exhausted (your give_up_after_slots bound fired) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled.
  - `resign_hint` — object — Present ONLY while status is needs_resign: why it didn't land + the exact re-sign call with this intent's real id. The needs_resign callback payload embeds the same object.
    - `reason` — string — Why the signed bytes died: blockhash_expired | nonce_advanced.
    - `action` — string — The one next action, in plain words.
    - `send` — object — A ready-to-send re-sign call, prefilled with this intent's real id.
      - `method` — string
      - `url` — string — The ABSOLUTE re-sign endpoint — the intent's own cluster send door, https://clear-<cluster>.k256.xyz/v1/clear/intents/send.
      - `body` — object
    - `retry_collapse` — string — How retries collapse onto this intent, in the ingress door's own vocabulary (API/direct: intent_id + the client_reference_id/idempotency_key body fields; drop-in RPC: the X-Clear-Reference-Id header).
  - `fee_posture` — object — How this transaction's priority fee sat against the live fee market when Clear accepted it — deliberately coarse. Snapshotted once at acceptance, so create and every later read return the SAME value. ABSENT when the fee wasn't classified at acceptance (and bundle members carry no posture) — never guessed.
    - `level` — "none" | "low" | "typical" | "high" — The create-time price band: none (no priority fee set) | low | typical | high, relative to observed network demand when Clear accepted the transaction.
    - `note` — string — A factual description of that create-time price band.
  - `decoded` — any | null — The decoded transaction message (fee payer, instructions, account keys, address-lookup-table resolution) — a read-only view of the bytes you signed. Null before decode.
  - `result` — any | null — The on-chain outcome once landed — slot, block_time, fee (lamports), compute units consumed, balance/token deltas, and program logs. Null until landed.
  - `error` — any — The exact failure detail when status is invalid (pre-broadcast validation) or failed (the chain's error plus a plain-words reading); null otherwise.
  - `not_before` — number | null — The earliest unix-ms this intent may broadcast (the not_before you set), or null for an immediate send.
  - `collect_expires_at` — number — When this multisig stops waiting for its remaining signatures (unix-ms) and cancels with reason collecting_expired — nothing is broadcast. Present only while a collection is open; defaults to 1 hour after create unless you set collect_expires_at.
  - `release` — object — The release axis — WHEN the bytes broadcast, orthogonal to `shape`.
    - `kind` — string — The release mechanism — immediate (broadcast at create) | scheduled (held for not_before) | window (broadcast now, keep trying until window_until) | triggered (armed; broadcasts on /fire).
    - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
    - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release — cancels cleanly if never fired; null otherwise.
    - `armed` — boolean — True while a triggered intent is held awaiting /fire.
    - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only) — Clear stores it opaquely and never interprets it. Null on every other release kind.
  - `created_at` — number — When Clear created this intent (unix-ms).
  - `updated_at` — number — When this intent last changed (unix-ms).
  - `terminal_at` — number | null — When the intent reached a terminal state (finalized | invalid | failed | canceled); null while still live or in needs_resign.

### `POST /v1/clear/intents/{id}/bump` — Fee-bump
- Action: `write` · MCP tool: `clear.intents_bump`
- Base URL for THIS endpoint: `https://clear-{cluster}.k256.xyz` — Clear's send endpoint — geo-routed to the nearest location for the fastest submission; it serves the whole send path. Reads, status, and cancel stay on https://api.k256.xyz. — `{cluster}` = `mainnet` | `devnet` | `testnet` (default `mainnet`; selects the `cluster` in this base URL — the host you send to)
- Attaches a higher-priced re-sign of an in-flight transaction so it can land faster. Safe only for a durable-nonce transaction — the shared nonce guarantees at most one version lands, never both. For a normal blockhash transaction, let it expire and re-sign instead.
- Path param `id` (string, required) — The intent's id (lc_…) — from the send receipt or the feed.
- Request body (JSON, required):
  - `signed_tx_base64` — string (required) — The same durable-nonce action re-signed at a HIGHER priority fee — base64 wire bytes. Clear races both; the shared nonce guarantees at most one lands.
  - `last_valid_block_height` — integer — Optional expiry height from getLatestBlockhash for the new bytes — lets Clear declare needs_resign precisely instead of probing.
  - `cluster` — "mainnet" | "devnet" | "testnet" — The intent's cluster — resolves the clear-<cluster>.k256.xyz send door this call is routed to. Defaults to mainnet.
- Response (JSON):
  - `intent_id` — string
  - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
  - `status` — string — The lifecycle state — follow it live on GET /v1/clear/events. Held before broadcast: building (momentary, at create) · collecting (multisig — awaiting the remaining signatures) · scheduled (waiting on a future not_before / window) · armed (waiting on a trigger — POST /intents/:id/fire, or arm_expires_at). Live once broadcast, in order: submitted → processed → confirmed → finalized. Your effect applies (and the landed callback fires) when it reaches your commitment_target; Clear then keeps watching through finalized. Terminal: finalized (landed), invalid (rejected before broadcast — see `error`), failed (landed but rejected on chain — see `error`), or canceled (you stopped it — see the final event's reason). needs_resign is a RECOVERABLE stop, not terminal: the signed bytes expired and the intent waits — `resign_hint` carries the exact re-sign call.
  - `consumer` — string — The app/label you set on create — the console feed groups by it.
  - `kind` — string | null — Your optional free-text action label from create (e.g. "swap", "withdraw"); null when unset.
  - `cluster` — string — The Solana cluster this intent lives on — mainnet | devnet | testnet.
  - `commitment_target` — string — The landing gate you chose — confirmed | finalized. Clear applies your effect and fires the landed callback when the transaction reaches it, then always keeps watching through finalized.
  - `client_reference_id` — string | null — Your own id from create — searchable in the feed (?search=) and echoed in callbacks; null when you sent none.
  - `give_up_after_slots` — integer — Your opt-in give-up bound in slots from the send, when you set one — absent otherwise. When it fires the intent settles as canceled with reason leader_budget_exhausted.
  - `idempotency_key` — string — The dedup key for this intent (your idempotency_key, else the tx signature) — a resend under it collapses to this one record instead of double-sending, for at least 72 hours after this intent settles.
  - `bundle_id` — string | null — The bundle this intent belongs to, or null for a standalone send.
  - `shape` — "single" | "scheduled" — single = broadcast at create; scheduled = held or windowed at create (any not_before, window_until, or trigger). The exact release kind is in `release`.
  - `submitted_via` — string — How it entered Clear — api (structured /intents/send) | rpc (drop-in sendTransaction) | direct (submitted straight to Clear's send endpoint).
  - `signature` — string | null — The transaction signature from the accepted wire bytes. When the chain has observed an attempt this is that observed signature; otherwise it is the latest accepted attempt, including held, expired, invalid, or canceled-before-broadcast transactions. Null only while a multisig transaction is still collecting signatures or no attempt exists.
  - `explorer_url` — string | null — A ready-to-open block-explorer link when the signature was broadcast and may have a chain record. Null before broadcast and for transactions known not to have landed, including invalid and needs_resign intents.
  - `origin` — any — The origin object you sent on create (label, optional return_url, opaque context), echoed back verbatim; null when you sent none.
  - `origin_geo` — object | null — Where the create request came from (network + GeoIP). `ip` is visible only to the intent's owner. Null until the geo write lands.
    - `country` — string | null
    - `continent` — string | null
    - `city` — string | null
    - `region` — string | null
    - `lat` — number | null
    - `lon` — number | null
    - `timezone` — string | null
    - `asn` — number | null
    - `as_org` — string | null
    - `ip` — string | null
  - `resolution` — object | null — Where and how it landed — the slot, the commitment reached, and the validator that included it. Null until landed.
    - `landed_slot` — number | null — The slot the transaction landed in; null until landed.
    - `sent_slot` — number | null — The slot the network was in when Clear admitted the transaction — the SEND end of slot latency. Absent on rows predating this field.
    - `landed_commitment` — string | null — The deepest commitment the landing reached (processed | confirmed | finalized); null until landed. A landed-but-program-rejected transaction can report processed — the failure gate commits before deeper commitments are recorded.
    - `landed_attempt_id` — string | null — Which attempt (see `attempts[]`) actually landed; null until landed.
    - `leader` — object | null — The validator that included the transaction — its identity, client software, stake and geo (all publicly verifiable on-chain). Null before landing; geo/client/stake null when not known.
      - `identity` — string
      - `country` — string | null
      - `city` — string | null
      - `asn` — number | null
      - `as_org` — string | null
      - `lat` — number | null
      - `lon` — number | null
      - `client` — object | null — The validator's declared client software (agave | frankendancer | …); null when no version is known.
      - `stake` — number | null — Activated stake (lamports) of the validator that included the tx — null when not known.
  - `attempts[]` — object[] — Every signed version of this action Clear has driven — one per create / re-sign / bump, newest last. Each carries its own signature and blockhash so you can trace exactly which bytes were on the wire.
    - `attempt_no` — number — 1-based attempt index — bumped by each re-sign / bump.
    - `signature` — string — This attempt's transaction signature.
    - `blockhash` — string — The blockhash (or durable-nonce value) these bytes were signed against.
    - `last_valid_block_height` — number | null — The height past which this attempt's blockhash expires. Null when Clear could not resolve it — a blockhash older than the window the box tracks, which is typical of bytes a client has been retrying for a while; the attempt is still driven normally.
    - `status` — string — in_flight while the intent is live; a landed attempt carries its reached commitment (processed | confirmed | finalized). Once the intent terminalizes, an attempt that never landed tells the truth instead: superseded (a re-sign/bump replaced it, or another attempt landed) | invalid (Clear rejected the bytes before broadcast) | failed (the chain rejected this signature) | canceled (future re-broadcasts stopped) | expired (the bytes died — see resign_hint.reason).
  - `events[]` — object[] — The ordered transition timeline (oldest first) — every status change with its observation time and, where recorded, its reason. This is the audit trail behind the current `status`.
    - `at` — number — Unix-ms when Clear OBSERVED this transition — observation time, never the on-chain time (that lives in result.block_time). Same-second neighbors are real: e.g. a transaction accepted with an already-expired blockhash shows submitted and needs_resign within the same second.
    - `status` — string — The status this transition moved the intent INTO — the same vocabulary as the top-level `status`, plus result_recorded — the on-chain outcome enrichment recorded after landing.
    - `reason` — string — Why this transition happened, when recorded — needs_resign: blockhash_expired | nonce_advanced; canceled: caller_requested | leader_budget_exhausted (your give_up_after_slots bound fired) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled.
  - `resign_hint` — object — Present ONLY while status is needs_resign: why it didn't land + the exact re-sign call with this intent's real id. The needs_resign callback payload embeds the same object.
    - `reason` — string — Why the signed bytes died: blockhash_expired | nonce_advanced.
    - `action` — string — The one next action, in plain words.
    - `send` — object — A ready-to-send re-sign call, prefilled with this intent's real id.
      - `method` — string
      - `url` — string — The ABSOLUTE re-sign endpoint — the intent's own cluster send door, https://clear-<cluster>.k256.xyz/v1/clear/intents/send.
      - `body` — object
    - `retry_collapse` — string — How retries collapse onto this intent, in the ingress door's own vocabulary (API/direct: intent_id + the client_reference_id/idempotency_key body fields; drop-in RPC: the X-Clear-Reference-Id header).
  - `fee_posture` — object — How this transaction's priority fee sat against the live fee market when Clear accepted it — deliberately coarse. Snapshotted once at acceptance, so create and every later read return the SAME value. ABSENT when the fee wasn't classified at acceptance (and bundle members carry no posture) — never guessed.
    - `level` — "none" | "low" | "typical" | "high" — The create-time price band: none (no priority fee set) | low | typical | high, relative to observed network demand when Clear accepted the transaction.
    - `note` — string — A factual description of that create-time price band.
  - `decoded` — any | null — The decoded transaction message (fee payer, instructions, account keys, address-lookup-table resolution) — a read-only view of the bytes you signed. Null before decode.
  - `result` — any | null — The on-chain outcome once landed — slot, block_time, fee (lamports), compute units consumed, balance/token deltas, and program logs. Null until landed.
  - `error` — any — The exact failure detail when status is invalid (pre-broadcast validation) or failed (the chain's error plus a plain-words reading); null otherwise.
  - `not_before` — number | null — The earliest unix-ms this intent may broadcast (the not_before you set), or null for an immediate send.
  - `collect_expires_at` — number — When this multisig stops waiting for its remaining signatures (unix-ms) and cancels with reason collecting_expired — nothing is broadcast. Present only while a collection is open; defaults to 1 hour after create unless you set collect_expires_at.
  - `release` — object — The release axis — WHEN the bytes broadcast, orthogonal to `shape`.
    - `kind` — string — The release mechanism — immediate (broadcast at create) | scheduled (held for not_before) | window (broadcast now, keep trying until window_until) | triggered (armed; broadcasts on /fire).
    - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
    - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release — cancels cleanly if never fired; null otherwise.
    - `armed` — boolean — True while a triggered intent is held awaiting /fire.
    - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only) — Clear stores it opaquely and never interprets it. Null on every other release kind.
  - `created_at` — number — When Clear created this intent (unix-ms).
  - `updated_at` — number — When this intent last changed (unix-ms).
  - `terminal_at` — number | null — When the intent reached a terminal state (finalized | invalid | failed | canceled); null while still live or in needs_resign.

### `POST /v1/clear/intents/{id}/cancel` — Cancel
- Action: `write` · MCP tool: `clear.intents_cancel`
- Stops Clear from making any further attempt on this intent. Returns an honest outcome — bytes already on the wire can still land and can't be revoked.
- Path param `id` (string, required) — The intent's id (lc_…) — from the send receipt or the feed.
- Response (JSON):
  - `intent_id` — string
  - `outcome` — string — What the cancel actually did: stopped_before_submit (nothing was ever sent) | stopped_further_attempts (it was in flight — Clear stops any further attempt; bytes already sent may still land) | dropped_after_cancel_request (a needs_resign was dropped) | landed_after_cancel_request (the chain landed it first — nothing to cancel) | already_canceled | already_invalid (rejected before broadcast, so there is nothing to stop) | already_submitted_cannot_revoke (it already ran / is past the point of no return — nothing changed).

### `POST /v1/clear/bundles` — Create a bundle
- Action: `write` · MCP tool: `clear.bundles_send`
- Base URL for THIS endpoint: `https://clear-{cluster}.k256.xyz` — Clear's send endpoint — geo-routed to the nearest location for the fastest submission; it serves the whole send path. Reads, status, and cancel stay on https://api.k256.xyz. — `{cluster}` = `mainnet` | `devnet` | `testnet` (default `mainnet`; selects the `cluster` in this base URL — the host you send to)
- Lands a set of signed transactions together — mode=sequential (each waits for the prior to land), parallel (all at once), or dag (per-step dependencies). Retry is automatic; on an on-chain failure the bundle follows on_failure (stop | continue) and reports exactly which steps landed and which didn't. Not atomic — landed steps stay on chain.
- Request body (JSON, required):
  - `mode` — "sequential" | "parallel" | "dag" (required) — sequential: each transaction is submitted only after the prior reaches the gate. parallel: all at once, independent. dag: per-step `after` dependencies.
  - `on_failure` — "stop" | "continue" — When a step fails on chain: stop freezes every step not yet started; continue keeps going — a sequential chain skips past the failed step, and in a dag the failed step's own descendants can never start while independent branches continue. Default: stop for sequential, continue for parallel/dag.
  - `cluster` — "mainnet" | "devnet" | "testnet" — Optional cross-check. Send to https://clear-<cluster>.k256.xyz and the hostname selects the cluster for every member; if supplied, this value must match the host. Explorer and MCP calls use it to choose a host and default to mainnet. Reads and cancel stay on https://api.k256.xyz.
  - `idempotency_key` — string (required) — Required (unique per workspace): a retried create with the same key returns the existing bundle — never a double-send.
  - `commitment_target` — "confirmed" | "finalized" — The landing gate for EVERY member — and the sequential/dag advance gate (the next step waits for the prior to reach it). Default CONFIRMED (supermajority-voted, ~0.4-2s per sequential step — the same default as a single send); choose finalized to wait for irreversibility (~15s per step).
  - `client_reference_id` — string — Your own id for the WHOLE bundle — searchable in the feed and echoed in callbacks (each step can carry its own too).
  - `origin` — object — Where this came from — a label for the console feed, an optional return_url, and an opaque context echoed back.
  - `consumer` — string — Free-form producer tag (your service/app name) echoed on reads — separates bundles from different systems in one workspace.
  - `callback` — object — HTTPS endpoint + subscribed events for bundle and step transitions — signed, retried with backoff, logged. Requires a workspace callback secret.
  - `transactions` — object[] (required) — The bundle's steps, in order (1–20). Each carries its own fully-signed transaction; sequential/dag ordering applies across them.
- Response (JSON):
  - `bundle_id` — string
  - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
  - `status` — string — The bundle lifecycle — building (assembling / held before release) · running (steps executing) · completed (all steps landed) · completed_with_failures (finished, some steps did not land — see failed_count and each step in `transactions`) · stopped (halted by on_failure=stop after a step failed) · canceled (you canceled it).
  - `mode` — "sequential" | "parallel" | "dag" — Execution shape — sequential (each step after the previous lands) | parallel (all at once) | dag (per-step dependency graph; see plan_edges).
  - `on_failure` — string — What happens when a step fails to land — stop (halt the remaining steps) | continue (run the rest anyway).
  - `cluster` — string — The Solana cluster the bundle runs on — mainnet | devnet | testnet.
  - `commitment_target` — string — The landing gate applied to every step — confirmed | finalized.
  - `client_reference_id` — string | null — Your own id from create — searchable and echoed in callbacks; null when unset.
  - `origin` — any — The origin object you sent on create, echoed back; null when unset.
  - `tx_count` — number — Total steps in the bundle.
  - `landed_count` — number — How many steps have landed so far.
  - `failed_count` — number — How many steps have failed to land so far.
  - `release` — object — The release axis — WHEN the bundle sends.
    - `kind` — string — The release mechanism for the bundle — immediate | scheduled | window | triggered (see the intent `release.kind`).
    - `not_before` — number | null — Earliest broadcast time (unix-ms) for a scheduled release; null otherwise.
    - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
    - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release; null otherwise.
    - `armed` — boolean — True while a triggered bundle is held awaiting /fire.
    - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only). Null on every other release kind.
  - `created_at` — number — When the bundle was created (unix-ms).
  - `updated_at` — number — When the bundle last changed (unix-ms).
  - `terminal_at` — number | null — When the bundle reached a terminal state; null while still running.
  - `transactions[]` — object[] — The bundle's steps, in order — each is a full intent object (same shape as GET /intents/:id) plus its `step` index.
    - `intent_id` — string
    - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
    - `status` — string — The lifecycle state — follow it live on GET /v1/clear/events. Held before broadcast: building (momentary, at create) · collecting (multisig — awaiting the remaining signatures) · scheduled (waiting on a future not_before / window) · armed (waiting on a trigger — POST /intents/:id/fire, or arm_expires_at). Live once broadcast, in order: submitted → processed → confirmed → finalized. Your effect applies (and the landed callback fires) when it reaches your commitment_target; Clear then keeps watching through finalized. Terminal: finalized (landed), invalid (rejected before broadcast — see `error`), failed (landed but rejected on chain — see `error`), or canceled (you stopped it — see the final event's reason). needs_resign is a RECOVERABLE stop, not terminal: the signed bytes expired and the intent waits — `resign_hint` carries the exact re-sign call.
    - `consumer` — string — The app/label you set on create — the console feed groups by it.
    - `kind` — string | null — Your optional free-text action label from create (e.g. "swap", "withdraw"); null when unset.
    - `cluster` — string — The Solana cluster this intent lives on — mainnet | devnet | testnet.
    - `commitment_target` — string — The landing gate you chose — confirmed | finalized. Clear applies your effect and fires the landed callback when the transaction reaches it, then always keeps watching through finalized.
    - `client_reference_id` — string | null — Your own id from create — searchable in the feed (?search=) and echoed in callbacks; null when you sent none.
    - `give_up_after_slots` — integer — Your opt-in give-up bound in slots from the send, when you set one — absent otherwise. When it fires the intent settles as canceled with reason leader_budget_exhausted.
    - `idempotency_key` — string — The dedup key for this intent (your idempotency_key, else the tx signature) — a resend under it collapses to this one record instead of double-sending, for at least 72 hours after this intent settles.
    - `bundle_id` — string | null — The bundle this intent belongs to, or null for a standalone send.
    - `shape` — "single" | "scheduled" — single = broadcast at create; scheduled = held or windowed at create (any not_before, window_until, or trigger). The exact release kind is in `release`.
    - `submitted_via` — string — How it entered Clear — api (structured /intents/send) | rpc (drop-in sendTransaction) | direct (submitted straight to Clear's send endpoint).
    - `signature` — string | null — The transaction signature from the accepted wire bytes. When the chain has observed an attempt this is that observed signature; otherwise it is the latest accepted attempt, including held, expired, invalid, or canceled-before-broadcast transactions. Null only while a multisig transaction is still collecting signatures or no attempt exists.
    - `explorer_url` — string | null — A ready-to-open block-explorer link when the signature was broadcast and may have a chain record. Null before broadcast and for transactions known not to have landed, including invalid and needs_resign intents.
    - `origin` — any — The origin object you sent on create (label, optional return_url, opaque context), echoed back verbatim; null when you sent none.
    - `origin_geo` — object | null — Where the create request came from (network + GeoIP). `ip` is visible only to the intent's owner. Null until the geo write lands.
      - `country` — string | null
      - `continent` — string | null
      - `city` — string | null
      - `region` — string | null
      - `lat` — number | null
      - `lon` — number | null
      - `timezone` — string | null
      - `asn` — number | null
      - `as_org` — string | null
      - `ip` — string | null
    - `resolution` — object | null — Where and how it landed — the slot, the commitment reached, and the validator that included it. Null until landed.
      - `landed_slot` — number | null — The slot the transaction landed in; null until landed.
      - `sent_slot` — number | null — The slot the network was in when Clear admitted the transaction — the SEND end of slot latency. Absent on rows predating this field.
      - `landed_commitment` — string | null — The deepest commitment the landing reached (processed | confirmed | finalized); null until landed. A landed-but-program-rejected transaction can report processed — the failure gate commits before deeper commitments are recorded.
      - `landed_attempt_id` — string | null — Which attempt (see `attempts[]`) actually landed; null until landed.
      - `leader` — object | null — The validator that included the transaction — its identity, client software, stake and geo (all publicly verifiable on-chain). Null before landing; geo/client/stake null when not known.
    - `attempts[]` — object[] — Every signed version of this action Clear has driven — one per create / re-sign / bump, newest last. Each carries its own signature and blockhash so you can trace exactly which bytes were on the wire.
      - `attempt_no` — number — 1-based attempt index — bumped by each re-sign / bump.
      - `signature` — string — This attempt's transaction signature.
      - `blockhash` — string — The blockhash (or durable-nonce value) these bytes were signed against.
      - `last_valid_block_height` — number | null — The height past which this attempt's blockhash expires. Null when Clear could not resolve it — a blockhash older than the window the box tracks, which is typical of bytes a client has been retrying for a while; the attempt is still driven normally.
      - `status` — string — in_flight while the intent is live; a landed attempt carries its reached commitment (processed | confirmed | finalized). Once the intent terminalizes, an attempt that never landed tells the truth instead: superseded (a re-sign/bump replaced it, or another attempt landed) | invalid (Clear rejected the bytes before broadcast) | failed (the chain rejected this signature) | canceled (future re-broadcasts stopped) | expired (the bytes died — see resign_hint.reason).
    - `events[]` — object[] — The ordered transition timeline (oldest first) — every status change with its observation time and, where recorded, its reason. This is the audit trail behind the current `status`.
      - `at` — number — Unix-ms when Clear OBSERVED this transition — observation time, never the on-chain time (that lives in result.block_time). Same-second neighbors are real: e.g. a transaction accepted with an already-expired blockhash shows submitted and needs_resign within the same second.
      - `status` — string — The status this transition moved the intent INTO — the same vocabulary as the top-level `status`, plus result_recorded — the on-chain outcome enrichment recorded after landing.
      - `reason` — string — Why this transition happened, when recorded — needs_resign: blockhash_expired | nonce_advanced; canceled: caller_requested | leader_budget_exhausted (your give_up_after_slots bound fired) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled.
    - `resign_hint` — object — Present ONLY while status is needs_resign: why it didn't land + the exact re-sign call with this intent's real id. The needs_resign callback payload embeds the same object.
      - `reason` — string — Why the signed bytes died: blockhash_expired | nonce_advanced.
      - `action` — string — The one next action, in plain words.
      - `send` — object — A ready-to-send re-sign call, prefilled with this intent's real id.
      - `retry_collapse` — string — How retries collapse onto this intent, in the ingress door's own vocabulary (API/direct: intent_id + the client_reference_id/idempotency_key body fields; drop-in RPC: the X-Clear-Reference-Id header).
    - `fee_posture` — object — How this transaction's priority fee sat against the live fee market when Clear accepted it — deliberately coarse. Snapshotted once at acceptance, so create and every later read return the SAME value. ABSENT when the fee wasn't classified at acceptance (and bundle members carry no posture) — never guessed.
      - `level` — "none" | "low" | "typical" | "high" — The create-time price band: none (no priority fee set) | low | typical | high, relative to observed network demand when Clear accepted the transaction.
      - `note` — string — A factual description of that create-time price band.
    - `decoded` — any | null — The decoded transaction message (fee payer, instructions, account keys, address-lookup-table resolution) — a read-only view of the bytes you signed. Null before decode.
    - `result` — any | null — The on-chain outcome once landed — slot, block_time, fee (lamports), compute units consumed, balance/token deltas, and program logs. Null until landed.
    - `error` — any — The exact failure detail when status is invalid (pre-broadcast validation) or failed (the chain's error plus a plain-words reading); null otherwise.
    - `not_before` — number | null — The earliest unix-ms this intent may broadcast (the not_before you set), or null for an immediate send.
    - `collect_expires_at` — number — When this multisig stops waiting for its remaining signatures (unix-ms) and cancels with reason collecting_expired — nothing is broadcast. Present only while a collection is open; defaults to 1 hour after create unless you set collect_expires_at.
    - `release` — object — The release axis — WHEN the bytes broadcast, orthogonal to `shape`.
      - `kind` — string — The release mechanism — immediate (broadcast at create) | scheduled (held for not_before) | window (broadcast now, keep trying until window_until) | triggered (armed; broadcasts on /fire).
      - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
      - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release — cancels cleanly if never fired; null otherwise.
      - `armed` — boolean — True while a triggered intent is held awaiting /fire.
      - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only) — Clear stores it opaquely and never interprets it. Null on every other release kind.
    - `created_at` — number — When Clear created this intent (unix-ms).
    - `updated_at` — number — When this intent last changed (unix-ms).
    - `terminal_at` — number | null — When the intent reached a terminal state (finalized | invalid | failed | canceled); null while still live or in needs_resign.
    - `step` — integer — This step's index in the bundle, the SAME number `plan_edges` uses for from_step/to_step. Array order already matches it, but the field means you can key a step without relying on position.
  - `plan_edges[]` — object[] — The plan's dependency edges (step index → step index): a dag's real waits_on, a sequence's implicit chain, a parallel's empty fan.
    - `from_step` — number
    - `to_step` — number

### `POST /v1/clear/bundles/{id}/cancel` — Cancel a bundle
- Action: `write` · MCP tool: `clear.bundles_cancel`
- Stops any step that hasn't started yet. Steps already in flight follow the single-transaction rules and steps that already landed stay on chain — nothing is reverted. Returns the honest per-step outcome and the bundle's final state.
- Path param `id` (string, required) — The bundle's id (bn_…) — from the create receipt or the feed.
- Response (JSON):
  - `bundle_id` — string
  - `status` — string
  - `steps[]` — object[]
    - `intent_id` — string
    - `outcome` — string — Per-step truth: stopped_before_submit (its bytes never went on the wire — whether this call stopped it or an earlier cancel/seal already had) | stopped_further_attempts (was in flight — future re-broadcasts stop; wire bytes may still land) | landed_cannot_revoke (already on chain — stays landed) | already_canceled (canceled earlier, AFTER its bytes had been broadcast) | failed.

### `GET /v1/clear/intents/{id}` — Get an intent
- Action: `read` · MCP tool: `clear.intents_get`
- A snapshot of one intent — its status, attempts, timeline, and outcome. For live updates, subscribe to GET /v1/clear/events?id=<lc_…> (SSE, JSON long-poll, or WebSocket — one seq cursor across all three) instead of re-polling. Add ?include=forensics for the on-chain outcome receipt; the default read stays light. When id is a transaction signature, add ?cluster=… if the same signed bytes were recorded on multiple clusters.
- Path param `id` (string, required) — The intent's id (lc_…) — or a transaction signature; Clear resolves the signature to its intent.
- Query param `cluster` ("mainnet" | "devnet" | "testnet") — Optional when id is a transaction signature. Supply it to disambiguate the same signed bytes recorded on multiple clusters; lifecycle ids are already unambiguous.
- Query param `include` ("forensics") — Pass "forensics" to include chain facts plus Clear-observed delivery evidence inline as `forensics`. Omit for the light snapshot — no report unless asked.
- Response (JSON):
  - `intent_id` — string
  - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
  - `status` — string — The lifecycle state — follow it live on GET /v1/clear/events. Held before broadcast: building (momentary, at create) · collecting (multisig — awaiting the remaining signatures) · scheduled (waiting on a future not_before / window) · armed (waiting on a trigger — POST /intents/:id/fire, or arm_expires_at). Live once broadcast, in order: submitted → processed → confirmed → finalized. Your effect applies (and the landed callback fires) when it reaches your commitment_target; Clear then keeps watching through finalized. Terminal: finalized (landed), invalid (rejected before broadcast — see `error`), failed (landed but rejected on chain — see `error`), or canceled (you stopped it — see the final event's reason). needs_resign is a RECOVERABLE stop, not terminal: the signed bytes expired and the intent waits — `resign_hint` carries the exact re-sign call.
  - `consumer` — string — The app/label you set on create — the console feed groups by it.
  - `kind` — string | null — Your optional free-text action label from create (e.g. "swap", "withdraw"); null when unset.
  - `cluster` — string — The Solana cluster this intent lives on — mainnet | devnet | testnet.
  - `commitment_target` — string — The landing gate you chose — confirmed | finalized. Clear applies your effect and fires the landed callback when the transaction reaches it, then always keeps watching through finalized.
  - `client_reference_id` — string | null — Your own id from create — searchable in the feed (?search=) and echoed in callbacks; null when you sent none.
  - `give_up_after_slots` — integer — Your opt-in give-up bound in slots from the send, when you set one — absent otherwise. When it fires the intent settles as canceled with reason leader_budget_exhausted.
  - `idempotency_key` — string — The dedup key for this intent (your idempotency_key, else the tx signature) — a resend under it collapses to this one record instead of double-sending, for at least 72 hours after this intent settles.
  - `bundle_id` — string | null — The bundle this intent belongs to, or null for a standalone send.
  - `shape` — "single" | "scheduled" — single = broadcast at create; scheduled = held or windowed at create (any not_before, window_until, or trigger). The exact release kind is in `release`.
  - `submitted_via` — string — How it entered Clear — api (structured /intents/send) | rpc (drop-in sendTransaction) | direct (submitted straight to Clear's send endpoint).
  - `signature` — string | null — The transaction signature from the accepted wire bytes. When the chain has observed an attempt this is that observed signature; otherwise it is the latest accepted attempt, including held, expired, invalid, or canceled-before-broadcast transactions. Null only while a multisig transaction is still collecting signatures or no attempt exists.
  - `explorer_url` — string | null — A ready-to-open block-explorer link when the signature was broadcast and may have a chain record. Null before broadcast and for transactions known not to have landed, including invalid and needs_resign intents.
  - `origin` — any — The origin object you sent on create (label, optional return_url, opaque context), echoed back verbatim; null when you sent none.
  - `origin_geo` — object | null — Where the create request came from (network + GeoIP). `ip` is visible only to the intent's owner. Null until the geo write lands.
    - `country` — string | null
    - `continent` — string | null
    - `city` — string | null
    - `region` — string | null
    - `lat` — number | null
    - `lon` — number | null
    - `timezone` — string | null
    - `asn` — number | null
    - `as_org` — string | null
    - `ip` — string | null
  - `resolution` — object | null — Where and how it landed — the slot, the commitment reached, and the validator that included it. Null until landed.
    - `landed_slot` — number | null — The slot the transaction landed in; null until landed.
    - `sent_slot` — number | null — The slot the network was in when Clear admitted the transaction — the SEND end of slot latency. Absent on rows predating this field.
    - `landed_commitment` — string | null — The deepest commitment the landing reached (processed | confirmed | finalized); null until landed. A landed-but-program-rejected transaction can report processed — the failure gate commits before deeper commitments are recorded.
    - `landed_attempt_id` — string | null — Which attempt (see `attempts[]`) actually landed; null until landed.
    - `leader` — object | null — The validator that included the transaction — its identity, client software, stake and geo (all publicly verifiable on-chain). Null before landing; geo/client/stake null when not known.
      - `identity` — string
      - `country` — string | null
      - `city` — string | null
      - `asn` — number | null
      - `as_org` — string | null
      - `lat` — number | null
      - `lon` — number | null
      - `client` — object | null — The validator's declared client software (agave | frankendancer | …); null when no version is known.
      - `stake` — number | null — Activated stake (lamports) of the validator that included the tx — null when not known.
  - `attempts[]` — object[] — Every signed version of this action Clear has driven — one per create / re-sign / bump, newest last. Each carries its own signature and blockhash so you can trace exactly which bytes were on the wire.
    - `attempt_no` — number — 1-based attempt index — bumped by each re-sign / bump.
    - `signature` — string — This attempt's transaction signature.
    - `blockhash` — string — The blockhash (or durable-nonce value) these bytes were signed against.
    - `last_valid_block_height` — number | null — The height past which this attempt's blockhash expires. Null when Clear could not resolve it — a blockhash older than the window the box tracks, which is typical of bytes a client has been retrying for a while; the attempt is still driven normally.
    - `status` — string — in_flight while the intent is live; a landed attempt carries its reached commitment (processed | confirmed | finalized). Once the intent terminalizes, an attempt that never landed tells the truth instead: superseded (a re-sign/bump replaced it, or another attempt landed) | invalid (Clear rejected the bytes before broadcast) | failed (the chain rejected this signature) | canceled (future re-broadcasts stopped) | expired (the bytes died — see resign_hint.reason).
  - `events[]` — object[] — The ordered transition timeline (oldest first) — every status change with its observation time and, where recorded, its reason. This is the audit trail behind the current `status`.
    - `at` — number — Unix-ms when Clear OBSERVED this transition — observation time, never the on-chain time (that lives in result.block_time). Same-second neighbors are real: e.g. a transaction accepted with an already-expired blockhash shows submitted and needs_resign within the same second.
    - `status` — string — The status this transition moved the intent INTO — the same vocabulary as the top-level `status`, plus result_recorded — the on-chain outcome enrichment recorded after landing.
    - `reason` — string — Why this transition happened, when recorded — needs_resign: blockhash_expired | nonce_advanced; canceled: caller_requested | leader_budget_exhausted (your give_up_after_slots bound fired) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled.
  - `resign_hint` — object — Present ONLY while status is needs_resign: why it didn't land + the exact re-sign call with this intent's real id. The needs_resign callback payload embeds the same object.
    - `reason` — string — Why the signed bytes died: blockhash_expired | nonce_advanced.
    - `action` — string — The one next action, in plain words.
    - `send` — object — A ready-to-send re-sign call, prefilled with this intent's real id.
      - `method` — string
      - `url` — string — The ABSOLUTE re-sign endpoint — the intent's own cluster send door, https://clear-<cluster>.k256.xyz/v1/clear/intents/send.
      - `body` — object
    - `retry_collapse` — string — How retries collapse onto this intent, in the ingress door's own vocabulary (API/direct: intent_id + the client_reference_id/idempotency_key body fields; drop-in RPC: the X-Clear-Reference-Id header).
  - `fee_posture` — object — How this transaction's priority fee sat against the live fee market when Clear accepted it — deliberately coarse. Snapshotted once at acceptance, so create and every later read return the SAME value. ABSENT when the fee wasn't classified at acceptance (and bundle members carry no posture) — never guessed.
    - `level` — "none" | "low" | "typical" | "high" — The create-time price band: none (no priority fee set) | low | typical | high, relative to observed network demand when Clear accepted the transaction.
    - `note` — string — A factual description of that create-time price band.
  - `decoded` — any | null — The decoded transaction message (fee payer, instructions, account keys, address-lookup-table resolution) — a read-only view of the bytes you signed. Null before decode.
  - `result` — any | null — The on-chain outcome once landed — slot, block_time, fee (lamports), compute units consumed, balance/token deltas, and program logs. Null until landed.
  - `error` — any — The exact failure detail when status is invalid (pre-broadcast validation) or failed (the chain's error plus a plain-words reading); null otherwise.
  - `not_before` — number | null — The earliest unix-ms this intent may broadcast (the not_before you set), or null for an immediate send.
  - `collect_expires_at` — number — When this multisig stops waiting for its remaining signatures (unix-ms) and cancels with reason collecting_expired — nothing is broadcast. Present only while a collection is open; defaults to 1 hour after create unless you set collect_expires_at.
  - `release` — object — The release axis — WHEN the bytes broadcast, orthogonal to `shape`.
    - `kind` — string — The release mechanism — immediate (broadcast at create) | scheduled (held for not_before) | window (broadcast now, keep trying until window_until) | triggered (armed; broadcasts on /fire).
    - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
    - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release — cancels cleanly if never fired; null otherwise.
    - `armed` — boolean — True while a triggered intent is held awaiting /fire.
    - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only) — Clear stores it opaquely and never interprets it. Null on every other release kind.
  - `created_at` — number — When Clear created this intent (unix-ms).
  - `updated_at` — number — When this intent last changed (unix-ms).
  - `terminal_at` — number | null — When the intent reached a terminal state (finalized | invalid | failed | canceled); null while still live or in needs_resign.
  - `forensics` — object — The opt-in outcome receipt: exact landed-attempt, finalized block, runtime-reported compute, charged fee, signed declaration, message-declared writable, and observed-effect evidence. Every potentially unsafe integer is a decimal string and every partial comparison carries coverage.
    - `intent_id` — string
    - `signature` — string | null
    - `cluster` — string
    - `status` — string
    - `commitment_target` — string
    - `explorer_url` — string | null
    - `landed` — boolean
    - `slot_latency` — object | null — How many slots this one transaction took from send to on-chain inclusion. Null until landed.
      - `sent_slot` — number — The slot the network was in when Clear admitted this transaction.
      - `landed_slot` — number — The slot it landed in.
      - `slots` — number — Slots from send to inclusion — 0 means it landed in the very slot you sent it. THE per-transaction latency number, the counterpart of the analytics slot_latency percentiles.
    - `pending_reason` — string | null
    - `evidence` — object
      - `state` — "available" | "partial" | "unavailable" — How much of this report is evidence-backed. "available" = every claim is byte-verified against the exact signed bytes Clear broadcast AND the finalized chain read. "partial" = real chain-derived facts with one stated gap — most commonly the signed-bytes receipt is past Clear's live window, so block/execution/compute/fee facts come from the finalized chain read alone and no byte-match is claimed (reason: landed_attempt_unavailable); block-level gaps (block_read_unavailable, block_coverage_partial, …) also report partial. "unavailable" = no chain receipt exists yet, or nothing could be read.
      - `reason` — "pending_chain_outcome" | "landed_attempt_unavailable" | "landed_attempt_mismatch" | "unsupported_transaction_version" | "malformed_transaction" | "finalized_transaction_pending" | "transaction_read_unavailable" | "transaction_metadata_unavailable" | "block_read_unavailable" | "scheduled_leader_unavailable" | "target_block_mismatch" | "target_signature_ambiguous" | "block_coverage_partial" | null — The single gap being reported, or null when evidence is fully available. landed_attempt_unavailable with state "partial" means chain-derived facts only: the signed-bytes receipt is past Clear's live window (permanent, retryable:false) or was unreachable just now (retryable:true).
      - `retryable` — boolean — true when re-requesting the report can improve it (a transient gap); false when the gap is permanent — e.g. the signed bytes are past Clear's live window and will not return.
    - `block` — object | null
      - `slot` — integer
      - `block_time` — integer | null
      - `blockhash` — string | null
      - `scheduled_leader` — string | null
      - `clear_observed_commitment_ms` — number | null — Clear-observed submission-to-commitment elapsed time; not an on-chain latency claim.
      - `transaction_index_zero_based` — integer | null
      - `transaction_count` — integer | null
    - `execution` — object | null
      - `state` — "succeeded" | "executed_reverted" | "rejected_fee_charged" | "rejected_no_fee" | "unavailable"
      - `error` — any | null
      - `error_readable` — string | null
    - `compute` — object | null
      - `runtime_reported_compute_units_exact` — string | null
      - `signed_limit_exact` — string | null
      - `signed_limit_source` — "explicit" | "implicit" | "v1_explicit" | "v1_default_zero" | "unavailable"
    - `fee` — object | null
      - `charged_total_lamports_exact` — string
      - `charged_priority_lamports_exact` — string | null
      - `transaction_signatures` — integer
      - `fee_counted_precompile_signatures` — integer
      - `signed_compute_unit_price` — object
      - `signed_compute_unit_limit_exact` — string | null
      - `signed_v1_priority_lamports_exact` — string | null
    - `block_context` — object | null
      - `state` — "available" | "partial"
      - `shared_writable_position` — object
      - `resources` — object
      - `writable_overlap` — object
      - `fee_position` — object
    - `effect` — object | null
      - `declared_label` — string | null
      - `balance_changes[]` — object[]
      - `balance_changes_complete` — boolean
      - `token_changes[]` — object[]
      - `token_changes_complete` — boolean
      - `message_declared_writable_accounts[]` — string[]
      - `inner_program_counts_by_instruction[]` — object[]
      - `inner_program_counts_complete` — boolean
      - `logs[]` — string[] | null
    - `identifiers` — object
      - `intent_id` — string
      - `signature` — string | null
      - `client_reference_id` — string | null
      - `kind` — string | null
      - `commitment_target` — string
      - `transaction_version` — "legacy" | "v0" | "v1" | "unknown"
      - `lifetime` — "recent_blockhash" | "durable_nonce" | "unknown"
      - `attempt_count` — integer

### `GET /v1/clear/bundles/{id}` — Get a bundle
- Action: `read` · MCP tool: `clear.bundles_get`
- The bundle's aggregate status and every child transaction. For live updates, subscribe to GET /v1/clear/events?id=<bn_…> (SSE, JSON long-poll, or WebSocket — one seq cursor across all three) instead of re-polling. Add ?include=forensics for the aggregate forensic report; the default read stays light.
- Path param `id` (string, required) — The bundle's id (bn_…) — from the create receipt or the feed.
- Query param `include` ("forensics") — Pass "forensics" to include the aggregate forensic report (whole and parts) inline as `forensics`. Omit for the light snapshot — no forensics unless asked.
- Response (JSON):
  - `bundle_id` — string
  - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
  - `status` — string — The bundle lifecycle — building (assembling / held before release) · running (steps executing) · completed (all steps landed) · completed_with_failures (finished, some steps did not land — see failed_count and each step in `transactions`) · stopped (halted by on_failure=stop after a step failed) · canceled (you canceled it).
  - `mode` — "sequential" | "parallel" | "dag" — Execution shape — sequential (each step after the previous lands) | parallel (all at once) | dag (per-step dependency graph; see plan_edges).
  - `on_failure` — string — What happens when a step fails to land — stop (halt the remaining steps) | continue (run the rest anyway).
  - `cluster` — string — The Solana cluster the bundle runs on — mainnet | devnet | testnet.
  - `commitment_target` — string — The landing gate applied to every step — confirmed | finalized.
  - `client_reference_id` — string | null — Your own id from create — searchable and echoed in callbacks; null when unset.
  - `origin` — any — The origin object you sent on create, echoed back; null when unset.
  - `tx_count` — number — Total steps in the bundle.
  - `landed_count` — number — How many steps have landed so far.
  - `failed_count` — number — How many steps have failed to land so far.
  - `release` — object — The release axis — WHEN the bundle sends.
    - `kind` — string — The release mechanism for the bundle — immediate | scheduled | window | triggered (see the intent `release.kind`).
    - `not_before` — number | null — Earliest broadcast time (unix-ms) for a scheduled release; null otherwise.
    - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
    - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release; null otherwise.
    - `armed` — boolean — True while a triggered bundle is held awaiting /fire.
    - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only). Null on every other release kind.
  - `created_at` — number — When the bundle was created (unix-ms).
  - `updated_at` — number — When the bundle last changed (unix-ms).
  - `terminal_at` — number | null — When the bundle reached a terminal state; null while still running.
  - `transactions[]` — object[] — The bundle's steps, in order — each is a full intent object (same shape as GET /intents/:id) plus its `step` index.
    - `intent_id` — string
    - `version` — number — Monotonic revision, bumped on every state change — the lifecycle clock. Realtime events on GET /v1/clear/events carry it; apply an event only when its version is newer than the snapshot you hold.
    - `status` — string — The lifecycle state — follow it live on GET /v1/clear/events. Held before broadcast: building (momentary, at create) · collecting (multisig — awaiting the remaining signatures) · scheduled (waiting on a future not_before / window) · armed (waiting on a trigger — POST /intents/:id/fire, or arm_expires_at). Live once broadcast, in order: submitted → processed → confirmed → finalized. Your effect applies (and the landed callback fires) when it reaches your commitment_target; Clear then keeps watching through finalized. Terminal: finalized (landed), invalid (rejected before broadcast — see `error`), failed (landed but rejected on chain — see `error`), or canceled (you stopped it — see the final event's reason). needs_resign is a RECOVERABLE stop, not terminal: the signed bytes expired and the intent waits — `resign_hint` carries the exact re-sign call.
    - `consumer` — string — The app/label you set on create — the console feed groups by it.
    - `kind` — string | null — Your optional free-text action label from create (e.g. "swap", "withdraw"); null when unset.
    - `cluster` — string — The Solana cluster this intent lives on — mainnet | devnet | testnet.
    - `commitment_target` — string — The landing gate you chose — confirmed | finalized. Clear applies your effect and fires the landed callback when the transaction reaches it, then always keeps watching through finalized.
    - `client_reference_id` — string | null — Your own id from create — searchable in the feed (?search=) and echoed in callbacks; null when you sent none.
    - `give_up_after_slots` — integer — Your opt-in give-up bound in slots from the send, when you set one — absent otherwise. When it fires the intent settles as canceled with reason leader_budget_exhausted.
    - `idempotency_key` — string — The dedup key for this intent (your idempotency_key, else the tx signature) — a resend under it collapses to this one record instead of double-sending, for at least 72 hours after this intent settles.
    - `bundle_id` — string | null — The bundle this intent belongs to, or null for a standalone send.
    - `shape` — "single" | "scheduled" — single = broadcast at create; scheduled = held or windowed at create (any not_before, window_until, or trigger). The exact release kind is in `release`.
    - `submitted_via` — string — How it entered Clear — api (structured /intents/send) | rpc (drop-in sendTransaction) | direct (submitted straight to Clear's send endpoint).
    - `signature` — string | null — The transaction signature from the accepted wire bytes. When the chain has observed an attempt this is that observed signature; otherwise it is the latest accepted attempt, including held, expired, invalid, or canceled-before-broadcast transactions. Null only while a multisig transaction is still collecting signatures or no attempt exists.
    - `explorer_url` — string | null — A ready-to-open block-explorer link when the signature was broadcast and may have a chain record. Null before broadcast and for transactions known not to have landed, including invalid and needs_resign intents.
    - `origin` — any — The origin object you sent on create (label, optional return_url, opaque context), echoed back verbatim; null when you sent none.
    - `origin_geo` — object | null — Where the create request came from (network + GeoIP). `ip` is visible only to the intent's owner. Null until the geo write lands.
      - `country` — string | null
      - `continent` — string | null
      - `city` — string | null
      - `region` — string | null
      - `lat` — number | null
      - `lon` — number | null
      - `timezone` — string | null
      - `asn` — number | null
      - `as_org` — string | null
      - `ip` — string | null
    - `resolution` — object | null — Where and how it landed — the slot, the commitment reached, and the validator that included it. Null until landed.
      - `landed_slot` — number | null — The slot the transaction landed in; null until landed.
      - `sent_slot` — number | null — The slot the network was in when Clear admitted the transaction — the SEND end of slot latency. Absent on rows predating this field.
      - `landed_commitment` — string | null — The deepest commitment the landing reached (processed | confirmed | finalized); null until landed. A landed-but-program-rejected transaction can report processed — the failure gate commits before deeper commitments are recorded.
      - `landed_attempt_id` — string | null — Which attempt (see `attempts[]`) actually landed; null until landed.
      - `leader` — object | null — The validator that included the transaction — its identity, client software, stake and geo (all publicly verifiable on-chain). Null before landing; geo/client/stake null when not known.
    - `attempts[]` — object[] — Every signed version of this action Clear has driven — one per create / re-sign / bump, newest last. Each carries its own signature and blockhash so you can trace exactly which bytes were on the wire.
      - `attempt_no` — number — 1-based attempt index — bumped by each re-sign / bump.
      - `signature` — string — This attempt's transaction signature.
      - `blockhash` — string — The blockhash (or durable-nonce value) these bytes were signed against.
      - `last_valid_block_height` — number | null — The height past which this attempt's blockhash expires. Null when Clear could not resolve it — a blockhash older than the window the box tracks, which is typical of bytes a client has been retrying for a while; the attempt is still driven normally.
      - `status` — string — in_flight while the intent is live; a landed attempt carries its reached commitment (processed | confirmed | finalized). Once the intent terminalizes, an attempt that never landed tells the truth instead: superseded (a re-sign/bump replaced it, or another attempt landed) | invalid (Clear rejected the bytes before broadcast) | failed (the chain rejected this signature) | canceled (future re-broadcasts stopped) | expired (the bytes died — see resign_hint.reason).
    - `events[]` — object[] — The ordered transition timeline (oldest first) — every status change with its observation time and, where recorded, its reason. This is the audit trail behind the current `status`.
      - `at` — number — Unix-ms when Clear OBSERVED this transition — observation time, never the on-chain time (that lives in result.block_time). Same-second neighbors are real: e.g. a transaction accepted with an already-expired blockhash shows submitted and needs_resign within the same second.
      - `status` — string — The status this transition moved the intent INTO — the same vocabulary as the top-level `status`, plus result_recorded — the on-chain outcome enrichment recorded after landing.
      - `reason` — string — Why this transition happened, when recorded — needs_resign: blockhash_expired | nonce_advanced; canceled: caller_requested | leader_budget_exhausted (your give_up_after_slots bound fired) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled.
    - `resign_hint` — object — Present ONLY while status is needs_resign: why it didn't land + the exact re-sign call with this intent's real id. The needs_resign callback payload embeds the same object.
      - `reason` — string — Why the signed bytes died: blockhash_expired | nonce_advanced.
      - `action` — string — The one next action, in plain words.
      - `send` — object — A ready-to-send re-sign call, prefilled with this intent's real id.
      - `retry_collapse` — string — How retries collapse onto this intent, in the ingress door's own vocabulary (API/direct: intent_id + the client_reference_id/idempotency_key body fields; drop-in RPC: the X-Clear-Reference-Id header).
    - `fee_posture` — object — How this transaction's priority fee sat against the live fee market when Clear accepted it — deliberately coarse. Snapshotted once at acceptance, so create and every later read return the SAME value. ABSENT when the fee wasn't classified at acceptance (and bundle members carry no posture) — never guessed.
      - `level` — "none" | "low" | "typical" | "high" — The create-time price band: none (no priority fee set) | low | typical | high, relative to observed network demand when Clear accepted the transaction.
      - `note` — string — A factual description of that create-time price band.
    - `decoded` — any | null — The decoded transaction message (fee payer, instructions, account keys, address-lookup-table resolution) — a read-only view of the bytes you signed. Null before decode.
    - `result` — any | null — The on-chain outcome once landed — slot, block_time, fee (lamports), compute units consumed, balance/token deltas, and program logs. Null until landed.
    - `error` — any — The exact failure detail when status is invalid (pre-broadcast validation) or failed (the chain's error plus a plain-words reading); null otherwise.
    - `not_before` — number | null — The earliest unix-ms this intent may broadcast (the not_before you set), or null for an immediate send.
    - `collect_expires_at` — number — When this multisig stops waiting for its remaining signatures (unix-ms) and cancels with reason collecting_expired — nothing is broadcast. Present only while a collection is open; defaults to 1 hour after create unless you set collect_expires_at.
    - `release` — object — The release axis — WHEN the bytes broadcast, orthogonal to `shape`.
      - `kind` — string — The release mechanism — immediate (broadcast at create) | scheduled (held for not_before) | window (broadcast now, keep trying until window_until) | triggered (armed; broadcasts on /fire).
      - `window_until` — number | null — Landing-window deadline (unix-ms) for a window release; null otherwise.
      - `arm_expires_at` — number | null — TTL (unix-ms) for a triggered release — cancels cleanly if never fired; null otherwise.
      - `armed` — boolean — True while a triggered intent is held awaiting /fire.
      - `trigger_spec` — any | null — Your own resolve condition, echoed verbatim from create (triggered release only) — Clear stores it opaquely and never interprets it. Null on every other release kind.
    - `created_at` — number — When Clear created this intent (unix-ms).
    - `updated_at` — number — When this intent last changed (unix-ms).
    - `terminal_at` — number | null — When the intent reached a terminal state (finalized | invalid | failed | canceled); null while still live or in needs_resign.
    - `step` — integer — This step's index in the bundle, the SAME number `plan_edges` uses for from_step/to_step. Array order already matches it, but the field means you can key a step without relying on position.
  - `plan_edges[]` — object[] — The plan's dependency edges (step index → step index): a dag's real waits_on, a sequence's implicit chain, a parallel's empty fan.
    - `from_step` — number
    - `to_step` — number
  - `forensics` — object — The bounded opt-in bundle receipt with lifecycle facts, member receipt evidence, and covered/expected counts.
    - `bundle_id` — string
    - `shape` — "sequential" | "parallel" | "dag"
    - `status` — string
    - `cluster` — string — The Solana cluster the bundle ran on.
    - `on_failure` — string — What happens when a step fails to land — stop (halt the remaining steps) | continue (run the rest anyway).
    - `commitment_target` — string — The commitment gate each step must reach — confirmed | finalized.
    - `plan_edges[]` — object[] — The real dependency edges for a DAG, the implicit chain for a sequence, or an empty array for a parallel bundle.
      - `from_step` — integer
      - `to_step` — integer
    - `aggregate` — object
      - `members_total` — integer
      - `members_landed` — integer — Steps that reached the bundle's commitment gate — the bundle head's own landed_count semantics. A failed step was included on chain but never reached its gate, so it counts under members_failed, never here.
      - `members_failed` — integer
      - `members_not_started` — integer
      - `total_fee` — object
      - `total_runtime_reported_compute` — object
      - `wall_clock_ms` — number | null
      - `slot_span` — object
      - `co_landing` — object
      - `scheduled_leaders` — object
      - `inter_step_latency[]` — object[]
      - `sibling_writable_overlap` — object
      - `stopped_at_step` — integer | null
    - `gantt[]` — object[]
      - `intent_id` — string
      - `step_index` — integer
      - `label` — string
      - `submitted_at` — number | null
      - `landed_at` — number | null
      - `slot` — integer | null
      - `scheduled_leader` — string | null
      - `status` — string
    - `members[]` — object[]
      - `intent_id` — string
      - `step_index` — integer
      - `lifecycle_status` — string
      - `report` — object | null

### `GET /v1/clear/feed` — List executions
- Action: `read` · MCP tool: `clear.feed`
- One row per execution — standalone intents and bundles alike. A bundle is a single row; drill into it for its steps. Filter by type and by outcome (comma-separated: in_flight, needs_you, scheduled, landed), and supply exact from/to boundaries to scope every outcome to the same creation-time window. Cursor-paginated newest first.
- Query param `type` ("single" | "release" | "bundle") — Filter by record shape: single (one immediate tx) · release (scheduled/triggered/window) · bundle. Omit for every shape.
- Query param `outcome` (string) — Comma-separated outcome buckets, unioned: in_flight, needs_you, scheduled, landed.
- Query param `cluster` ("mainnet" | "devnet" | "testnet") — Filter to one cluster. Omit for every cluster (the feed spans mainnet/devnet/testnet).
- Query param `source` ("api" | "rpc" | "direct") — Filter by how it was submitted: api (structured /intents·/bundles) · rpc (drop-in sendTransaction) · direct (submitted straight to Clear's send endpoint). Omit for every lane.
- Query param `search` (string) — Free-text match on your client_reference_id (the id you set on send). Omit for no search.
- Query param `cursor` (string) — Pagination cursor — pass the `next_cursor` from the previous page. Omit for the first (newest) page.
- Query param `limit` (integer) — Rows per page (1–200). Defaults to 50.
- Query param `from` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Query param `to` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Response (JSON):
  - `items[]` — object[]
    - `kind` — "intent" | "bundle"
    - `id` — string
    - `type` — "single" | "release" | "bundle"
    - `variant` — string | null
    - `label` — string | null
    - `status` — string
    - `cluster` — string
    - `commitment_target` — string
    - `client_reference_id` — string | null — The caller's own reference id, or null. The feed's `search` matches this column, so a hit can show why the row matched.
    - `signature` — string | null — Accepted transaction signature for an intent; null for bundles or while a multisig transaction is still collecting signatures.
    - `explorer_url` — string | null — Explorer link only when the signature was broadcast and may have a chain record.
    - `not_before` — number | null
    - `tx_count` — number | null
    - `landed_count` — number | null
    - `child_statuses[]` — string[] | null
    - `submitted_via` — string
    - `canceled_reason` — string | null — Only on canceled rows — why it canceled: caller_requested (you canceled it) | leader_budget_exhausted (your give_up_after_slots bound fired without a landing) | arm_expired | window_closed | collecting_expired | bundle_sealed | bundle_canceled. Null for every other status, and for bundles. Distinguishes a cancel you performed from the auto give-up you pre-declared.
    - `landed_leader_identity` — string | null — Landed validator identity (intent only; null for bundles). Present on every cluster once landed.
    - `landed_leader_client_family` — string | null — The client software of the validator that included the tx (e.g. agave, firedancer). Null today — client attribution is not yet wired for landed leaders.
    - `landed_leader_client_version` — string | null — The client version of the validator that included the tx (e.g. 2.1.11). Null today — client attribution is not yet wired for landed leaders.
    - `created_at` — number
    - `updated_at` — number
    - `terminal_at` — number | null
  - `next_cursor` — string | null
  - `degraded` — boolean — True when the history store could not be reached and this page may be incomplete — retry shortly rather than treating an empty page as truth.
  - `as_of_ms` — number | null — Unix ms of the freshest record consulted for this page; null when nothing was readable.

### `GET /v1/clear/requests` — Inspect your API calls
- Action: `read` · MCP tool: `clear.requests`
- See exactly what you sent and what Clear answered on each of your recent API calls (`items`, newest first — the quote, the accept / needs_resign outcome, or the error), plus a per-endpoint performance summary — calls, error rate, and p50/p90/p99 latency. Exact from/to boundaries scope both rows and summary; range_days remains a compatibility summary window. Debug a quote or a send without adding your own logging. Filter by `endpoint` and `cluster`; the raw signed transaction is never captured, and secret-bearing calls record metadata only.
- Query param `endpoint` (string) — Filter to one operation, named by its op id — the same vocabulary `by_endpoint` reports: clear.intents_send, clear.fees_quote, clear.intents_sign, clear.intents_fire, clear.intents_bump, clear.intents_cancel, clear.bundles_send, clear.bundles_cancel, clear.intents_get, clear.bundles_get, clear.feed, … Omit for every operation.
- Query param `cluster` (string) — Filter to calls on one cluster when the product records a cluster. Omit for every cluster.
- Query param `status` ("2xx" | "3xx" | "4xx" | "5xx" | "error") — Filter the feed and endpoint summary by response status class. `error` means status >= 400.
- Query param `tier` (integer) — Filter by capture tier: 0 = Full bodies, 1 = metadata only.
- Query param `cursor` (string) — Pagination cursor for the `items` feed — pass the `next_cursor` from the previous page.
- Query param `limit` (integer) — Rows per page for the `items` feed (1–200). Defaults to 50.
- Query param `range_days` (integer) — Compatibility window in days (1–90) for `by_endpoint`. Exact from/to filters both items and summary. Defaults to 14.
- Query param `from` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Query param `to` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Response (JSON):
  - `items[]` — object[] — Recent keyed customer API calls, newest first. Dashboard-session, service, and internal calls are never included.
    - `timestamp` — number — Unix-ms when the call was served.
    - `endpoint` — string — The captured customer-facing operation.
    - `method` — string — HTTP method.
    - `status` — number — HTTP status returned.
    - `latency_ms` — number — Server-side latency in milliseconds.
    - `cluster` — string | null — Cluster stamped on the call, or null when the product has no cluster dimension.
    - `request_body` — any — Captured request JSON, or null when the capture tier carried no body.
    - `response_body` — any — Captured response JSON, or null when the capture tier carried no body.
    - `request_size` — number — Captured request body size in bytes before truncation.
    - `response_size` — number — Captured response body size in bytes before truncation.
    - `user_agent` — string | null — Caller's User-Agent when captured.
    - `client_id` — string | null — Caller-supplied X-Client-ID when present.
    - `tier` — number — Capture tier: 0 = Full, 1 = MetadataOnly.
    - `country_code` — string | null — Caller's GeoIP country.
    - `city` — string | null — Caller's GeoIP city.
    - `region` — string | null — Caller's GeoIP region/subdivision.
    - `continent_code` — string | null — Caller's GeoIP continent code.
    - `asn` — number | null — Caller's network ASN.
    - `as_org` — string | null — Caller's network organization name.
  - `by_endpoint[]` — object[] — Per-endpoint performance over the selected window.
    - `endpoint` — string — The captured operation.
    - `calls` — number — Number of calls to this endpoint in the window.
    - `error_rate` — number — Percent of calls with status >= 400 (0–100).
    - `p50_latency_ms` — number — Median server-side latency in milliseconds.
    - `p90_latency_ms` — number — p90 server-side latency in milliseconds.
    - `p99_latency_ms` — number — p99 server-side latency in milliseconds.
  - `next_cursor` — string | null — Pass as `cursor` to fetch the next older page of items.
  - `degraded` — boolean — true when the inspection store is unavailable; items and by_endpoint are then empty.

### `GET /v1/clear/callback-secret` — Callback secret status
- Action: `read` · MCP tool: `clear.callback_secret_status`
- Reports whether this workspace has a callback signing secret and when it was created or last rotated — never the secret itself. Check it before setting a `callback`: a secret must exist first.
- Response (JSON):
  - `exists` — boolean — Whether a callback signing secret is set for this workspace. It must be true before any intent may set a `callback` — mint one with POST /callback-secret.
  - `created_at` — number — Unix-ms the secret was first created; absent when none is set.
  - `rotated_at` — number | null — Unix-ms of the most recent rotation, or null if it has never been rotated; absent when no secret is set.

### `POST /v1/clear/callback-secret` — Create/rotate callback secret
- Action: `write` · MCP tool: `clear.callback_secret_rotate`
- Mints the HMAC secret Clear uses to sign your callbacks and returns it once — store it now, it's never re-readable. Required before any intent can set a `callback`. Creating the first secret needs nothing else; REPLACING a live one is irreversible and refuses without `confirm_rotate: true`.
- Request body (JSON, required):
  - `confirm_rotate` — boolean — Required ONLY when a secret already exists: set true to confirm replacing it. Rotating invalidates the previous secret immediately and irreversibly; deliveries keep being signed with the OLD secret for a short propagation window, so accept both until the window closes.
- Response (JSON):
  - `secret` — string — The HMAC signing secret, returned ONCE and never re-readable — store it now. Clear signs every outbound callback with it (verify via the X-Clear-Signature header).
  - `rotated` — boolean — true if this replaced an existing secret (any previously-issued secret is now invalid); false on first creation.
  - `effective_in_seconds` — number — Roughly how long until every send box signs with THIS secret (it propagates to the send path, it is not instant). Accept BOTH the old and the new secret in your verifier until this elapses — a delivery signed moments after rotation still carries the previous one.

### `GET /v1/clear/callbacks/health` — Callback delivery health
- Action: `read` · MCP tool: `clear.callbacks_health`
- Workspace-wide callback health across intents and bundles: open work, automatic retries, and dead-lettered deliveries that exhausted Clear's automatic retry window. Use this as the callback outage signal.
- Query param `since` (integer) — Your acknowledgement time (unix ms). When given, dead_lettered_since counts only deliveries that dead-lettered after it — alert on NEW failures, not the ones you already handled.
- Response (JSON):
  - `state` — "healthy" | "retrying" | "action_required" — healthy (nothing outstanding) | retrying (deliveries are being re-attempted) | action_required (something dead-lettered — see dead_lettered).
  - `configured` — boolean
  - `open` — number
  - `retrying` — number
  - `dead_lettered` — number
  - `oldest_open_at` — number | null
  - `next_retry_at` — number | null
  - `oldest_dead_lettered_entity_id` — string | null — The oldest dead-lettered intent or bundle id in the window; its callback log holds every attempt and the full request to replay. Null when nothing is dead-lettered.
  - `latest_dead_lettered_entity_id` — string | null — The newest dead-lettered intent or bundle id — the failure that most recently happened. Null when nothing is dead-lettered.
  - `latest_dead_lettered_at` — number | null — When the newest dead-letter happened (its final attempt, unix ms). Null when nothing is dead-lettered.
  - `dead_lettered_since` — number | null — How many deliveries dead-lettered after `since`. Null when `since` was not given.
  - `receivers[]` — object[] — The receivers behind dead_lettered, worst first (up to three) — the hosts to fix.
    - `host` — string — The receiver host that refused the deliveries.
    - `dead_lettered` — number — Deliveries to this host that exhausted retries in the window.
    - `last_status` — number | null — The HTTP status it last answered; null when it could not be reached at all.
    - `latest_dead_lettered_at` — number — Its newest dead-letter (final attempt, unix ms).
    - `latest_entity_id` — string — The intent or bundle behind that newest dead-letter.
  - `checked_at` — number

### `GET /v1/clear/intents/{id}/callbacks` — Intent callback log
- Action: `read` · MCP tool: `clear.intents_callbacks`
- Every callback Clear delivered for this intent — the destination url, the exact signed envelope, each attempt's status, response and latency, and the retry / dead-letter state. Your own delivery records.
- Path param `id` (string, required) — The intent's id (lc_…) or the bundle's id (bn_…) whose callback deliveries to read.
- Response (JSON):
  - `configured` — boolean
  - `deliveries[]` — object[]
    - `id` — string
    - `event` — string
    - `url` — string
    - `payload` — string | null
    - `request_headers` — object
    - `attempt_no` — number — Monotonic attempt count across Clear's automatic retries.
    - `last_status` — string | null
    - `response_body` — string | null
    - `response_time_ms` — number | null
    - `attempts[]` — object[]
      - `attempt_no` — number — Monotonic sequence number for this delivery attempt.
      - `at` — number
      - `status` — string
      - `response_body` — string | null
      - `response_time_ms` — number | null
      - `ok` — boolean
    - `delivered_at` — number | null
    - `dead_lettered` — boolean
    - `next_retry_at` — number | null
    - `backpressured_at` — number | null — When delivery was most recently delayed by receiver-capacity pressure without consuming an attempt.
    - `created_at` — number

### `POST /v1/clear/intents/{id}/callbacks/{delivery_id}/resend` — Resend a callback delivery
- Action: `write` · MCP tool: `clear.callbacks_resend`
- Re-send one callback delivery. The exact envelope Clear already signed is POSTed again on a fresh retry ladder — use it after fixing an endpoint that was down, or when your receiver lost a delivery. A delivery that is still retrying automatically is left alone; retry it once it stops.
- Path param `id` (string, required) — The intent id that owns the delivery.
- Path param `delivery_id` (string, required) — The delivery id from the callback log (the envelope's `delivery_id`).
- Response (JSON):
  - `configured` — boolean
  - `deliveries[]` — object[]
    - `id` — string
    - `event` — string
    - `url` — string
    - `payload` — string | null
    - `request_headers` — object
    - `attempt_no` — number — Monotonic attempt count across Clear's automatic retries.
    - `last_status` — string | null
    - `response_body` — string | null
    - `response_time_ms` — number | null
    - `attempts[]` — object[]
      - `attempt_no` — number — Monotonic sequence number for this delivery attempt.
      - `at` — number
      - `status` — string
      - `response_body` — string | null
      - `response_time_ms` — number | null
      - `ok` — boolean
    - `delivered_at` — number | null
    - `dead_lettered` — boolean
    - `next_retry_at` — number | null
    - `backpressured_at` — number | null — When delivery was most recently delayed by receiver-capacity pressure without consuming an attempt.
    - `created_at` — number

### `GET /v1/clear/bundles/{id}/callbacks` — Bundle callback log
- Action: `read` · MCP tool: `clear.bundles_callbacks`
- Every bundle-level callback Clear delivered for this bundle — the bundle/step event, the step it was about, the destination url, the exact signed envelope, each attempt's status, response and latency, and the retry / dead-letter state. Your own delivery records.
- Path param `id` (string, required) — The intent's id (lc_…) or the bundle's id (bn_…) whose callback deliveries to read.
- Response (JSON):
  - `configured` — boolean
  - `deliveries[]` — object[]
    - `id` — string
    - `event` — string
    - `step_intent_id` — string | null
    - `url` — string
    - `payload` — string | null
    - `request_headers` — object
    - `attempt_no` — number — Monotonic attempt count across Clear's automatic retries.
    - `last_status` — string | null
    - `response_body` — string | null
    - `response_time_ms` — number | null
    - `attempts[]` — object[]
      - `attempt_no` — number — Monotonic sequence number for this delivery attempt.
      - `at` — number
      - `status` — string
      - `response_body` — string | null
      - `response_time_ms` — number | null
      - `ok` — boolean
    - `delivered_at` — number | null
    - `dead_lettered` — boolean
    - `next_retry_at` — number | null
    - `backpressured_at` — number | null — When delivery was most recently delayed by receiver-capacity pressure without consuming an attempt.
    - `created_at` — number

### `GET /v1/clear/events/ws-token` — Realtime events WebSocket token
- Action: `read` · MCP tool: `clear.events_ws_token`
- A 30-second token for the realtime lifecycle stream (wss…/v1/clear/events) — browsers can't set Authorization on a WS handshake, so fetch this and open the returned url immediately. Scoped to your workspace and (when passed) one intent/bundle id. Non-browser clients skip this and connect with Authorization: Bearer directly; SSE and long-poll on the same route need no token at all.
- Query param `id` (string) — Optional intent (lc_…) or bundle (bn_…) id — mints a token scoped to that one execution's stream. Omit for your whole workspace feed.
- Response (JSON):
  - `token` — string — Pass as ?token= on wss…/v1/clear/events. Gateway-audience only (never authenticates anywhere else); bound to your workspace and the exact ?id= you minted with.
  - `expires_in` — number — Seconds until expiry (30). Mint immediately before connecting; reconnects mint a fresh one.
  - `url` — string — The ready-to-open wss:// URL with the token (and id) already attached.

### `GET /v1/clear/avoid-list` — Get your avoid list
- Action: `read` · MCP tool: `clear.avoid_list`
- Your standing delivery control, per network (?cluster=mainnet|devnet|testnet): the validators, networks (AS), countries, and client software Clear will never send your transactions through on that cluster. The only other delivery choice is per-send: give_up_after_slots on the send (maxRetries on the drop-in RPC) bounds how long Clear drives it. Everything else about delivery, Clear decides for you.
- Query param `cluster` ("mainnet" | "devnet" | "testnet", required) — Which network's avoid list to read.
- Response (JSON):
  - `avoid` — object
    - `identities[]` — string[]
    - `asns[]` — number[]
    - `countries[]` — string[]
    - `clients[]` — string[]
  - `updated_at` — number | null — Unix-ms of the last change — null if never set. Changes apply on the very next send.

### `POST /v1/clear/avoid-list` — Update your avoid list
- Action: `write` · MCP tool: `clear.avoid_list_set`
- Replaces the avoid list for the given cluster. It takes effect on your very next send — an avoided validator is never routed through, from your very next transaction onward. Requires write access.
- Request body (JSON, required):
  - `cluster` — "mainnet" | "devnet" | "testnet" (required) — Which network's avoid list to replace.
  - `avoid` — object (required) — The full avoid list — this REPLACES the stored list (read-modify-write). At most 200 entries combined across identities, asns, and countries.
- Response (JSON):
  - `avoid` — object
    - `identities[]` — string[]
    - `asns[]` — number[]
    - `countries[]` — string[]
    - `clients[]` — string[]
  - `updated_at` — number | null — Unix-ms of the last change — null if never set. Changes apply on the very next send.

### `GET /v1/clear/endpoints` — Send endpoints
- Action: `read` · MCP tool: `clear.endpoints`
- The send base URL per cluster — https://clear-<cluster>.k256.xyz. SDKs cache this list and send transactions there directly. Reads, status, and cancel stay on https://api.k256.xyz.
- Response (JSON):
  - `direct_endpoints[]` — object[]
    - `cluster` — string
    - `url` — string — The single geo send base for the cluster, e.g. https://clear-devnet.k256.xyz.

### `GET /v1/clear/analytics` — Execution analytics
- Action: `read` · MCP tool: `clear.analytics`
- Your selected-window execution analytics: standing (total, landed, failed, in-flight, success rate), slot latency (p50/p90/p99 slots from send to inclusion, and the share landing within a single slot — the practical success criterion for landing on Solana), dynamically bucketed volume and landing latency, equal-duration KPI comparisons, most-invoked programs, priority fees, and shape mix. Exact from/to boundaries scope every selected-window field. All computed over your own executions.
- Query param `range_days` (integer) — Compatibility trailing window in days (1–90). Exact from/to takes precedence. Defaults to 14.
- Query param `cluster` ("mainnet" | "devnet" | "testnet") — The cluster to report on. Omit for the workspace total across all clusters.
- Query param `from` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Query param `to` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Response (JSON):
  - `range_days` — number
  - `window` — object — Exact [from,to) unix-ms window and chart bucket used for every selected-window aggregate.
    - `from` — number
    - `to` — number
    - `bucket_ms` — number
  - `status` — object — Landing standing for executions created in the selected window — the at-a-glance totals and attention buckets that filter the Console feed over the same exact rows.
    - `total_executions` — number — Standalone intents accepted for execution plus bundles in the selected window; pre-broadcast invalid acknowledgements are reported separately.
    - `landed` — number — How many landed — intents (confirmed/finalized) + bundles (completed / completed_with_failures).
    - `invalid` — number — Drop-in sends rejected before broadcast after their signature acknowledgement; excluded from landing-rate and fee metrics.
    - `failed` — number — Standalone intents that landed but were rejected on chain.
    - `in_flight` — number — Intents + bundles created in the selected window that are still actively landing.
    - `success_rate` — number | null — landed / (landed + needs_resign + gave_up + bundles_halted). Misses include signed-byte expiry, your requested slot deadline expiring without landing, and halted bundles. A transaction rejected by its program on chain still counts as landed. Explicit caller cancellations, unreleased or in-flight work, and invalid pre-broadcast acknowledgements are excluded. Null when no executions have settled.
    - `needs_resign` — number — Intents waiting on your re-signature (recoverable stop — the bytes expired).
    - `gave_up` — number — Sends stopped without landing when your give_up_after_slots deadline expired. Counted as delivery misses in success_rate, separately from explicit caller cancellations.
    - `collecting` — number — Intents still gathering their remaining transaction signatures.
    - `held` — number — Scheduled/armed intents + bundles — waiting on a time or trigger, not failed.
    - `bundles_halted` — number — Bundles stopped by on_failure=stop after a step failed — need attention.
  - `kpis` — object
    - `executions` — object — Executions in the selected window, compared with the immediately preceding equal-duration window.
      - `value` — number | null
      - `delta` — number | null
    - `landing_rate_window` — object
      - `value` — number | null
      - `delta` — number | null
    - `avg_land_ms_window` — object
      - `value` — number | null
      - `delta` — number | null
    - `in_flight` — number
    - `p50_land_ms_window` — number | null
  - `series[]` — object[] — Dynamically bucketed selected-window series; bucket_ms is declared in window.
    - `ts` — number
    - `total` — number
    - `landed` — number
    - `failed` — number
    - `p50_ms` — number | null
  - `top_programs[]` — object[]
    - `label` — string
    - `value` — number
  - `by_shape` — object
    - `single` — number
    - `scheduled` — number
    - `bundle` — number
  - `transaction_versions` — object | null — Wire versions of captured raw/RPC and structured send requests in this exact window. Includes retries and refusals, not unique transactions, bundle children or proven landings. Counts sum to total. Null means version counts are unavailable; other analytics retain their own availability.
    - `total` — integer
    - `v1` — integer
    - `v0` — integer
    - `legacy` — integer
    - `unknown` — integer — Captured sends with missing or unrecognized transaction version; never assumed legacy.
  - `slot_latency` — object — Per-transaction inclusion distance from Clear's observed admission slot, conditional on measured landings. Unlanded offers and client-to-Clear transit are not represented by this distribution.
    - `measured` — number — Landings with both Clear's observed admission slot and an inclusion slot at or after it. This is the denominator for within_one_slot_rate. Zero means no measured landings; percentiles and rate are then null.
    - `p50_slots` — number | null — Median slots from Clear's observed admission slot to inclusion, among measured landings. Null when measured = 0.
    - `p90_slots` — number | null — 90th-percentile slots from Clear's observed admission slot to inclusion, among measured landings. Null when measured = 0.
    - `p99_slots` — number | null — 99th-percentile slots from Clear's observed admission slot to inclusion, among measured landings. Null when measured = 0.
    - `within_one_slot_rate` — number | null — Fraction of measured landings included in Clear's observed admission slot or the next slot. The denominator is measured landings, not all offered transactions; client-to-Clear transit is not measured here. Null when measured = 0.
  - `slot_distribution` — object — Measured landings bucketed by distance from Clear's observed admission slot. Buckets sum to slot_latency.measured; unlanded offers and client-to-Clear transit are not represented.
    - `same_slot` — number — Included in Clear's observed admission slot.
    - `next_slot` — number — Landed one slot later.
    - `slots_2` — number — Two slots later.
    - `slots_3_5` — number — Three to five slots later.
    - `slots_6_10` — number — Six to ten slots later.
    - `slots_11_plus` — number — Eleven or more slots later — the slow tail.
  - `fees` — object — Priority-fee efficiency over your OWN landed sends (from the create-time economics snapshot) — the OUTCOME 'are you paying efficiently / how did your fee sit vs the market', not quote-door usage. Same exact selected window + cluster as the op.
    - `sends` — number — Landed sends in the range that carry a known compute-unit price — the denominator for the shares and median below. 0 when you have no priced landed sends (the whole block is then an honest empty: null shares/median, 0 total).
    - `paid_fee_share` — number | null — Fraction of those landed sends that carried a priority fee (cu_price > 0). Null when sends = 0.
    - `zero_fee_share` — number | null — Fraction that carried NO priority fee (cu_price = 0). paid_fee_share + zero_fee_share = 1. Null when sends = 0.
    - `median_priority_fee_micro_lamports` — number | null — Median compute-unit price (micro-lamports per CU) carried by landed sends. Null when sends = 0. This is a factual price position, not proof that a higher or lower fee was necessary.
    - `total_priority_fee_lamports` — number — Estimated priority fees across landed sends with recorded CU price and limit: Σ ceil(cu_price × cu_limit / 1_000_000). v1 carries a signed lamport total, so reconstructing it from its derived rate is approximate. Missing budgets do not contribute; zero does not establish zero spend. Not a billing total; use transaction receipts for exact charges.
    - `fee_posture_mix` — object — How each landed send's fee sat vs the live market at acceptance — the same coarse posture (none/low/typical/high) the intent DTO's fee_posture carries, counted across the range. Outcome, not fee-market machinery.
      - `none` — number — No priority fee set.
      - `low` — number — In the low band for network demand when Clear accepted it.
      - `typical` — number — In line with network demand.
      - `high` — number — In the high band for network demand when Clear accepted it.
      - `unclassified` — number — Landed with an economics row but no classification (the fee oracle was cold at create) — honest, never bucketed into a posture.
    - `series[]` — object[] — Dynamically bucketed fee trend for interactive clients.
      - `ts` — number — Bucket start (unix-ms); width is window.bucket_ms.
      - `paid_fee_share` — number | null
      - `median_priority_fee_micro_lamports` — number | null
  - `programs_scanned` — number

### `GET /v1/clear/network` — Network conditions
- Action: `read` · MCP tool: `clear.network`
- Current conditions per cluster from real chain data — the recent priority-fee distribution and trend, and recent block fullness. No score and no recommended fee; Clear shows the conditions, you draw the conclusion.
- Response (JSON):
  - `clusters[]` — object[]
    - `cluster` — string
    - `available` — boolean — Whether current conditions are priced for this cluster. false = no conditions data here right now — nothing more; use the percentiles and trend only when true.
    - `p50` — number | null
    - `percentiles` — object | null
      - `p25` — number
      - `p50` — number
      - `p75` — number
      - `p90` — number
    - `trend[]` — object[]
      - `slot` — number
      - `value` — number | null
    - `fullness[]` — object[] — Recent blocks' execution compute units (raw). Deliberately no percentage: the per-block cap is priced in cost units (signatures + write locks + data + loaded accounts + execution), so execution-CU ÷ cap would understate real fullness.
      - `slot` — number
      - `cu` — number
    - `priced_count` — number

### `GET /v1/clear/senders/reputation` — Your sender activity and fee usage
- Action: `read` · MCP tool: `clear.sender_reputation`
- Your workspace's captured send requests on one cluster over the selected window, their priority-fee share, and a fee-usage signal. Counts are requests, not unique transactions or proven landings. Includes a bucketed send-count trend. Informational only; fee usage does not establish landing success or the fee a transaction needs. No activity returns null standing; unavailable reads return an error.
- Query param `cluster` ("mainnet" | "devnet" | "testnet") — The cluster to read your sender standing for. Defaults to mainnet — standing is per-cluster.
- Query param `range` ("24h" | "7d" | "30d" | "90d" | "365d") — Preset trend window. Exact from/to takes precedence.
- Query param `from` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Query param `to` (string) — Exact ISO-8601 boundary. Supply both from and to; the interval is [from, to).
- Response (JSON):
  - `cluster` — string
  - `range` — string — Label for the selected window.
  - `window` — object
    - `from` — number
    - `to` — number
    - `bucket_ms` — number
  - `window_standing` — object | null — Standing computed over the exact selected window, or null when there was no captured activity. Unavailable reads return an error.
    - `total` — number — Captured send requests in the window, not unique transactions or landings.
    - `paid_fee_share` — number — Share of captured sends that carried a priority fee (0..1).
    - `zero_fee_share` — number — Share that carried no priority fee (0..1). paid_fee_share + zero_fee_share = 1.
    - `first_seen` — number | null — Unix-ms of the earliest captured send in the window.
    - `last_seen` — number | null — Unix-ms of the most recent captured send in the window.
    - `recommended_action` — object — Your one recommended action for this cluster — informational only; nothing is throttled without your action.
      - `action` — "none" | "add_priority_fee" — Fee-usage signal: add_priority_fee when at least half the sends have zero priority fee; otherwise none. Not a fee quote or landing-success measurement.
      - `note` — string — The recommendation in plain words.
  - `series[]` — object[] — Send-request trend for the cluster over the selected range. Empty buckets contain zero; unavailable reads return an error.
    - `t` — number — Bucket start (unix-ms).
    - `landings` — number — Captured send requests in the bucket; this field does not count on-chain landings.
