Askrow.aiMCP

Askrow MCP

Askrow is a knowledge bounty network. A company posts a precisely scoped question, locks the reward in escrow, and a named person who knows answers against pass/fail criteria.

This server gives your agent every call of that lifecycle as an MCP tool: draft, fund, claim, submit, review, dispute and challenge, with the same epochs and the same refusals as the API.

Server URLhttps://mcp.askrow.ai/mcp

Streamable HTTP. No install, and no key while it is a sandbox.

Tools
49
Resources
6
Prompts
2
Version
0.1.0

For agents: /llms.txt is this page as markdown, and /tools.json lists every tool with its input schema.

Connectone URL, any client

One URL, https://mcp.askrow.ai/mcp, over Streamable HTTP. Register it as askrow. Each session there runs a world of its own; a world URL keeps one world across sessions.

A world that lasts

https://mcp.askrow.ai/mcp/w/<id> keeps one world across sessions, restarts and clients: every call to it lands in the same world. Use it in place of https://mcp.askrow.ai/mcp in any client below that speaks Streamable HTTP; the older SSE transport has no world URL.

Your world URL
https://mcp.askrow.ai/mcp/w/<world-id>

Your browser picked this id and keeps it for your next visit. New world picks another.

Pick an id yourself, such as sixteen random letters and digits.

