Decide: execute a plan
POST /api/decide/executeRun a decision's plan (decisionId from POST /api/decide), or a free plan sketch (steps), through Agent402: first-party steps run directly, third-party steps are bought from the seller and resold to you at Agent402's price (paid with a wallet on Base; prepaid credits and cards do not pay this route). Send POST /api/decide/execute with no required fields (6 optional) and pay quoted per request from $0.001 over x402 with USDC on Base or MPP. It returns a JSON object with runId, decisionId, status, steps, budgetUsd and 5 more.
Priced at the plan's budget (or your maxBudgetUsd, whichever you set) less a valid execution credit; spend stops at that budget, fallbacks are tried in order, and any unspent amount comes back as a credit. A run where no step succeeds is not charged on x402. Reusing a saved plan: send its decisionId with replan: true and the saved task is planned again on current prices and reliability before the run, for the POST /api/decide price at that decision's depth added to the quote; the answer's replanned field gives the new decisionId and each step whose tool, seller or price changed (or unchanged: true), and a re-plan that cannot run falls back to the saved plan with its price returned as credit. Also runs a free plan sketch: pass the sketch's tool slugs as steps (no decisionId) with params for step 1, and each later step takes its one required input from the step before, at list price. Takes up to 3 minutes to answer: send the paid call with "Prefer: respond-async" to get a job link at once and collect the answer from it (payment still settles only on a delivered result), or with "Prefer: wait=180" and keep the connection open for at least 210 seconds, because a client that disconnects first loses the answer. A paid call with neither header is answered 400 before any payment is taken.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
decisionId | string | no | From POST /api/decide (or pass steps instead) |
steps | array of string | no | Instead of decisionId: the tool slugs of a free plan sketch (from /api/find or /api/route), 2 to 5, in order. Pass params for step 1; a later step takes its one required input from the step before. |
creditToken | string | no | executionCredit.token from that decision (optional) |
maxBudgetUsd | number | no | Spend ceiling for the run (default: the plan's estimate via Agent402) |
params | object | no | Per-step params overriding the plan's exampleParams, keyed by step number |
replan | boolean | no | With decisionId: plan the saved task again on current prices and reliability, then run the new plan. Adds the plan price for that decision's depth to the quote; the answer's replanned field lists what changed. Default false. |
Example request
curl -i -X POST https://agent402.tools/api/decide/execute \
-H "Content-Type: application/json" \
-d '{"steps":["ens-resolve","wallet-balance"],"params":{"1":{"name":"vitalik.eth"}}}'Without payment this returns HTTP 402 Payment Required with the exact price for decide-execute; any x402 v2 or MPP client pays it and retries.
Example response
{
"runId": "run_…",
"decisionId": "dec_…",
"status": "complete",
"steps": [
{
"step": 1,
"status": "ok",
"tool": {
"slug": "search",
"seller": "agent402",
"firstParty": true
},
"costUsd": 0.02,
"result": {}
}
],
"budgetUsd": 0.02,
"spentUsd": 0.02,
"paidUsd": 0.001,
"creditAppliedUsd": 0.02,
"routingFeePct": 5,
"leftoverCredit": null
}| Field | Type | Always present | In the example |
|---|---|---|---|
runId | string | yes | run_… |
decisionId | string | yes | dec_… |
status | string | yes | complete |
steps | array of objects | yes | 1 item in the example |
budgetUsd | number | yes | 0.02 |
spentUsd | number | yes | 0.02 |
paidUsd | number | yes | 0.001 |
creditAppliedUsd | number | yes | 0.02 |
routingFeePct | number | yes | 5 |
leftoverCredit | null | no | null |
From an MCP client
catalog.call {
"slug": "decide-execute",
"params": {
"steps": [
"ens-resolve",
"wallet-balance"
],
"params": {
"1": {
"name": "vitalik.eth"
}
}
}
}The hosted connector at https://agent402.tools/mcp needs a payment for decide-execute; the stdio package pays it from a wallet or from an AGENT402_CREDITS_KEY issued earlier. Local install: npx -y agent402-mcp@0.13.32.
Errors and behavior
- Every field is optional. An input the tool rejects returns an HTTP 4xx whose body carries
error,tool,expected,requiredandexample. - A paid call that ends in any status of 400 or above is not charged over x402 or MPP: settlement runs after the tool and only on a successful response.
- Wallet-only: this tool runs a model, so it has no proof-of-work tier. It buys from an outside seller with our wallet, so it is paid with a wallet; prepaid credits and cards do not pay it.
- Model-backed: the answer is generated by a model, so the same input can produce a different result.
- Long-running: payment settles after the work finishes, so x402 is offered on EVM chains only and MPP on Base or Celo; Tempo is not offered.
- Takes up to 180 seconds. Send the paid call with
Prefer: respond-asyncto get202and a job link at once, then pollGET /api/jobs/{id}for its stage, progress and ETA until it has the answer; payment still settles only when the answer is ready. To wait on the connection instead, sendPrefer: wait=180and keep it open that long. A paid call with neither header is answered400before any payment is taken. - Priced per request: the 402 quotes this body, between $0.001 and $3.
- A
GETorHEADto /api/decide/execute returns the same 402 quote, so the price can be read without a body. - An
Idempotency-Keyheader makes a retried paid call replay the first 200 instead of charging again (an answer larger than 1 MB is not replayed).
Paid call (JavaScript agent)
import { wrapFetchWithPayment } from "@x402/fetch";
import { x402Client } from "@x402/core/client";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
const client = new x402Client();
client.setSpendControls?.({ maxAmountPerPayment: "$3.00" }); // refuse any quote above this tool's price
registerExactEvmScheme(client, { signer: privateKeyToAccount(KEY) });
const payFetch = wrapFetchWithPayment(fetch, client);
const res = await payFetch("https://agent402.tools/api/decide/execute", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"steps": [
"ens-resolve",
"wallet-balance"
],
"params": {
"1": {
"name": "vitalik.eth"
}
}
}),
});Related tools
Decide: tool plan for a task
Describe a job and get a call-ready plan: which tools, across this catalog and outside x402 sellers with a recently.
Route and execute
Describe a task (or name a slug) and the Smart Order Router resolves the best-matching tool and RUNS it in the same call.
Route and execute (max tier)
Describe a task (or name a slug) and the Smart Order Router resolves the best-matching tool and RUNS it in the same call.
Route and execute (plus tier)
Describe a task (or name a slug) and the Smart Order Router resolves the best-matching tool and RUNS it in the same call.
Route and execute (pro tier)
Describe a task (or name a slug) and the Smart Order Router resolves the best-matching tool and RUNS it in the same call.
Attest a settled call on Base
Write an on-chain attestation (Ethereum Attestation Service on Base) that binds a call you paid for to the bytes you.