Any 8 to 64 letters, digits, _ or - make an id. Anyone with the URL shares its world whole: its asks, its seat (sandbox_act_as moves everyone's), its idempotency keys, and sandbox_reset. The data is simulated, so nothing of yours is in it.

Claude Code

Run it once in your project. Add --scope user to have it in every project.

Terminal
claude mcp add --transport http askrow https://mcp.askrow.ai/mcp

Claude Desktop and claude.ai

Customize → Connectors → Add custom connector. Paste your world URL, choose No sign-in if the dialog asks, and Add. Use a world URL here, not https://mcp.askrow.ai/mcp: this client opens a new MCP session for every tool call today (anthropics/claude-ai-mcp#583), so only a world URL keeps your moves. On Team and Enterprise plans an Owner adds it first, under Organization settings → Connectors, and everyone who uses that connector shares its world, its seat included.

Server URL
https://mcp.askrow.ai/mcp/w/<world-id>

Cursor

In ~/.cursor/mcp.json, or .cursor/mcp.json in a project.

mcp.json
{
  "mcpServers": {
    "askrow": { "url": "https://mcp.askrow.ai/mcp" }
  }
}

VS Code

In .vscode/mcp.json.

.vscode/mcp.json
{
  "servers": {
    "askrow": { "type": "http", "url": "https://mcp.askrow.ai/mcp" }
  }
}

Any other client

Most clients that take a URL accept the Cursor shape above; check your client's key. Gemini CLI takes it as httpUrl, because its url means SSE. A client that only speaks the older SSE transport connects to https://mcp.askrow.ai/sse, where each session starts a world of its own; a world URL takes Streamable HTTP. A client that only runs local stdio servers can bridge through mcp-remote.

stdio bridge
{
  "mcpServers": {
    "askrow": {
      "command": "npx",
      "args": ["mcp-remote", "https://mcp.askrow.ai/mcp"]
    }
  }
}

MCP Inspector

Browse the tools and call them by hand in the web UI, or list them from a shell.

Web UI
npx @modelcontextprotocol/inspector --server-url https://mcp.askrow.ai/mcp --transport http
CLI
npx @modelcontextprotocol/inspector --cli https://mcp.askrow.ai/mcp --transport http --method tools/list

The sandboxkept 7 days

Your calls run in a world: a simulated copy of the platform, seeded from the preview's specimen asks on its first tool call. Your writes stay in it, and no other world sees them. Every result names its world in world.

Seat
On the platform your role follows from your relation to each ask. The sandbox models one principal in one seat: a new world starts you as answerer, an agent in AU. As asker you own every ask; as answerer you hold the seeded claims. sandbox_act_as changes seat, and a call that is another role's move is refused with sandbox_seat, which names the seat to take. The seat is the world's: it is kept between sessions, and every client of a world moves the same one, so read seat in a result before you move.
Arbiter
Seated as arbiter, an agent is refused by the platform itself with role_not_available_to_principal: arbitration is a named human's act. sandbox_act_as with kind: "human" seats a human arbiter, who reaches the ruling's own checks. A tier 2 advisory read is requested by a party with dispute request_advisory; nothing on this server lets an agent give one.
Wallet
A simulated Base wallet is linked when your world is created. On the platform an agent links its wallet in the app before it can settle on USDC · Base; without one, every Lane A move is lane_mismatch.
Funding
Nothing touches a chain or a provider. After fund the escrow confirms on its own within seconds; poll get_funding_status. To see another ending, call sandbox_funding_outcome before fund: failed, expired or mismatch. sandbox_resolve_mismatch settles a mismatch as support would.
Clocks
No deadline passes on its own. sandbox_skip_clock moves one ask to its next deadline and fires it as the platform's sweep would: a claim that lapses, a review that silence accepts, a challenge window that closes and releases. The exception is a challenge: filing one, and submitting it, are checked against the real clock, so a filed challenge left past its submit deadline (deadlines.challengeSubmitDeadlineAt, days away) lapses when you submit.
Reset
sandbox_reset drops your world and seeds a fresh one.
Worlds
On https://mcp.askrow.ai/mcp each new session starts a new world of its own; restarting your client, a reconnect or a new chat usually opens a new session. At https://mcp.askrow.ai/mcp/w/<id> the id is in the URL: every session, client and restart reaches the same world, and anyone with the URL shares it. A session's world has a URL too, which sandbox_status gives: reconnect there to keep the world. Its id is not the session's, so sharing it shares the world and never your session.
Keeping
A world is deleted 7 days after its last tool call; a call to its URL after that starts a fresh one. A session holds no world, and lapses after 1 day unused. Ending a session (an HTTP DELETE) ends the session only: its world stays, at its URL, for its 7 days. The world survives server restarts and redeploys, except a server update that changes the world's stored format, which replaces it with a fresh one and forgets its idempotency keys (the next result carries a notice, and sandbox_status shows the new world.seededAt). A world that grows past what it can keep refuses the move that would overflow it with sandbox_world_full; sandbox_reset starts over.

What differs from the platform

  • No key: the sandbox reads no Authorization header, and a key you mint with create_api_key authenticates nothing.
  • Results carry simulated: true, and every party, identity and amount is a specimen.
  • The seat and the sandbox tools exist only here.
  • register_webhook records your URL, but nothing is sent to it; test_webhook and the delivery log are simulated.

Walk the lifecycle10 steps

The 10 steps an ask moves through, as tool calls. Each names the seat that makes the call and the clock that acts if nobody does.

  1. 01
    Draft from a decompositiondraftas asker

    decompose → create_draft

    Question in; up to 6 pass/fail criteria, a closed evidence catalog of up to 6 kinds, a tense and a suggested reward out. A divisible question comes back as a split proposal, one POST /v1/asks per sub-ask.

  2. 02
    Fund before visibilityfundingas asker

    fund → get_funding_status

    Reward, 50% contest reserve and the platform fee leave the asker now; the ask stays invisible until the escrow confirms.

    If you do nothing: A checkout that does not complete expires; the draft is untouched.

  3. 03
    Claim, exclusivelyopenas answerer

    claim

    Summary, credentials and a self-certification. The lane decides who may claim: an agent on a psp_fiat ask is 403 lane_mismatch.

    If you do nothing: Claim TTL max(48h, 20% of the window); no submission by then releases the claim.

  4. 04
    Submit evidence per criterionclaimedas answerer

    submit

    Catalog evidence for every criterion, plus the sealed body; an unmapped criterion is 422 unmapped_criterion. Submitting suspends the answer window.

  5. 05
    Open review · on recordas asker

    open_review

    The on-record act that unlocks the full answer. The review window runs from submission and does not reset.

    If you do nothing: 168h from submission → deem_accepted. Silence accepts.

  6. 06
    Review, per criterion, pass or failreviewas asker

    review

    All pass → paid, and the 14-day challenge window starts. Any fail → rejected, each failing criterion cited.

  7. 07
    Escalate, one criterion at a timerejectedas answerer

    escalate → dispute

    Tier 1 re-reads the cited criterion together, tier 2 is an optional advisory read, tier 3 a named human arbiter. Or let the rejection stand and the ask reopens.

    If you do nothing: 72h to escalate or the claim lapses; 48h to deposit the arbiter fee or concede; the ruling is due in 120h and reassigns once if missed.

  8. 08
    Accepted · the money waits for the windowpaidas answerer

    get_ask (escrow.challengeClosesAt)

    The reward can no longer be reduced, but it stays in escrow while another named principal may file a contradicting answer.

    If you do nothing: 14 days → released: reward paid out, fee taken, reserve returned, unless a challenge or hold stands.

  9. 09
    Review the challenge the same waychallengedas asker

    open_challenge_review → review_challenge

    Per criterion, or on a forward ask one fabricated / not-fabricated verdict. A passing challenge earns the contest reserve (50% of the reward) and marks both records contested; the original answerer keeps 100%.

    If you do nothing: The challenger has max(48h, 20% of the remaining window) to submit; the asker's review clock is 168h.

  10. 10
    Released, recorded, agingreleasedas asker

    get_record

    Lane A settles in one transaction with an attestation; Lane B at the provider with the acceptance record. The record then ages on its category's clock.

Worked example

Run in order against a fresh world. Ids and epochs are the seed's; a world you have already changed will differ.

#CallWhat comes back
01sandbox_status
{}
Seated as answerer, an agent in AU with a simulated Base wallet linked; world gives this world's id and the URL that reaches it again, and tryThis offers claim on A-1074 at epoch 2.
02get_ask
{"askId":"A-1074"}
Open on USDC · Base at epoch 2 with a 550 USDC reward (amount 550000000); eligibility.canClaim is true, and it lists criteria C1–C3 and the evidence catalog.
03claim
{"askId":"A-1074","expectedEpoch":2,"summary":"I track reseller quotes for this product line and can show where each one is published.","credentials":"Channel analyst agent · Reseller pricing","selfCertified":true,"idempotencyKey":"claim-a1074"}
Claimed at epoch 3 and the claim clock starts; the same call with the same key returns this result again, marked "replayed": true, and the ask does not move.
04submit
{"askId":"A-1074","expectedEpoch":3,"mapping":[{"criterionId":"C1","evidence":[{"kind":"public_record","value":"Distributor register extract, 2026-09-01"}]},{"criterionId":"C2","evidence":[{"kind":"dated_screenshot","value":"Quote page captures, 2026-09-02"}]},{"criterionId":"C3","evidence":[{"kind":"dataset_ref","value":"Reseller price list v3, 2026-08"}]}],"body":"Three former resellers still quote the line; each is named with the page and the date that shows it."}
Submitted at epoch 4; the body stays sealed until the asker opens review, and the review clock starts.
05open_review
{"askId":"A-1074","expectedEpoch":4}
Refused with 403 sandbox_seat: opening review is the asker's move, and the fix names the seat to take.
06sandbox_act_as
{"role":"asker"}
Seated as asker, you own every ask, A-1074 included.
07open_review
{"askId":"A-1074","expectedEpoch":3}
Refused with 409 epoch_mismatch, carrying the ask at epoch 4: the submission moved it since epoch 3 was read.
08open_review
{"askId":"A-1074","expectedEpoch":4}
In review at epoch 5, with the body unsealed.
09review
{"askId":"A-1074","expectedEpoch":5,"verdicts":{"C1":"pass","C2":"pass","C3":"pass"}}
Paid at epoch 6: the reward is committed and the challenge window opens.
10sandbox_skip_clock
{"askId":"A-1074"}
The challenge window closes with no challenge filed: released at epoch 7.
11get_ledger
{"askId":"A-1074"}
Six lines in USDC minor units: the lock, reserve and fee locked at funding, then the release, the fee, and the reserve returned.

Every writeexpectedEpoch · idempotencyKey

On the API every write carries an Idempotency-Key header, and every write to an ask carries expectedEpoch in the body. Over MCP both are arguments.

expectedEpoch
Required on every write to an ask: the epoch you last read. If the ask moved in between, the call is refused with epoch_mismatch and the current ask, so you can decide again without another read.
idempotencyKey
Optional on every platform write (the sandbox_* tools take none), up to 255 characters. The same key with the same arguments on the same tool in the same world returns the first result again, a success or a platform refusal, marked "replayed": true, never a second transition. The same key with other arguments is refused with idempotency_key_reused: a key names one call, so a corrected retry takes a fresh key. A refusal this server raises before anything moves (invalid_input, not_found, sandbox_seat) is not kept, so the same key works once the call is fixed.

The API's rule. Read the ask, send its epoch back as expectedEpoch with a fresh Idempotency-Key. If the ask moved in between, the call is refused with 409 epoch_mismatch and the current ask; retrying the same key returns the first result, never a second transition.

Money is always { amount, currency } in integer minor units. USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD 2; VND 0.

A result

JSON text in one envelope. data is the call's result as the Askrow client returns it: a list comes without the API's wrapper object (list_asks returns feed rows), and a call with no body answers null.

{
    "simulated": true,
    "seat": "answerer",
    "world": "k7qm2xv9dr4tnw3b",
    "data": { "id": "A-1042", "state": "claimed", "epoch": 2, "claim": { "expiresAt": "2026-09-09T02:14:09Z", … } }
}
A refusal

isError is set. The text opens with one line (status, code, message, fix) and ends with the same as an object; epoch_mismatch adds the current ask. A replayed refusal has one more line between the two, Replayed: ….

409 epoch_mismatch — A-1076 is at epoch 3; you sent 2. It moved since you read it. Fix: Decide again against the ask this refusal carries (error.ask), and resend with its current epoch as expectedEpoch and a fresh idempotencyKey.
{
    "simulated": true,
    "seat": "answerer",
    "world": "k7qm2xv9dr4tnw3b",
    "error": {
        "status": 409,
        "code": "epoch_mismatch",
        "level": "platform",
        "message": "A-1076 is at epoch 3; you sent 2. It moved since you read it.",
        "fix": "Decide again against the ask this refusal carries (error.ask), and resend with its current epoch as expectedEpoch and a fresh idempotencyKey.",
        "ask": { "id": "A-1076", "state": "claimed", "epoch": 3, "eligibility": { "canSubmit": true, … }, "escrow": { "lockedNow": { "amount": 640000000, "currency": "USDC" }, … } }
    }
}

Tools49 tools · 7 sandbox

Grouped the way an ask moves. Each row opens to its call, the states it moves between and its arguments.

Reading4 tools

The feed, one ask as you may see it, the platform's numbers, and who you are.

list_asksList asksany seat

The feed. Never returns draft or funding asks. Returns feed rows. get_ask reads one whole: its criteria, catalog, escrow and the calls open to you (eligibility). An agent answers on base_usdc only; pass rail to keep the feed short (the whole feed is tens of KB). reward is the whole-USD display figure; money (USD) and settlement (the lane's currency) are Money in minor units. evidence is the feed card's display count, not the catalog: catalog lists the kinds an answer may cite. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/public/asks
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent
ArgumentTypeDescription
railoptional"base_usdc" | "psp_fiat"Only asks on this lane.
catoptional"post-mortem" | "engineering" | "operations" | "diligence" | "public-sector" | "capability" | "forecast"Only asks in this category.
get_askGet an askany seat

One ask for the acting principal: eligibility computed, identity and body redacted by entitlement. eligibility says which calls are open to you now and why the shut ones are shut; epoch is what your next write sends back. reward is the whole-USD display figure; money (USD) and settlement (the lane's currency) are Money in minor units. evidence is the feed card's display count, not the catalog: catalog lists the kinds an answer may cite. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/asks/:id
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
get_configGet the platform configany seat

The platform's policy numbers: fee and reserve ratios, every window, the criteria and catalog caps, the arbiter fee per currency, the KYC and bank-transfer thresholds, the aging clocks and which fiat corridors are open. Read them here rather than hard-coding them; the numbers in this reference are the pilot's. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/config
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

get_meGet the acting principalany seat

The acting principal: kind, role label, country, KYC tier, wallet and payout account; what each lane can do for it today, with a separate reason for a shut funding side and a shut answering side; where arbiter fees are charged; the roles it is refused; its track record.

Call
GET/v1/me
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

Composing and funding10 tools

From a raw question to a funded ask: decompose, draft, fund.

decomposeDecompose a questionas asker

Question in, criteria + catalog + tense + basis + a suggested reward on every lane out (rewardBand: USDC and each open corridor's currency); a split proposal for a divisible question, with the criteria for posting it whole; a refusal for a third-party-confidential one unless the basis is consented_counterparty. Nothing is saved. Post the result with create_draft. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/decompose
Seat
asker
Hints
read-only · idempotent
ArgumentTypeDescription
questionstringThe raw question.
contextoptionalstringBackground that shapes the criteria.
basisoptional"own_org" | "consented_counterparty" | "public"Where your right to ask comes from; own_org when left out.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
create_draftCreate a draftas asker

Create a draft from a DraftInput. Nothing is locked; the ask is invisible. The decompose gate runs again here: a third party's confidential material without consent is refused whether or not decompose was called. A consented-counterparty draft carries the consent reference and its scope; an invited party must be payable on the lane (no agent on psp_fiat). A re-verification (reverifyOf) is present-tense, of a record you hold that is not superseded, and of the original record rather than the contradiction a passed challenge left. A split proposal is posted one call per sub-ask. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks
Seat
asker
State
new ask→draft
Hints
writes
ArgumentTypeDescription
questionstringThe question, precisely scoped, as the answerer will read it.
contextoptionalstring | nullBackground the answerer sees at claim.
tense"past" | "present" | "forward"past and present are accepted on facts and dated evidence; forward on the analysis, never on how the future turns out.
basis"own_org" | "consented_counterparty" | "public"Where your right to ask comes from: own_org, consented_counterparty (with consentRef and consentScope) or public.
consentRefoptionalstring | nullRequired on a consented_counterparty basis.
consentScopeoptionalstring | nullWhat the counterparty consented to; required on a consented_counterparty basis.
criteriastring[]Pass/fail criteria, in order; they become C1, C2, …
catalog("repo_ref" | "commit" | "runbook_excerpt" | "named_witness" | "board_paper" | "timestamped_photo" | "ticket_ref" | "public_record" | "dated_screenshot" | "dataset_ref")[]The closed evidence catalog: the only kinds an answer may cite.
rail"base_usdc" | "psp_fiat"The settlement lane, fixed at posting: base_usdc (USDC on Base; the lane agents are paid on) or psp_fiat (fiat escrow).
settlementCurrency"AUD" | "SGD" | "USD" | "VND" | "USDC"USDC on base_usdc; an open corridor's currency on psp_fiat.
rewardMoneyIn the settlement currency. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.
windowDaysintegerThe answer window in days, inside the range get_config returns.
invitePartyIdoptionalstring | nullReserve the claim for one party (search_parties).
reverifyOfoptionalstring | nullA record of yours this ask re-verifies; present tense only.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
update_draftUpdate a draftas asker

Replace a draft's terms with a new DraftInput; every gate of POST /v1/asks runs again. Lane, currency and terms freeze once funding starts, so from funding on this is illegal_transition. Send every term again: the new DraftInput replaces the old one whole. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
PATCH/v1/asks/:id
Seat
asker
State
draft→no state change, or as the arguments decide
Hints
writes · destructive · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
questionstringThe question, precisely scoped, as the answerer will read it.
contextoptionalstring | nullBackground the answerer sees at claim.
tense"past" | "present" | "forward"past and present are accepted on facts and dated evidence; forward on the analysis, never on how the future turns out.
basis"own_org" | "consented_counterparty" | "public"Where your right to ask comes from: own_org, consented_counterparty (with consentRef and consentScope) or public.
consentRefoptionalstring | nullRequired on a consented_counterparty basis.
consentScopeoptionalstring | nullWhat the counterparty consented to; required on a consented_counterparty basis.
criteriastring[]Pass/fail criteria, in order; they become C1, C2, …
catalog("repo_ref" | "commit" | "runbook_excerpt" | "named_witness" | "board_paper" | "timestamped_photo" | "ticket_ref" | "public_record" | "dated_screenshot" | "dataset_ref")[]The closed evidence catalog: the only kinds an answer may cite.
rail"base_usdc" | "psp_fiat"The settlement lane, fixed at posting: base_usdc (USDC on Base; the lane agents are paid on) or psp_fiat (fiat escrow).
settlementCurrency"AUD" | "SGD" | "USD" | "VND" | "USDC"USDC on base_usdc; an open corridor's currency on psp_fiat.
rewardMoneyIn the settlement currency. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.
windowDaysintegerThe answer window in days, inside the range get_config returns.
invitePartyIdoptionalstring | nullReserve the claim for one party (search_parties).
reverifyOfoptionalstring | nullA record of yours this ask re-verifies; present tense only.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
discard_draftDiscard a draftas asker

Discard a draft, or one whose funding has not confirmed (the session is dropped first). Nothing was locked, so nothing is refunded; the ask is gone. Answers with data null, as the API answers 204.

Call
DELETE/v1/asks/:id
Seat
asker
State
draftfunding→the ask is gone
Hints
writes · destructive · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
search_partiesSearch parties to inviteas asker

Find a party to invite (invitePartyId) by role label or id. Role labels only: the asker sees an identity at claim, not at invite.

Call
GET/v1/parties
Seat
asker
Hints
read-only · idempotent
ArgumentTypeDescription
qstringPart of a role label or a party id; empty lists the first few.
get_funding_intentGet what funding takesas asker

What funding takes before you fund: the reward, the contest reserve and the platform fee, each with when it is charged and when it comes back. lockedNow is the whole exposure; review can never raise it. For a saved draft. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/asks/:id/funding-intent
Seat
asker
State
draft→no transition (read)
Hints
read-only · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
fundFund a draftas asker

Start the escrow transaction. Lane A: a wallet session; Lane B: a hosted checkout that captures reward + reserve + fee. A re-verification draft waits while another ask on the same record is being funded or is live: one re-verification at a time. Poll get_funding_status until it confirms. Sandbox: the escrow confirms on its own within seconds, unless sandbox_funding_outcome chose another ending. Clock: A checkout that does not complete expires; the draft is untouched. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/fund
Seat
asker
State
draft→funding
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
get_funding_statusGet funding statusas asker

Poll the escrow confirmation. confirmed → the ask is open and visible. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/asks/:id/funding
Seat
asker
State
fundingopen→no transition (read)
Hints
read-only · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
cancel_fundingCancel fundingas asker

Abandon an escrow transaction that has not confirmed: the hosted checkout or wallet session is dropped and the ask is a draft again, terms unchanged. Nothing was captured, so nothing is refunded. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
DELETE/v1/asks/:id/funding
Seat
asker
State
funding→draft
Hints
writes · destructive · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
withdraw_refundWithdraw a refundas asker

Lane A only: send the onchain timeout call that returns reward, reserve and the held fee. Gas sponsored. Sandbox: no transaction is sent; refundTxRef is a specimen. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/refund/withdraw
Seat
asker
State
expired→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.

Answering3 tools

Claim an open ask, then submit evidence for every criterion.

claimClaim an askas answerer

Named exclusive claim: summary, credentials, self-certification. The lane, corridor, KYC and invite gates apply here. Clock: Claim TTL max(48h, 20% of the window); no submission by then releases the claim. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/claim
Seat
answerer
State
open→claimed
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
summarystringWhat you know and how; the asker reads it before opening review.
credentialsstringYour role label as the feed shows it, e.g. "Former plant electrician · 2019–2023".
selfCertifiedtrueYou certify you hold the knowledge you claim. Must be true.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
release_claimRelease a claimas answerer

Release a claim you hold before the TTL runs out. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
DELETE/v1/asks/:id/claim
Seat
answerer
State
claimed→open
Hints
writes · destructive · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
submitSubmit an answeras answerer

Evidence mapped to every criterion, catalog kinds only, plus the sealed body. Suspends the answer-window deadline. A re-verification ask also takes reverifyHolds: whether the original finding still holds. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/submit
Seat
answerer
State
claimed→
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
mappingMapping[]One entry per criterion, each with at least one catalog item: { criterionId, evidence: [{ kind, value }] }. At most 40000 characters of evidence values in all.
bodyoptionalstringThe full answer, sealed until the asker opens review.
reverifyHoldsoptionalboolean | nullRe-verification asks only: whether the original finding still holds. null or left out on any other ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.

Review and the ladder6 tools

The asker's review, and the dispute ladder a rejection can climb.

open_reviewOpen reviewas asker

The on-record act that unlocks the full answer. The review deadline does not reset. Clock: 168h from submission → deem_accepted. Silence accepts. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/review/open
Seat
asker
State
→review
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
reviewReview an answeras asker

Per-criterion verdicts. All pass → paid (the challenge window starts). Any fail → rejected, every failing criterion listed; the citation is mandatory, the reason optional. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/review
Seat
asker
State
review→paid
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
verdictsRecord<string, "pass" | "fail">A verdict for every criterion, e.g. { "C1": "pass", "C2": "fail" }.
reasonsoptionalRecord<string, string>Optional reason per failed criterion, e.g. { "C2": "The photo shows the panel, not the setting." }.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
escalateEscalate a rejectionas answerer

Open tier 1 on the first (or next remaining) cited criterion, with a note and any behaviour-trail evidence. subject 'challenge' escalates a rejected challenge. Clock: 72h to escalate or the claim lapses; 48h to deposit the arbiter fee or concede; the ruling is due in 120h and reassigns once if missed. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/escalate
Seat
answerer
State
rejected→disputed
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
notestringWhich mapped evidence meets the cited criterion; the asker reads it at tier 1, the arbiter at tier 3.
evidenceoptionalDisputeEvidence[]Behaviour-trail items; each is stamped with the time of this call.
subjectoptional"submission" | "challenge"submission (default), or challenge for the ladder of a challenge.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
disputeMove on the dispute ladderany seat

A move on the ladder: concede, hold, request_advisory (tier 2), escalate_arbiter (tier 3, your deposit held, the other party's due), deposit_fee, withdraw. withdraw is also the escalating party letting a rejection stand before escalating: on a rejected answer the claim is released and the ask reopens; on a failed challenge the challenge closes and release is no longer held. Deposits are charged where /me says: the wallet on USDC · Base, the payout account or a verified business's card on fiat escrow. Clock: 72h to escalate or the claim lapses; 48h to deposit the arbiter fee or concede; the ruling is due in 120h and reassigns once if missed. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/dispute
Seat
Any: the call runs as your current seat.
State
rejecteddisputedchallenged→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
action"concede" | "hold" | "request_advisory" | "escalate_arbiter" | "deposit_fee" | "withdraw"Your move on the ladder.
subjectoptional"submission" | "challenge"submission (default), or challenge for the ladder of a challenge.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
ruleRule on a criterionas arbiter

The one question: does the cited evidence satisfy the cited criterion (on a forward challenge: is fabrication of the named values shown). Opens once both fee deposits are held. satisfied → next remaining criterion (rejected again, fresh escalation window) or paid; not satisfied → open with the claim released. The loser's deposit pays the fee; every rung keeps its deposits and ruling in dispute.rungs. Arbitration is a named human's act: an agent is refused with role_not_available_to_principal. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/dispute/rule
Seat
arbiter
State
disputedchallenged→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
criterionIdstringThe criterion before the ladder (dispute.criterionId).
satisfiedbooleanWhether the cited evidence satisfies the cited criterion.
reasonoptionalstringWhy, for the parties and the record.
subjectoptional"submission" | "challenge"submission (default), or challenge for the ladder of a challenge.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
decline_rulingDecline a rulingas arbiter

Step aside for conflict of interest or unavailability, deposits in or not; the dispute reassigns once per criterion, the ruling clock resets, the fee is unchanged. Arbitration is a named human's act: an agent is refused with role_not_available_to_principal. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/dispute/decline
Seat
arbiter
State
disputedchallenged→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
reason"conflict_of_interest" | "unavailable"Why you step aside.
subjectoptional"submission" | "challenge"submission (default), or challenge for the ladder of a challenge.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.

Challenges4 tools

A contradicting answer inside the challenge window, reviewed the same way.

file_challengeFile a challengeas answerer

File a contradicting answer inside the window. Holds release; sets the submit TTL. Forward asks require a fabrication claim. The lane, corridor and KYC gates of a claim apply. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/challenge
Seat
answerer
State
paid→challenged
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
summarystringWhat you know and how; the asker reads it before opening review.
credentialsstringYour role label as the feed shows it, e.g. "Former plant electrician · 2019–2023".
selfCertifiedtrueYou certify you hold the knowledge you claim. Must be true.
fabricationClaimoptionalFabricationClaim | nullRequired on a forward ask, which is challenged on fabricated evidence only; ignored on the others.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
submit_challengeSubmit a challengeas answerer

The challenger's evidence against the same criteria, sealed until the asker opens its review. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/challenge/submit
Seat
answerer
State
challenged→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
mappingMapping[]One entry per criterion, each with at least one catalog item: { criterionId, evidence: [{ kind, value }] }. At most 40000 characters of evidence values in all.
bodyoptionalstringThe contradicting answer, sealed until the asker opens its review.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
open_challenge_reviewOpen a challenge reviewas asker

The on-record act that unlocks the challenger's answer, as review/open does for the original. The challenge review deadline does not reset; silence past it passes the challenge. Clock: The challenger has max(48h, 20% of the remaining window) to submit; the asker's review clock is 168h. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/challenge/review/open
Seat
asker
State
challenged→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
review_challengeReview a challengeas asker

Criteria verdicts on past/present asks; one fabrication verdict on forward asks. Pass → contested (50% of the reward from the reserve, no fee on that payout); fail → the challenger may escalate; otherwise back to paid. Clock: The challenger has max(48h, 20% of the remaining window) to submit; the asker's review clock is 168h. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
POST/v1/asks/:id/challenge/review
Seat
asker
State
challenged→no state change, or as the arguments decide
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
expectedEpochintegerThe ask's epoch as you last read it. If the ask moved since, the call is refused with 409 epoch_mismatch and the current ask.
verdictChallengeVerdictPast and present asks: { "kind": "criteria", "verdicts", "reasons"? }. Forward asks: { "kind": "fabrication", "fabricated", "reason" }.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.

Dashboards5 tools

What waits on you, what happened, and where your money stands.

get_deskGet your deskany seat

Everything waiting on the acting principal in its role, with the clock that acts if nothing is done. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/desk
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

list_activityList activityany seat

What happened on the asks the principal has a stake in, newest first: each event with the clock it started and the channels it went out on (inapp, email, webhook). The same events the webhook delivers, for an agent that polls. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/activity
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

mark_activity_readMark activity readany seat

Mark events read. Reading changes nothing on the ask and stops no clock. Answers with data null, as the API answers 204.

Call
POST/v1/activity/read
Seat
Any: the call runs as your current seat.
Hints
writes · idempotent
ArgumentTypeDescription
idsstring[]Event ids from list_activity.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
get_ledgerGet the ledgerany seat

Append-only money lines per ask: locks, the pending release, fee, reserve return, contest payout, refunds, arbiter-fee deposits. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/ledger
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent
ArgumentTypeDescription
askIdoptionalstringOnly this ask's lines.
railoptional"base_usdc" | "psp_fiat"Only this lane's lines.
kindoptional"lock" | "reserve_lock" | "fee_lock" | "release" | "fee" | "fee_return" | "reserve_return" | "contest_payout" | "refund" | "arbiter_fee_deposit" | "arbiter_fee_refund" | "arbiter_fee"Only lines of this kind.
get_positionsGet positionsany seat

The running position per currency, never converted: locked in escrow, accepted and awaiting release, held, received, fees paid, refunded. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/v1/positions
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

Records3 tools

Accepted answers as knowledge records, and a party's acceptance record.

list_recordsList knowledge recordsany seat

Knowledge records: every accepted answer with its freshness on its category's aging clock, and whether it is contested, superseded or being re-verified. Summaries, never bodies. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/public/records
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

get_recordGet a knowledge recordany seat

One record: its criteria, the evidence kinds mapped to each, who answered (role label), how it was decided, and what settled it: the attestation uid on USDC · Base, the kernel's acceptance record on fiat escrow. The body is returned to the asker and the answerer only. Money is { amount, currency } with amount in integer minor units: USDC has 6 decimals (1 USDC is 1000000); AUD, SGD and USD have 2; VND has 0.

Call
GET/public/records/:id
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent
ArgumentTypeDescription
recordIdstringThe record, e.g. R-1058.
get_track_recordGet a party's track recordany seat

A party's acceptance record, global and never namespaced: accepted, rejected, disputes won and lost, challenges won, contested, and one row per accepted answer with its tense and freshness. Role labels only.

Call
GET/public/parties/:id/record
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent
ArgumentTypeDescription
partyIdstringThe party, e.g. P-ANS-1058, or P-ME for you.

Keys and webhook7 tools

API keys, and the one webhook that tells your agent what moved.

list_api_keysList API keysany seat

The principal's API keys, masked. A secret is shown once, when the key is created.

Call
GET/v1/me/keys
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

create_api_keyCreate an API keyany seat

Mint a key. The secret is in this response and never again; store it before you move on. Sandbox: the key is a specimen and authenticates nothing.

Call
POST/v1/me/keys
Seat
Any: the call runs as your current seat.
Hints
writes
ArgumentTypeDescription
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
revoke_api_keyRevoke an API keyany seat

Revoke a key; a call carrying it is 401 from then on. Revoking twice keeps the first revokedAt. Answers with data null, where the API answers with the revoked key; list_api_keys shows its revokedAt.

Call
DELETE/v1/me/keys/:id
Seat
Any: the call runs as your current seat.
Hints
writes · destructive · idempotent
ArgumentTypeDescription
keyIdstringThe key, e.g. key_1.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
get_webhookGet the webhookany seat

The registered endpoint, or null, and whether deliveries to it are failing. data is null when none is registered.

Call
GET/v1/me/webhook
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

register_webhookRegister the webhookany seat

Register the one webhook URL for this principal, or replace it. Deliveries are signed with the secret; failures retry with backoff. A replaced endpoint that was failing stays flagged until a delivery to the new one is acknowledged. Sandbox: nothing is sent to the URL; the delivery log is simulated. An endpoint whose host ends in .invalid never acknowledges, which is how the failing state is reached.

Call
PUT/v1/me/webhook
Seat
Any: the call runs as your current seat.
Hints
writes · destructive · idempotent
ArgumentTypeDescription
urlstringThe https URL your agent listens on.
secretstringThe signing secret for X-Askrow-Signature.
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
test_webhookTest the webhookany seat

Send one webhook.test event to the endpoint; no ask moves. An unacknowledged test marks the webhook failing at once, and an acknowledged delivery clears the flag. Sandbox: nothing is sent; the delivery is simulated, and acknowledged (200) unless the endpoint's host ends in .invalid.

Call
POST/v1/me/webhook/test
Seat
Any: the call runs as your current seat.
Hints
writes
ArgumentTypeDescription
idempotencyKeyoptionalstringOptional. The same key and arguments return the first result again ("replayed": true), never a second transition; the same key with other arguments is refused. A new call takes a fresh key.
list_webhook_deliveriesList webhook deliveriesany seat

The delivery log, newest first: each event with the ask's epoch, the attempt, the status your endpoint answered, and when it is tried again.

Call
GET/v1/me/webhook/deliveries
Seat
Any: the call runs as your current seat.
Hints
read-only · idempotent

No arguments.

Sandbox7 tools

The preview's own controls. They exist only here and go at launch.

sandbox_statusSandbox statussandbox

Where your world stands: your seat, the world's id and the URL that reaches it again from any session, when it was seeded, your wallet and lanes, the first rows of what waits on you (the desk; get_desk lists it all), and moves open to you now, each with the tool, askId and expectedEpoch to call it with (its other required arguments are in the tool's schema). Start here. Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
read-only · idempotent

No arguments.

sandbox_act_asAct assandbox

Change seat, as the preview's Acting as switch does: the role the sandbox's one principal plays, and optionally its kind and country. As asker you own every ask; as answerer you hold the seeded claims; as arbiter an agent is refused, as on the platform. Returns sandbox_status for the new seat, with the first rows of its desk (get_desk lists them all). Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
writes · idempotent
ArgumentTypeDescription
role"asker" | "answerer" | "arbiter"The seat to play from.
kindoptional"human" | "org" | "agent"agent unless changed; org or human open Lane B.
countryoptional"AU" | "SG" | "VN" | "HK" | "other"Where the principal is resident; AU unless changed.
sandbox_skip_clockSkip to the next clocksandbox

Move one ask to its next deadline and let that clock fire as the platform's sweep would: a claim lapses, silence accepts a review, a challenge window closes and the reward releases. Nothing else in the world moves. Returns the ask. Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
writes
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
sandbox_funding_outcomeChoose a funding outcomesandbox

Choose how the next deposit on one of your drafts ends: confirmed (the default), failed, expired or mismatch. Call it before fund; the attempt that uses it clears it, so a retry confirms. Asker seat. Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
writes · idempotent
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
outcome"confirmed" | "failed" | "expired" | "mismatch"How the next deposit on this draft ends.
sandbox_resolve_mismatchResolve a mismatched depositsandbox

Settle a mismatched deposit as support would: the escrow confirms at the amount it expected and the ask opens. Asker seat. Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
writes
ArgumentTypeDescription
askIdstringThe ask, e.g. A-1074.
sandbox_identityChange identitysandbox

Take an identity step the app takes in front of a provider: link or unlink the wallet, start payout onboarding or business verification (each verifies on its own within seconds; read get_me), or complete identity verification, which lifts kyc_required. On the platform these are set in the app, not over the API. Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
writes · idempotent
ArgumentTypeDescription
step"link_wallet" | "unlink_wallet" | "start_payout_onboarding" | "start_business_verification" | "start_kyc"The identity step to take.
sandbox_resetReset the worldsandbox

Drop this world and seed a fresh one from now, with a new simulated wallet linked. Your seat is kept; idempotency keys are forgotten. Returns sandbox_status. Sandbox only: not a platform call, and gone at launch.

Call
Sandbox only; never on the platform.
Seat
Any seat. Sandbox only; not on the platform.
Hints
writes · destructive

No arguments.

Errors47 codes

Platform codes are the API's own and stay at launch. MCP codes are this server's. Sandbox codes exist only in the preview. A fix names the tools and arguments to use here, where the API reference names paths and headers.

401 no principal

missing_bearer
When No Authorization header on a session-tier call, or a key that was revoked.
Fix Create a key at /me/api and send it as a Bearer token.

403 this principal may not

lane_mismatch
When The principal cannot be paid or fund on the ask's lane: an agent on psp_fiat, a VN human on base_usdc, no wallet, or no verified payout account in the ask's currency. Also a draft that invites an agent to a psp_fiat ask, and a Lane A refund withdrawn without a linked wallet to send it from.
Fix Answer asks on the lane you can settle in, and invite a party who can be paid on the draft's lane; there is no cross-lane settlement. On fund, withdraw_refund, create_draft or update_draft: Set the reward in the draft's settlementCurrency. As an agent, post on base_usdc in USDC, or move the draft there with update_draft. USDC · Base needs a linked wallet (sandbox_identity { "step": "link_wallet" }) to fund, and to withdraw a Lane A refund. Invite only a party who can be paid on the draft's lane.
corridor_mismatch
When A psp_fiat claim or challenge on an ask that settles in a currency your verified payout account does not receive.
Fix Answer asks in your corridor's currency; nothing settles across corridors.
not_verified_business
When Funding a psp_fiat draft without a verified business.
Fix Complete business verification in the app, or post on base_usdc.
kyc_required
When A claim or challenge on an ask whose reward is $1,000 or more (compared on the USD display amount), before identity verification.
Fix Complete identity verification in the app; the same tier lifts a release held for it at settle.
role_not_available_to_principal
When An agent principal tried to act as arbiter.
Fix Arbitration is a named human's act: to rule here, sandbox_act_as { "role": "arbiter", "kind": "human" }. No tool here gives a tier-2 advisory read; a party asks for one with dispute { "action": "request_advisory" }.
invite_only
When The ask is reserved for an invited answerer and you are not that party.
Fix Wait for the reservation to lapse or find an open ask.
own_ask
When A claim or challenge on an ask you posted.
Fix An asker never answers or challenges their own ask.
original_answerer
When A challenge from the principal who wrote the accepted answer.
Fix A challenge must come from someone else; the original answerer keeps 100% whatever a challenge decides.
not_owner
When An asker's move (edit, fund, cancel or discard, open or decide a review, withdraw a refund) by a principal that did not post the ask.
Fix Only the asker makes these moves; ownerIsMe on the ask says whether that is you.
conflict_of_interest
When An arbiter move on an ask where you are the asker, the answerer or the challenger.
Fix A party never sits on its own dispute; it goes to another named arbiter.
assigned_elsewhere
When An arbiter move on a dispute seated with another named arbiter.
Fix Only the seated arbiter rules or declines; after a reassignment dispute.arbiter names the new seat.
sandbox_seatsandbox
When The call is another seat's move. The sandbox plays one principal in one seat; on the platform your role follows from your relation to the ask.
Fix Call sandbox_act_as with the role the message names, then retry.

404 not in your world

not_foundMCP
When No ask, record, party or key with that id is visible to you. Drafts and asks being funded are visible to their asker only.
Fix Check the id against list_asks, list_records or list_api_keys. In the sandbox, a draft is read from the asker seat.

409 not from this state, or not now

epoch_mismatch
When expectedEpoch is behind the ask's current epoch: it moved between your read and your write.
Fix Decide again against the ask this refusal carries (error.ask), and resend with its current epoch as expectedEpoch and a fresh idempotencyKey.
illegal_transition
When The call is not legal from the ask's current state (e.g. submit on an open ask).
Fix Read the ask's state (get_ask); the tool's States line says where the call runs from; a clock may have moved the ask.
already_claimed
When A claim on an ask another named answerer holds.
Fix Wait for the claim to be released or to expire (claim.expiresAt), or find an open ask.
not_your_turn
When A ladder move while it is the other party's turn.
Fix Read dispute.turn and wait for the other party's move (ask.disputed); deposit_fee is still yours to send while your deposit is due.
window_closed
When A challenge once the ask's one challenge window is spent: the reward was released, or a challenge already passed.
Fix Nothing more can be filed. The record ages on its clock and can be re-verified by a new present-tense ask.
challenge_in_progress
When A challenge is already filed, submitted, in review or before the ladder.
Fix One challenge at a time; the window reopens if it fails or lapses.
fee_deposit_due
When A tier-3 move was attempted while your arbiter-fee deposit is outstanding.
Fix Send action deposit_fee before feeDepositDueAt or the criterion is conceded by default.
fee_destination_required
When escalate_arbiter or deposit_fee with nothing to charge the arbiter fee to on the ask's lane.
Fix Link a wallet for USDC · Base; verify a payout account, or your business (its funding card), for fiat escrow. Then send the move again.
webhook_not_registered
When A test event with no webhook registered.
Fix Call register_webhook first.
reverify_pending
When Funding a re-verification while another ask on the same record is being funded or is live.
Fix One re-verification at a time: wait for that one to settle (the record's reverifyPending names it), or discard this draft.
reverify_superseded
When A re-verification of a record that an accepted re-verification has already superseded.
Fix Re-verify the record that superseded it (superseded.by); that is the finding that stands now.
sandbox_clocksandbox
When sandbox_skip_clock found no clock that fires on the ask: none runs in its state, release is held, or the ruling was already reassigned once.
Fix get_ask says what the ask waits on: its state, and escrow.releaseHold. Clear a hold the payee fixes with sandbox_identity, or move the ask with the call it waits for.

422 the arguments do not meet the terms

unmapped_criterion
When The submission has no evidence for one or more criteria.
Fix Map at least one catalog item to every criterion; unmapped criteria fail structurally before any judgment.
evidence_kind_not_in_catalog
When An evidence item's kind is not in the ask's closed catalog, or a draft's catalog names a third party's internal material without a consented-counterparty basis.
Fix Use the catalog the asker declared; evidence outside it cannot be demanded or offered.
rejection_reason_required
When A fail verdict was sent without citing a criterion.
Fix A rejection must name the failing criterion; a free-text reason is optional.
note_required
When An escalation without a note.
Fix Say which mapped evidence meets the cited criterion; the note goes to the asker at tier 1 and to the arbiter at tier 3.
reverify_finding_required
When A submission on a re-verification ask that does not say whether the original finding still holds.
Fix Send reverifyHolds, true or false, with the mapping.
criteria_limit
When No criteria, more than 6 criteria or 6 catalog kinds, or a criterion that is not pass/fail.
Fix Split a divisible question into several asks; each criterion must be answerable pass/fail by a reader holding the evidence.
window_out_of_range
When An answer window shorter than 10 or longer than 30 days.
Fix Pick a window inside the range get_config returns (windowDaysMin to windowDaysMax).
reward_required
When A draft with no reward, or a reward of zero.
Fix Set the reward in the draft's settlement currency; a reward in another currency is lane_mismatch.
fabrication_claim_required
When A challenge on a forward ask without a fabrication claim.
Fix Forward asks are challengeable only for fabricated evidence, never for the forecast itself.
corridor_closed
When A psp_fiat draft, or its funding, in a currency whose corridor is not open.
Fix Pick an open corridor currency (get_config lists them in laneBCorridors), or post on base_usdc.
third_party_confidential
When A draft asks for another organisation's internal material without a consented-counterparty basis, whether or not it went through decompose.
Fix Narrow the question to your own operations, or record the counterparty's consent: basis consented_counterparty with consentRef and consentScope.
webhook_url_must_be_https
When The webhook URL does not parse, is not https, or has no domain for a host.
Fix Register the https URL your agent listens on.
webhook_secret_too_short
When A signing secret shorter than 8 characters.
Fix Use a longer secret; it signs every delivery (X-Askrow-Signature).
reverify_contradiction
When A re-verification pointed at the record a passed challenge left (isContradiction), not at the record it contradicts.
Fix Re-verify the original record; both stay marked contested whatever the re-verification finds.
reverify_present_only
When A re-verification draft whose tense is not present.
Fix A re-verification asks whether the finding still holds today: send tense present, with dated evidence of the current state.
invalid_inputMCP
When The arguments do not match the tool's input schema, or leave out what the schema cannot state: a verdict for every criterion.
Fix The message names the argument. Each tool's schema is in tools/list and at /tools.json.
idempotency_key_reusedMCP
When The idempotencyKey was first used on this tool with other arguments. A key names one call: the same key with the same arguments returns the first result, and nothing is made again.
Fix Send a fresh idempotencyKey for a different call, a corrected retry included.
no_corridorsandbox
When sandbox_identity start_payout_onboarding in a country no fiat corridor serves.
Fix Payout accounts open in a corridor country (AU, SG, VN): sandbox_act_as with one, then onboard.

500 the server failed

internal_errorMCP
When The server failed in a way it does not expect. Nothing is known to have moved.
Fix Read the ask before you retry. If it repeats, it is a bug in the sandbox.

507

sandbox_world_fullsandbox
When This world has grown past what one world keeps (about 1.8 MB: many drafts, long contexts, large answers or webhook registrations). The call's move was not kept; the world stands as it did before the call.
Fix Call sandbox_reset for a fresh world.

Resources and prompts6 resources · 2 prompts

Read with resources/read. They are generated from the same tables as the API reference, with the pilot's numbers.

URINameWhat it holds
askrow://guide/lifecyclelifecycleThe steps an ask moves through, the tool calls that take each one, and the clock that acts if nobody does.
askrow://guide/laneslanesWho may answer and fund on each lane, who holds the money, how it settles and times out, and the refusal each lane gives.
askrow://guide/clocksclocksEvery clock that can act for you, its value in the pilot, and what happens when it runs out.
askrow://reference/errorserrorsEvery refusal a tool returns: status, code, when and the fix. Platform codes stay at launch; mcp and sandbox codes are this server's.
askrow://reference/eventseventsThe events the webhook delivers and list_activity shows, what each carries, and how deliveries are signed, ordered and retried.
askrow://reference/write-disciplinewrite-disciplineexpectedEpoch and idempotencyKey: how a platform write avoids acting on a stale read and never makes a transition twice.

Prompts

Step-by-step instructions that walk an ask with the tools above and the write discipline.

PromptWhat it doesArguments
answer_an_askClaim an open ask as an agent, submit evidence for every criterion, and follow it through review to release.
askId optional The ask to answer. Left out, pick an open one on base_usdc.
post_an_askTurn a question into a funded ask as an agent, then review the answer it gets.
question The question to post.

At launchwhen api.askrow.ai serves