{"version":1,"resources":["https://agent-exec.448c.org/execute","https://agent-exec.448c.org/listings/promote","https://agent-exec.448c.org/storage","https://agent-exec.448c.org/claim","https://agent-exec.448c.org/attest","https://agent-exec.448c.org/handoff","https://agent-exec.448c.org/deadman","https://agent-exec.448c.org/drift","https://agent-exec.448c.org/watch","https://agent-exec.448c.org/check/address","https://agent-exec.448c.org/check/url","https://agent-exec.448c.org/pay","https://agent-exec.448c.org/inbox","https://agent-exec.448c.org/dns","https://agent-exec.448c.org/relay","https://agent-exec.448c.org/rpc","https://agent-exec.448c.org/placement"],"accepts":[{"scheme":"exact","network":"base","maxAmountRequired":"1000","resource":"https://agent-exec.448c.org/execute","description":"POST /execute -- Execute python3/node code in a network-less sandbox; stdout, stderr, exit code. No account, pay over x402; one free run per wallet a day: POST /execute/free. Tier: default ($0.0010).","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"runtime":"python3","source":"print(1)"},"exampleFillsOmittedFields":true,"bodyFields":{"runtime":{"type":"string","required":true,"enum":["python3","node"],"description":"Must be one of the allowlisted runtimes enumerated here -- the free way to learn the set. An unsupported value is refused only AFTER a payment attempt, as RUNTIME_UNSUPPORTED, not before. Imports: python3 has the standard library plus numpy 2.2 and scipy 1.15; node has its standard library only. Nothing else is installed and the sandbox has no network, so any other `import` / `require` fails with a module-not-found error at run time, after payment. Send any other dependency as `files`."},"source":{"type":"string","required":true,"description":"Program source, written to the runtime's entry file. Imports: python3 has the standard library plus numpy 2.2 and scipy 1.15; node has its standard library only. Nothing else is installed and the sandbox has no network, so any other `import` / `require` fails with a module-not-found error at run time, after payment. Send any other dependency as `files`."},"stdin":{"type":"string","required":false,"description":"Written to the payload's stdin, then stdin is closed."},"files":{"type":"object","required":false,"description":"Extra files seeded alongside the entry file, as relative-path -> content."},"limits":{"type":"object","required":false,"description":"Per-request resource budget. Every field is optional; an omitted field takes its documented default."}}},"output":{"outcome":"completed","stdout":"1\n","stderr":"","exitCode":0,"durationMs":42,"truncated":{"stdout":false,"stderr":false},"error":null,"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"1000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"},"receipt":{"requestDigest":"0000000000000000000000000000000000000000000000000000000000000000","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"1000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","reference":"0x0000000000000000000000000000000000000000000000000000000000000000"},"priceUsd":0.001,"price":"$0.0010","tier":"default","limits":{"timeoutMs":5000,"maxMemoryBytes":2147483648,"maxOutputBytes":1048576,"workDirBytes":67108864},"usage":{"outcome":"completed","durationMs":42,"exitCode":0,"truncated":{"stdout":false,"stderr":false}},"status":{"code":null,"category":"success","billable":true},"outputDigest":"0000000000000000000000000000000000000000000000000000000000000000"}}},"extensions":{"bazaar":{"info":{"input":{"example":{"runtime":"python3","source":"print(1)"}},"output":{"example":{"outcome":"completed","stdout":"1\n","stderr":"","exitCode":0,"durationMs":42,"truncated":{"stdout":false,"stderr":false},"error":null,"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"1000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"},"receipt":{"requestDigest":"0000000000000000000000000000000000000000000000000000000000000000","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"1000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","reference":"0x0000000000000000000000000000000000000000000000000000000000000000"},"priceUsd":0.001,"price":"$0.0010","tier":"default","limits":{"timeoutMs":5000,"maxMemoryBytes":2147483648,"maxOutputBytes":1048576,"workDirBytes":67108864},"usage":{"outcome":"completed","durationMs":42,"exitCode":0,"truncated":{"stdout":false,"stderr":false}},"status":{"code":null,"category":"success","billable":true},"outputDigest":"0000000000000000000000000000000000000000000000000000000000000000"}}}}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"66700","resource":"https://agent-exec.448c.org/listings/promote","description":"POST /listings/promote -- Paid placement in the agent-exec directory: promoted listings outrank free ones while paid ($0.0667/day, $0.3333/week, $1/month) and demote once payment lapses. This entry buys day ($0.0667). Not a review -- payment doesn't verify or endorse a listing. No account needed; pay over x402.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"id":"your-listing-id","duration":"week"},"bodyFields":{"id":{"type":"string","required":true,"description":"The directory listing id to promote. If you have none, POST /listings first -- it mints one free, charges nothing, and returns its id. You must pay from the wallet that owns it."},"duration":{"type":"string","required":true,"enum":["day","week","month"],"description":"One of: day, week, month."}}},"output":{"listing":{"id":"example-listing","tier":"paid","paidUntil":1700000000000},"promotion":{"duration":"week","durationMs":604800000,"paidUntil":1700000000000,"priceUsd":0.3333},"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"333300","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"5100","resource":"https://agent-exec.448c.org/storage","description":"POST /storage -- Store up to 65536 bytes for 86400 seconds (small plan). Readable only by the paying wallet.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"binary","exampleQuery":{"plan":"small","label":"planner-state"},"queryParams":{"plan":{"type":"string","required":true,"enum":["small","medium","large","year"],"description":"One of: small, medium, large, year."},"label":{"type":"string","required":false,"description":"Optional, at most 128 characters, no control characters. A name of your own choosing for this object, stored verbatim and returned on every GET /storage/list row, so a later run that no longer remembers the id can still tell which object is which without downloading them."}}},"output":{"id":"00000000-0000-4000-8000-000000000000","expiresAt":1700000000000,"plan":"small","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"5100","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"5200","resource":"https://agent-exec.448c.org/claim","description":"POST /claim -- Atomically win a caller-named key for 3600 seconds (hour plan), or learn who already holds it. Scoped to your own paying wallet -- coordinates one wallet's own fleet, not mutually distrusting strangers.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"key":"deploy-lock","holder":"worker-3","plan":"hour"},"bodyFields":{"key":{"type":"string","required":true,"description":"1..256 UTF-8 bytes, no '/' character -- the name you want to hold, scoped to your own wallet."},"holder":{"type":"string","required":true,"description":"1..256 UTF-8 bytes -- an id identifying which of your processes is claiming it."},"plan":{"type":"string","required":true,"enum":["hour","day","week"],"description":"One of: hour, day, week."}}},"output":{"outcome":"acquired","plan":"hour","claim":{"key":"deploy-lock","holder":"worker-3","acquiredAt":1700000000000,"expiresAt":1700003600000},"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"5200","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"8000","resource":"https://agent-exec.448c.org/attest","description":"POST /attest -- Fetch a URL from our vantage point and return a signed, timestamped attestation of what we saw (hash, status, headers) -- never the body. Retrievable afterwards for free at /attest/{attestation_id}.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"url":"https://example.com/terms"},"exampleFillsOmittedFields":true,"bodyFields":{"url":{"type":"string","required":true,"description":"An absolute http:// or https:// URL, at most 2048 UTF-8 bytes. Fetched from OUR vantage point; the body is never returned to you."}}},"output":{"attestation_id":"018f5b2e-0000-7000-8000-000000000000","url":"https://example.com/terms","observed_at":"2026-09-02T00:00:00.000Z","fetch_ok":true,"fetch_code":"ATTEST_FETCH_OK","http_status":200,"body_sha256":"0000000000000000000000000000000000000000000000000000000000000000","body_bytes":1234,"body_truncated":false,"content_type":"text/html; charset=utf-8","final_url_after_redirects":"https://example.com/terms","redirects":0,"detail":null,"signature":"0x00","signer_address":"0x0000000000000000000000000000000000dEaD","ots_digest_sha256":"0000000000000000000000000000000000000000000000000000000000000000","ots_proof_base64":"AE9wZW5UaW1lc3RhbXBzAABQcm9vZgC/ieLohOiSlAE...","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"8000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"5300","resource":"https://agent-exec.448c.org/handoff","description":"POST /handoff -- Deposit a typed briefing for your successor process (what's done and how it was verified, what's not done, what was in flight, what to pick up first). Returns an id; fetch it back for free at /handoff/{id}, no identity required.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"done":[{"text":"Rotated the signing key","confidence":"measured","evidence":"GET /health returned the new key id at 2026-11-02T14:00:00Z"}],"notDone":[{"text":"Backfill the 2026-10 ledger","confidence":"unverified"}],"inFlight":[{"text":"Deploy of release v42 is mid-rollout","confidence":"unverified"}],"pickUpFirst":"Finish the v42 rollout, then backfill the 2026-10 ledger."},"bodyFields":{"done":{"type":"array","required":true,"description":"Claims that are DONE. Each must be { text, confidence: \"measured\", evidence } -- evidence describing how it was verified is mandatory."},"notDone":{"type":"array","required":true,"description":"Claims that are NOT done. { text, confidence, evidence }, confidence may be \"measured\" or \"unverified\"."},"inFlight":{"type":"array","required":true,"description":"Claims that were in flight at the cut. Same claim shape as notDone."},"pickUpFirst":{"type":"string","required":true,"description":"What the successor should do first."}}},"output":{"id":"018f5b2e-0000-7000-8000-000000000000","expiresAt":1700000000000,"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"5300","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"5400","resource":"https://agent-exec.448c.org/deadman","description":"POST /deadman -- Register an irreversible-action intent with a lease and a verification probe. Confirm before expiry at POST /deadman/{id}/confirm, or the probe runs on your behalf and the verdict (confirmed-by-probe / refuted-by-probe / unresolved) is published at GET /deadman/{id}, free, forever.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"description":"Deploying release v42 to prod","leaseSeconds":3600,"probe":{"url":"https://example.com/health","expectedStatus":200}},"bodyFields":{"description":{"type":"string","required":true,"description":"What you are about to do."},"leaseSeconds":{"type":"number","required":true,"description":"How long before an unconfirmed entry's probe runs (1-604800)."},"probe":{"type":"object","required":true,"description":"{ url, expectedBodyContains?, expectedStatus? } -- at least one predicate is required."}}},"output":{"id":"018f5b2e-0000-7000-8000-000000000000","status":"pending","description":"Deploying release v42 to prod","probe":{"url":"https://example.com/health","expectedStatus":200},"createdAt":1700000000000,"leaseExpiresAt":1700003600000,"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"5400","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"6100","resource":"https://agent-exec.448c.org/drift","description":"POST /drift -- Re-fetch a venue endpoint we already snapshot and diff it against our archived baseline: field_added/removed, weight re-basing, enum growth, fleet-wide nulling. Returns BOTH raw bodies so you can verify the diff yourself. Body is JSON: {\"venue\": \"...\"} -- venue is one of the endpoints we already snapshot. Equivalent to POST /drift/{venue}, where GET /drift/{venue} is free and reports whether a baseline exists.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"venue":"percall"},"bodyFields":{"venue":{"type":"string","required":true,"enum":["agentry","clearedindex","percall","verantis","x402-list"],"pattern":"^[a-zA-Z0-9_-]+$","description":"One of the endpoints we already snapshot."}}},"output":{"venue":"percall","t1":{"fetched_at":"2026-09-01T00:00:00.000Z","url":"https://example.com/api/score","http_status":200,"content_type":"application/json","body_bytes":1234,"body_sha256":"0000000000000000000000000000000000000000000000000000000000000000","body":"{\"...\":\"...\"}"},"t2":{"fetched_at":"2026-09-04T00:00:00.000Z","url":"https://example.com/api/score","http_status":200,"content_type":"application/json","body_bytes":1256,"body_sha256":"1111111111111111111111111111111111111111111111111111111111111111","body":"{\"...\":\"...\"}","fetch_ok":true,"fetch_code":"DRIFT_FETCH_OK","detail":null,"body_truncated":false},"events":[{"type":"weights_rebased","path":"$.checks[].weight","field":"weight","before":{"sum":100,"min":0,"max":20,"count":10},"after":{"sum":122,"min":0,"max":20,"count":20}}],"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"6100","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"5800","resource":"https://agent-exec.448c.org/watch","description":"POST /watch -- Register a durable poll of a URL, priced by intervalSeconds x ttlSeconds. Read the current verdict, free, forever, at GET /watch/{id} -- lastPolledAt/nextPollDueAt/overdue tell you if the sweeper has fallen behind.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"url":"https://example.com/health","intervalSeconds":300,"ttlSeconds":86400,"predicate":{"type":"statusChanged"}},"bodyFields":{"url":{"type":"string","required":true,"description":"Absolute http(s) URL to poll."},"intervalSeconds":{"type":"number","required":true,"description":"Seconds between polls (60-86400)."},"ttlSeconds":{"type":"number","required":true,"description":"Stop polling after this many seconds (60-604800, at least intervalSeconds)."},"predicate":{"type":"object","required":true,"description":"One of {type:\"statusChanged\"} / {type:\"statusEquals\",status} / {type:\"bodyContains\",value} / {type:\"bodyNotContains\",value} / {type:\"jsonPathEquals\",path,value} / {type:\"jsonPathNotEquals\",path,value} / {type:\"changedFromNow\",path?}."},"storageKey":{"type":"string","required":false,"description":"Deliver a matched observation into /storage under this key (as its label), at most 128 characters."}}},"output":{"id":"018f5b2e-0000-7000-8000-000000000000","status":"active","url":"https://example.com/health","intervalSeconds":300,"ttlSeconds":3600,"predicate":{"type":"statusEquals","status":200},"createdAt":1700000000000,"ttlExpiresAt":1700003600000,"lastPolledAt":null,"nextPollDueAt":1700000000000,"overdue":false,"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"5800","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"20000","resource":"https://agent-exec.448c.org/check/address","description":"POST /check/address -- Check an EVM address against public risk feeds (OFAC, community darklists, on-chain age) and get back a verdict, score and reasons.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"address":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0"},"bodyFields":{"address":{"type":"string","required":true,"description":"An EVM (0x...) address to check."},"chain":{"type":"string","required":false,"description":"\"base\" or \"ethereum\" -- default \"base\"."}}},"output":{"verdict":"safe","score":0,"reasons":["no risk signals found in the checked sources"],"sources":["ofac","ethereum-lists/darklist"],"disclaimer":"Best-effort signal, not a guarantee; not financial advice. Aggregates public risk feeds.","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"20000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"20000","resource":"https://agent-exec.448c.org/check/url","description":"POST /check/url -- Check a URL against public risk feeds (phishing lists, domain age, lexical signals) and get back a verdict, score and reasons.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"url":"https://agent-exec.448c.org"},"exampleFillsOmittedFields":true,"bodyFields":{"url":{"type":"string","required":true,"description":"An http(s) URL or bare domain to check."}}},"output":{"verdict":"safe","score":0,"reasons":["no risk signals found in the checked sources"],"sources":["phishing-list","rdap-domain-age"],"disclaimer":"Best-effort signal, not a guarantee; not financial advice. Aggregates public risk feeds.","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"20000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"20000","resource":"https://agent-exec.448c.org/pay","description":"POST /pay -- Deliver an x402 authorization YOU signed to a seller exactly once, then check the chain for what became of it, and get back a signed-in-time receipt of what the seller answered. Retrievable afterwards for free at /pay/{id}.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"sellerUrl":"https://seller.example/resource","method":"POST","headers":{"content-type":"application/json"},"body":"{\"ask\":\"one widget\"}","authorization":{"headerName":"X-PAYMENT","header":"eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZSIsInBheWxvYWQiOnsic2lnbmF0dXJlIjoiMHhhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYjFiIiwiYXV0aG9yaXphdGlvbiI6eyJmcm9tIjoiMHgyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyIiwidG8iOiIweDMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMiLCJ2YWx1ZSI6IjEwMDAiLCJ2YWxpZEFmdGVyIjoiMCIsInZhbGlkQmVmb3JlIjoiNDEwMjQ0NDgwMCIsIm5vbmNlIjoiMHgxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExIn19fQ==","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},"bodyFields":{"sellerUrl":{"type":"string","required":true,"description":"The seller endpoint to deliver the authorization to, an absolute http:// or https:// URL of at most 2048 UTF-8 bytes."},"method":{"type":"string","required":true,"description":"The HTTP method to call the seller with: one of GET, POST, PUT, PATCH, DELETE."},"headers":{"type":"object","required":false,"description":"Optional request headers for the seller, at most 20 string values."},"body":{"type":"string","required":false,"description":"Optional request body for the seller, at most 65536 UTF-8 bytes."},"authorization":{"type":"object","required":true,"description":"The x402 authorization YOU already signed for the seller: {headerName: \"X-PAYMENT\"|\"PAYMENT-SIGNATURE\", header: base64 PaymentPayload, asset: the token contract it was signed against}. We never sign it."}}},"output":{"id":"018f5b2e-0000-7000-8000-000000000000","wallet":"0x0000000000000000000000000000000000dEaD","seller_url":"https://seller.example/resource","seller_method":"POST","seller_status":200,"seller_reason":null,"seller_body":"{\"ok\":true}","seller_body_bytes":11,"seller_body_truncated":false,"delivered":true,"requested_at":"2026-09-02T00:00:00.000Z","responded_at":"2026-09-02T00:00:01.000Z","verdict":"settled","verdict_tx":null,"verdict_checked_at":"2026-09-02T00:00:02.000Z","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"20000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"20000","resource":"https://agent-exec.448c.org/inbox","description":"POST /inbox -- Pay for a disposable, receive-only email address for 24 hours and read what arrives: GET /inbox/{id}/messages returns each mail as text with any verification codes and links extracted, free and owner-signed. Nothing is ever sent from it. Repeat the payment with {id} to extend. Problems or abuse: POST /feedback.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{},"bodyFields":{"id":{"type":"string","required":false,"description":"An inbox id this same wallet already owns: extends it 24 h from its current expiry instead of issuing a new address. Omit for a new address."}}},"output":{"id":"018f5b2e-0000-7000-8000-000000000000","address":"k3n8q2w7r1zx@example.com","owner":"0x0000000000000000000000000000000000dEaD","chain":"base","createdAt":"2026-09-02T00:00:00.000Z","expiresAt":"2026-09-03T00:00:00.000Z","expired":false,"messageCount":0,"extended":false,"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"20000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"500000","resource":"https://agent-exec.448c.org/dns","description":"POST /dns -- Rent <label>.448c.net for a year and point it where you say: A, AAAA, CNAME and TXT records, so you can hold a TLS certificate and pass domain-trust checks without a registrar account. The paying wallet owns the name. Readable afterwards for free at /dns/{name}.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"label":"my-agent","records":[{"type":"A","value":"203.0.113.10","ttl":300}]},"bodyFields":{"label":{"type":"string","required":true,"description":"The label to rent under 448c.net: string matching ^[a-z0-9][a-z0-9-]{1,30}$, and not one of: www, mail, ns1, ns2, agent-exec, sentinel, admin, api, _acme-challenge."},"records":{"type":"array","required":true,"description":"1 to 10 records, each {type: A|AAAA|CNAME|TXT, value: string, ttl: 60-3600 seconds}."}}},"output":{"name":"example.448c.net","owner":"0x0000000000000000000000000000000000dEaD","expiresAt":1800000000000,"records":[{"type":"A","value":"203.0.113.10","ttl":300}],"plan":"year","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"500000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"20000","resource":"https://agent-exec.448c.org/relay","description":"POST /relay -- Send USDC from a wallet that holds no gas: you sign an EIP-3009 TransferWithAuthorization, we broadcast it on Base with our ETH. Flat fee, paid in USDC. A refused order costs nothing.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":300,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"from":"0x2222222222222222222222222222222222222222","to":"0x3333333333333333333333333333333333333333","value":"1000000","validAfter":"0","validBefore":"4102444800","nonce":"0x1111111111111111111111111111111111111111111111111111111111111111","signature":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb1b"},"bodyFields":{"from":{"type":"string","required":true,"description":"The USDC holder who signed. The signature must recover to exactly this address."},"to":{"type":"string","required":true,"description":"Recipient of the USDC. Must differ from `from`."},"value":{"type":"string","required":true,"description":"Atomic USDC (6 decimals), 1..100000000 ($100 ceiling)."},"validAfter":{"type":"string","required":true,"description":"Unix seconds; must already have passed."},"validBefore":{"type":"string","required":true,"description":"Unix seconds; at least 30s out, so the broadcast lands inside the window."},"nonce":{"type":"string","required":true,"description":"32 bytes of hex, unique per order -- USDC rejects a reused one."},"signature":{"type":"string","required":true,"description":"65-byte hex EIP-712 signature of TransferWithAuthorization over chainId 8453, verifyingContract 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913. The example's is intentionally invalid: a valid one published here would be spendable by anyone."}}},"output":{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x2222222222222222222222222222222222222222","to":"0x3333333333333333333333333333333333333333","value":"1000000","relayedAt":"2026-10-29T00:00:00.000Z","payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"20000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"2000","resource":"https://agent-exec.448c.org/rpc","description":"POST /rpc -- Accountless JSON-RPC: send one call plus a chain label (base, base-sepolia, ethereum, solana), pay per call in USDC, get the node's own answer back. No signup, no API key, no provider account. A refused call costs nothing.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":120,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"chain":"base","method":"eth_blockNumber","params":[],"id":1},"bodyFields":{"chain":{"type":"string","required":true,"description":"Which chain to call: base, base-sepolia, ethereum, solana. You never name a URL -- we pick the endpoint."},"method":{"type":"string","required":true,"description":"A JSON-RPC method on this chain's allowlist (reads, fee queries, raw-transaction broadcast). EVM: eth_blockNumber, eth_call, eth_chainId, eth_estimateGas, eth_feeHistory, eth_gasPrice, eth_getBalance, eth_getBlockByHash, eth_getBlockByNumber, eth_getCode, eth_getLogs, eth_getStorageAt, eth_getTransactionByHash, eth_getTransactionCount, eth_getTransactionReceipt, eth_maxPriorityFeePerGas, eth_sendRawTransaction, net_version, web3_clientVersion. Solana: getAccountInfo, getBalance, getBlockHeight, getEpochInfo, getLatestBlockhash, getMinimumBalanceForRentExemption, getSignatureStatuses, getSlot, getTokenAccountBalance, getTokenAccountsByOwner, getTransaction, getVersion, sendTransaction, simulateTransaction."},"params":{"type":"array","required":false,"description":"The method's params, array or object, at most 8192 serialized bytes. Omitted means []. Not checked against the method -- the upstream answers a typed JSON-RPC error if they are wrong."},"id":{"type":"string","required":false,"description":"Your correlation id, a string of at most 64 chars or a safe integer. Echoed back on the response and never forwarded upstream."}}},"output":{"chain":"base","method":"eth_blockNumber","response":{"jsonrpc":"2.0","id":1,"result":"0x1c9c380"},"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"},{"scheme":"exact","network":"base","maxAmountRequired":"250000","resource":"https://agent-exec.448c.org/placement","description":"POST /placement -- Order a placement campaign for your service across every permissionless agent venue we know: each venue classified, submitted to every venue we hold a submitter for (17 of the 33 on-behalf venues today) and to each new one the hour its submitter lands while the order is open, and each entry proven in the catalogue by reading it back, weekly for 90 days. A venue we cannot yet submit to for you stays `queued` and is reported as owed, never as done. The paying wallet owns the order, readable owner-signed at /placement/{id}. Venues that need a human, or charge for an entry, are reported with the reason and never charged for.","mimeType":"application/json","payTo":"0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0","maxTimeoutSeconds":60,"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"name":"USD Coin","version":"2"},"outputSchema":{"input":{"type":"http","method":"POST","discoverable":true,"bodyType":"json","example":{"url":"https://your-service.example"},"bodyFields":{"url":{"type":"string","required":false,"description":"the absolute http(s) URL of YOUR service, at most 512 bytes -- the one a venue should list. Omit it to extend an order instead."},"id":{"type":"string","required":false,"description":"the id of an order you already own, to extend it by another 90 days of rechecks. Exactly one of url or id."}}},"output":{"outcome":"created","id":"1b4e28ba-2fa1-11d2-883f-0016d3cca427","owner":"0x0000000000000000000000000000000000dEaD","url":"https://your-service.example","expiresAt":"2027-01-08T00:00:00.000Z","venues":[{"venue":2,"name":"example-registry","lane":"on-behalf","state":"queued","evidence":null,"checkedAt":null,"reason":null}],"payment":{"payer":"0x0000000000000000000000000000000000dEaD","amount":"250000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","transaction":"0x0000000000000000000000000000000000000000000000000000000000000000"}}},"method":"POST"}],"freeResources":["https://agent-exec.448c.org/quote","https://agent-exec.448c.org/listings","https://agent-exec.448c.org/storage/usage","https://agent-exec.448c.org/storage/list","https://agent-exec.448c.org/claim/free","https://agent-exec.448c.org/supported","https://agent-exec.448c.org/verify"],"ownershipProofs":["0xc8Fceb0F3611BE99c41586eA2B83F6A0911d2Ff0"],"description":"Accountless, pay-per-use code execution for software agents: submit source code, get stdout, stderr and exit code back from an isolated, network-less sandbox. No account, no API key -- possession of valid payment is sufficient.","instructions":"# agent-exec\n\n> Accountless, pay-per-use code execution for software agents: submit source code, get stdout, stderr and exit code back from an isolated, network-less sandbox. No account, no API key -- possession of valid payment is sufficient.\n\n## Paid endpoints (HTTP 402, USDC on base via x402 -- no account, no API key, no signup)\n\n- POST https://agent-exec.448c.org/execute -- run source code to completion in the sandbox. Runtimes: python3, node. From $0.0010 at default limits; larger limits cost more -- call POST /quote first for the exact price of a given limits object. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/listings/promote -- buy paid placement for a directory listing you own, priced by time: day $0.0667, week $0.3333, month $1.0000. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/storage -- Accountless, pay-per-use durable object storage for software agents: pay once for a byte cap and a retention window, then read your bytes back for free with a wallet signature. No account, no API key, no public URL -- possession of the paying wallet is sufficient. Retention can be extended before it lapses via a paid POST /storage/{id}/renew, keeping the same id. Plans: small $0.0051 (65536 bytes, 86400s), medium $0.0055 (262144 bytes, 604800s), large $0.0125 (1048576 bytes, 2592000s), year $0.1000 (1048576 bytes, 31536000s). (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/claim -- atomically win a caller-named key for your own paying wallet's fleet, or learn who already holds it. Accountless compare-and-set: pays once, either wins the key (`outcome: \"acquired\"`) or is told who holds it and until when (`outcome: \"held\"`, not an error). Plans: hour $0.0052 (3600s), day $0.0168 (86400s), week $0.0470 (604800s). See \"Coordinating with /claim\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/attest -- pay to have us fetch a URL from OUR vantage point and return a signed, timestamped attestation of what we saw (hash, status, headers) -- never the body. $0.0080 flat. Retrieve it back for free at GET /attest/{id} to cite it to a third party who never paid us. See \"Verifying an attestation\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/handoff -- pay to deposit a typed briefing for your successor process: what is DONE (every entry must carry evidence of how it was verified), what is NOT done, what was IN FLIGHT at the cut, and what to pick up FIRST. $0.0053 flat, retained 3 days. Returns an id; the successor reads it back free at GET /handoff/{id} with no identity, header or payment of any kind, so neither side needs an account with us. The \"done\" section structurally refuses an unverified claim. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/deadman -- pay to register an intent you are about to act on irreversibly, with a lease (1-604800s) and a verification probe (a GET request plus a predicate: expectedBodyContains and/or expectedStatus). $0.0054 flat. Confirm before the lease expires at POST /deadman/{id}/confirm (free); otherwise the probe runs on your behalf and the verdict -- confirmed-by-probe, refuted-by-probe, or unresolved (a first-class honest outcome, never guessed as refuted) -- is published with the probe's raw response at GET /deadman/{id}, free, forever, so you can re-run the probe yourself and check our answer. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/watch -- pay to have us poll a URL until a condition fires (status changed/equals, body contains/not, a JSON path equals/not, or changed since registration) or the TTL runs out. Priced by how often and how long: $0.0050 + (floor(ttlSeconds / intervalSeconds) + 1) * $0.0004 per poll; minimum $0.0058. Body: {url, intervalSeconds, ttlSeconds, predicate, storageKey?}. POST it unpaid for the exact price. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/drift -- pay to re-fetch a venue endpoint we already snapshot and diff it against our archived baseline: field_added, field_removed, weights_rebased, enum_extended, nulled_fleet_wide. Substitute the venue as a path segment: POST /drift/{venue}, e.g. /drift/percall -- the venue names one of the endpoints we already snapshot. $0.0061 flat. Returns BOTH the archived and the fresh raw body so you can verify the diff yourself rather than trusting ours. GET /drift/{venue} is free and reports whether a baseline exists, without spending the live re-fetch a POST costs. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/check/address -- pay to check an EVM (0x...) address against public risk feeds (OFAC, community darklists, on-chain age) and get back a verdict, score and reasons. Body: {address, chain?} (chain defaults to \"base\"). $0.0200 flat. Charged only on success -- if every risk feed is unreachable the request is refused for free rather than answered with an unsourced verdict. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/check/url -- pay to check a URL against public risk feeds (phishing lists, domain age, lexical signals) and get back a verdict, score and reasons. Body: {url}. $0.0200 flat. Same charged-only-on-success contract as POST /check/address. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/pay -- pay to have an x402 authorization YOU signed delivered to a seller exactly once, then read the chain for what actually became of it, and get back an immutable receipt of what the seller answered. Body: {sellerUrl, method, headers?, body?, authorization:{headerName, header, asset}}. $0.0200 flat. We never sign on your behalf: read the seller's own price card free at POST /pay/requirements, sign one of its accepts[] yourself, then send it here. A seller 402, 4xx, 5xx or refused connection is a delivered, billable answer -- what you buy is the truth about what the seller did with your authorization, not a guaranteed 200. The receipt is free to re-read, forever and unauthenticated, at GET /pay/{id}, so the seller who says they were never paid can fetch it themselves. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/inbox -- pay for a disposable email address on a domain we own, live for 24 h, to receive the verification mail a signup demands. $0.0200 flat; pay again with `{id}` to extend the same address from its current expiry, no cap. RECEIVE ONLY -- nothing is ever sent from it. Mail is read free and owner-signed at GET https://agent-exec.448c.org/inbox/{id}/messages (newest first, `?since=` to poll); the inbox itself at GET https://agent-exec.448c.org/inbox/{id}; release it early with DELETE https://agent-exec.448c.org/inbox/{id} (the local part is then never issued again). (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/inbox/free -- RETIRED, and deliberately still live: there is no free inbox tier. Any call here answers POST https://agent-exec.448c.org/inbox's own 402 price card, with accepts[0].resource naming POST https://agent-exec.448c.org/inbox -- never a 400 or a 404, so a liveness prober reads \"live, priced\". Pay at POST https://agent-exec.448c.org/inbox. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/dns -- rent <label>.448c.net for a year and point it where you say: A, AAAA, CNAME and TXT records, so you can hold a TLS certificate (DNS-01) and pass a domain-trust check without a registrar account. $0.5000 per 365 days. The paying wallet owns the name; POST https://agent-exec.448c.org/dns/{name}/renew at the same price EXTENDS from the current expiry rather than resetting it. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/placement -- order a placement campaign: submitted to the 17 of 33 on-behalf agent venues we can reach today and to each new one as its submitter lands, every permissionless venue classified for YOUR service, then verified per venue in the catalogue and rechecked for 90 days (every 7 days). Body: {url}, or {id} to extend an order you own. $0.2500 an order. We submit to the 17 of 33 on-behalf venues we hold a submitter for today, and to each new one the hour its submitter lands while the order is open; every other venue is classified, owned and rechecked, and stays queued -- work we owe you, never reported as done. WHAT IS SOLD IS THE SUBMISSION WORK AND THE EVIDENCE, NEVER A PLACEMENT: a venue needing a human is reported with that reason and never charged for, a venue with its own entry fee comes back unfunded for you to fund yourself, and we submit only what your own discovery documents already say. The paying wallet owns the order and is the only wallet that can read or delete it. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/rpc -- pay per call for one JSON-RPC call to base, base-sepolia, ethereum or solana with no account, no API key and no provider signup: you send {chain, method, params?, id?}, we pick the endpoint and absorb its IP rate limit, and you get the node's own answer back with YOUR id echoed. $0.0020 a call. Chain reads, fee queries and raw-transaction broadcast only; a refused call (unknown chain, method off the allowlist, batch, oversize params) is a free 400 before the paywall, and an upstream \"execution reverted\" is a delivered 200 -- it is what you paid to learn. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/relay -- pay to have a USDC transfer YOU signed broadcast with our ETH: the product for a Base wallet holding USDC and no gas. You send one EIP-3009 TransferWithAuthorization ({from, to, value, validAfter, validBefore, nonce, signature}); we pay the gas and return the txHash. $0.0200 an order, $100 max an order. We hold no key of yours. Every refusal (bad signature, closed window, value over the ceiling, self-send) is a free 400 before the paywall -- we never charge for a transaction we did not send; and a box with no funded gas key answers a free 503 rather than taking your fee. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n\n## Success is not always 200\n\nA caller asserting `status === 200` mislabels a paid, delivered call as a failure (reported by a buyer of POST /attest on 2026-10-10, which is why this is now written down). These creating POSTs answer **201** on success: /feedback, /storage, /attest, /handoff, /deadman, /watch, /inbox, /dns, /dns/free. POST /listings, /claim, /claim/free and /placement answer either -- 201 when the row, key or order was created, 200 when it already existed (for /placement, when the order was EXTENDED instead), which is also a success and carries its own `outcome`. Everything else answers 200. Branch on 2xx and on the body, never on 200 alone; the per-route success status is also declared in /openapi.json.\n\n## Free endpoints (no payment required)\n\n- POST https://agent-exec.448c.org/execute/free -- free: 1 real sandboxed run per wallet per UTC day (2000ms, 32768 bytes of output), no payment: body {source, wallet, signature} and an optional {runtime} (omit it, or send anything we do not run, and the free route runs python3 and tells you so in the 200 -- only the paid POST /execute insists you name one), identity by an EIP-191 signature alone. Real stdout from the same sandbox POST /execute charges for -- call it before you decide to pay. Any refusal republishes the exact message to sign. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/dns/free -- free: one name per wallet, identity by the X-Signature header alone, so you can hold a working hostname before paying for a year of one. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/placement/venues -- free and unauthenticated: the lane table POST /placement works against -- every venue we know, its lane, the VENUE's own fee verbatim, and, where a venue is impossible, why. Read it before paying. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/placement/ready?url= -- free and unauthenticated: whether YOUR service publishes a well-known document a venue's crawler can read, which is the precondition for ever paying us. We read status and headers, never a body. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/placement/{id} -- free and owner-signed: your order, per venue -- state, the evidence the entry is in the catalogue, when it was last checked, and why a venue is human-only or unfunded. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- DELETE https://agent-exec.448c.org/placement/{id} -- free and owner-signed: stop the rechecks and drop the order. No refund; the window you paid for is not resold. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/dns/{name}/records -- free and owner-signed: replace the records we serve for a name you rent, as often as you like. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- DELETE https://agent-exec.448c.org/dns/{name} -- free and owner-signed: give the name back before it expires. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/dns/{name} -- free and unauthenticated: read the records we serve for a name and when it expires. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/pay/requirements -- free: ask a seller, unpaid, what it charges, and get back the accepts[] of its own 402 -- the exact PaymentRequirements to sign before POST /pay can deliver anything. Body: {sellerUrl, method?, headers?, body?}. No payment is sent to the seller and none is taken from you. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/pay/{id} -- free and unauthenticated: read a POST /pay receipt back by id, to cite to the seller. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/quote -- price a limits object before paying. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/supported -- free and unauthenticated: the x402 facilitator read contract, {kinds:[{x402Version, scheme, network}]}, folded out of the same manifest /.well-known/x402.json serves. Same handler and body at https://agent-exec.448c.org/x402/supported, https://agent-exec.448c.org/facilitator/supported, https://agent-exec.448c.org/facilitator/v2/supported, https://agent-exec.448c.org/api/supported. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/verify -- free and unauthenticated: check an EVM `exact` payment offline. Send {x402Version, paymentPayload, paymentRequirements}, get {isValid, invalidReason?, payer?}: EIP-712 recovery plus the same checks our paid routes run on their own X-PAYMENT. No balance or nonce is read, so isValid is not a settlement promise, and a Solana payload is refused rather than called invalid. Also at https://agent-exec.448c.org/x402/verify, https://agent-exec.448c.org/facilitator/verify, https://agent-exec.448c.org/api/verify. POST /settle is deliberately not served here -- settling broadcasts a transaction and spends gas. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/listings -- search the directory by tag, text, tier and liveness (?alive=true). See \"Liveness\" below: every row carries its own probe result. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/listings -- create or update a listing you own, proved by a wallet signature over the request body. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- DELETE https://agent-exec.448c.org/listings -- permanently delete a listing you own: a hard delete, not a tombstone, freeing the row against your owner cap and the directory's global cap. Proved by a wallet signature over its OWN domain-separated string `agent-exec:listing:delete:v1\\n<id>`, not the raw body -- a captured update signature cannot double as a delete. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/listings/{id} -- free and unauthenticated: read ONE listing back by the id POST /listings gave you, in the same `{listing}` envelope that create answered with. The direct lookup, so you need not page the whole catalogue to see your own row; a non-UUID id is refused LISTING_ID_MALFORMED, an unknown one LISTING_NOT_FOUND. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/listings/{id}/uptime -- free and unauthenticated: this listing's observed uptime, derived from the probe history this directory already accumulates. Every count ships beside the ratio so you can recompute it or apply a stricter rule than ours. Grouped by the url probed at the time, so a repointed listing does not inherit the previous host's record. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/storage/{id}/renew?plan=<plan> -- PAID. Extend an object's retention, keeping its id. Same plans and same prices as POST /storage; the window is added to what the object has left, not substituted for it. `id` must be a UUID minted by POST /storage -- an id from the retired free tier is refused, free, with STORAGE_FREE_OBJECT_NOT_ELIGIBLE -- store a new object with POST /storage instead. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/storage/{id}/replace?plan=<plan> -- PAID. Give an object NEW CONTENTS, keeping its id. This is the one that makes stored state usable as MEMORY rather than as a write-once archive: each run overwrites the slot the last run parked. Same plans and same prices as POST /storage. `id` must be a UUID minted by POST /storage -- an id from the retired free tier is refused, free, with STORAGE_FREE_OBJECT_NOT_ELIGIBLE -- store a new object with POST /storage instead. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/storage/free -- RETIRED, and deliberately still live: there is no free storage tier. Any call here -- any body, no signature -- answers POST https://agent-exec.448c.org/storage's own 402 price card at its cheapest plan, with accepts[0].resource naming POST https://agent-exec.448c.org/storage, the one path that settles. Never a 400, never a 404. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/storage/usage -- this wallet's current object count and total stored bytes, proved by an X-Signature header, never a payment. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/storage/{id} -- read back an object you paid to store, proved by an X-Signature header, never a payment. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/storage/list -- page this wallet's currently-unexpired stored objects (id, size, createdAt, expiresAt, label), newest first, proved by an X-Signature header, never a payment. See \"Reading storage back\" below for paging. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- DELETE https://agent-exec.448c.org/storage/{id} -- erase an object you paid to store before it expires, freeing its bytes against your wallet cap. Proved by an X-Signature header, never a payment -- but over its OWN signed domain, distinct from a read: a read signature is refused here. Buys nothing back -- no refund, no retention credit transferred. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/claim/free -- free: atomically win a caller-named key for 300 seconds, or learn who already holds it -- no payment, unlimited distinct keys per wallet, renewable by re-acquiring. A sibling of POST /claim, not a discount on it. Proved by an X-Signature header over its OWN domain, distinct from both the read and release domains below. See \"Coordinating with /claim\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/claim/{key} -- free: who currently holds this key, scoped to your own wallet. `claim: null` (never 404) means nobody holds it. Proved by an X-Signature header, never a payment. See \"Coordinating with /claim\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- DELETE https://agent-exec.448c.org/claim/{key} -- free: release a key you hold before it expires. Proved by an X-Signature header, over its OWN signed domain distinct from a read -- a read signature is refused here. See \"Coordinating with /claim\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/claim/{key}/renew?plan=<plan>&holder=<holder> -- PAID. Extend a hold you already have (a heartbeat), keeping your place in line. Same plans and same prices as POST /claim; the window is added to what the key has left, not substituted for it. Identity is the paying wallet, but `holder` (unsigned) must still name the key's CURRENT holder -- a re-acquire deliberately does not extend, so this explicit, separately-paid call is the only way. See \"Coordinating with /claim\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/attest/{id} -- free and unauthenticated: read a previously-created attestation back by id, to cite it to a third party. Not wallet-scoped and needs no signature -- see \"Verifying an attestation\" below. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/handoff/{id} -- free and unauthenticated: read a briefing back by id. Deliberately not wallet-scoped and needs no signature -- the successor is by construction a different process from the depositor and may hold no wallet at all. Possession of the id is the whole authorisation, so treat it as a secret. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/deadman/{id}/confirm -- free: the live caller closes the loop before the lease expires. Deliberately not wallet-scoped and needs no signature -- possession of the id is the whole authorisation. Refused once the entry has left pending, never a silent no-op. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/deadman/{id} -- free and unauthenticated: read an entry back by id, including its verdict once resolved. If the lease has lapsed and nobody resolved it yet, the probe runs right here before responding. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/drift/{venue} -- free: whether we hold a baseline snapshot for this venue at all, and a hash/byte-count of it, without spending the live re-fetch POST /drift/{venue} costs. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/watch/{id} -- free and unauthenticated: read a watch back by id -- status, last poll, next poll due, and the matching observation once the condition fired. The id is the capability. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/health -- liveness check. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/feedback -- free: complain, ask a question, ask for a price quote, or suggest a service you wish we had. Body { message, kind?, requestId?, contact?, topic? } or plain text; kind is complaint, question, quote, suggestion or other. Every report is read and analysed daily; there is no individual reply. GET /feedback shows the shape.\n- GET https://agent-exec.448c.org/openapi.json -- full OpenAPI 3.1 description of every endpoint above. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/openapi.yaml -- the same OpenAPI document, YAML-serialised. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- GET https://agent-exec.448c.org/.well-known/x402.json -- x402 Bazaar discovery manifest. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n- POST https://agent-exec.448c.org/mcp -- MCP (Model Context Protocol) transport, streamable-http, JSON-RPC 2.0. Three tools: service_card (what agent-exec sells, what it costs, where to pay) and search_listings (same data as GET /listings), both free and read-only, and execute -- PAID, x402 over MCP (the x402 MCP transport): call it without payment to get the price as a PaymentRequired, call it again with a signed payment in _meta['x402/payment'] to run the code; the receipt comes back in _meta['x402/payment-response']. Same prices, same Base and Solana offers, same settlement as POST /execute. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n\n## Something went wrong?\n\nEvery response carries an X-Request-Id header. If a call failed, returned something you did not expect, or a payment did not go through, POST https://agent-exec.448c.org/feedback with { \"kind\": \"complaint\", \"message\": \"what happened\", \"requestId\": \"<that header>\" } -- free, no account, no signature. The same address takes questions, quote requests and service suggestions. Every report is read and analysed daily; there is no individual reply.\n\n## Paying a 402 challenge\n\nEvery priced route above answers an unpaid request with HTTP 402: `{ x402Version, error, accepts: [PaymentRequirements] }`. Pick an entry from `accepts[]` and pay it by sending an `X-PAYMENT` request header on the SAME request, retried: base64 of the UTF-8 JSON object `{\"x402Version\":1,\"scheme\":\"exact\",\"network\":\"<the network named in the challenge>\",\"payload\":{\"signature\":\"0x<EIP-712 signature over the transferWithAuthorization>\",\"authorization\":{\"from\":\"0x<payer>\",\"to\":\"0x<the payTo named in the challenge>\",\"value\":\"<atomic units, >= maxAmountRequired>\",\"validAfter\":\"<unix seconds>\",\"validBefore\":\"<unix seconds>\",\"nonce\":\"0x<32 random bytes>\"}}}`. (A v2-shaped payload on a `PAYMENT-SIGNATURE` header is also accepted -- see GET /openapi.json's x-payment-header.v2 -- but X-PAYMENT is understood by every x402 client and needs no v2 support.)\n\n`payload.signature` is an EIP-712 signature over a `TransferWithAuthorization` message (EIP-3009), not a personal-sign string over the JSON. Domain: `name`/`version` from `accepts[].extra`, `chainId` for `accepts[].network` (8453 for \"base\", 84532 for \"base-sepolia\"), `verifyingContract` = `accepts[].asset`. Message fields: `from` (payer), `to` = `accepts[].payTo`, `value` (atomic units, >= `accepts[].maxAmountRequired`), `validAfter` (unix seconds, 0 is valid), `validBefore` (unix seconds; must be <= now + `accepts[].maxTimeoutSeconds` + 60s clock-skew slack -- 300s + 60s on every route above, checked locally before any facilitator call), `nonce` (0x-prefixed 32 random bytes, caller-chosen, single-use).\n\nPaying in Solana USDC: POST /execute, POST /listings/promote, POST /drift, POST /storage, POST /claim, POST /attest, POST /handoff, POST /deadman, POST /watch, POST /check/address, POST /check/url, POST /check/counterparty, POST /pay, POST /inbox, POST /dns, POST /placement, POST /relay, POST /rpc also accept USDC on Solana at the same price -- their 402 lists a Solana entry in accepts[] (network \"solana\" in x402 v1, \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp\" in v2; payTo GPbCdSaF5Qcfr5kdundH3etood2q5rafnRwdvVrs3Tan) beside the Base one. Pay it with the x402 exact scheme for Solana: a partially-signed USDC TransferChecked that our fee payer (accepts[].extra.feePayer) co-signs and submits, so you need USDC only, no SOL. Wallet-scoped routes (/storage, /claim reads, releases and free grants) prove ownership on Solana too: send X-Signature as \"solana:<base58 pubkey>:<base58 ed25519 signature>\" over exactly the same canonical message a Base caller signs -- ed25519 has no key recovery, so you state the address and we verify against it. Solana owners are stored base58 byte-exact; Base owners stay lowercased.\n\n## Liveness (what the directory offers that a free catalog does not)\n\nEvery row carries its own liveness data (lastProbeCode, lastSeenAlive, dead): lastProbeCode is the outcome of the last probe we ran, and lastSeenAlive is the Unix ms of the last probe it PASSED -- null if it has never passed one, and older than the last probe we ran on a row that is currently failing. We re-probe every listing on a 6-hour interval; a listing that fails 3 consecutive probes is marked dead, ranks below every live listing regardless of what its owner paid, and is eventually evicted -- after 6 hours if it never once answered a probe and its owner has no other listing here that has, 30 days otherwise (a listing under a live promotion keeps its place until that promotion lapses). We do not hide failures: we publish them per row. Pass ?alive=true to GET /listings to get back only the rows that have actually passed a probe -- dead=false AND lastSeenAlive set, which is not the same test as dead=false alone.\n\nThis is the differentiator, so it is stated precisely rather than generously: an unfiltered GET /listings is RANKED by liveness, not filtered by it, and a listing that has never answered a probe reads dead=false until enough consecutive failures accumulate. Ask for ?alive=true if what you need is \"only rows that have passed a probe\" -- that filter is applied in SQL before pagination, so walking the cursor never leaks one.\nA dead row is never silently deleted without warning: every row (not just yours) carries consecutiveFailures, deadSince, and -- once dead -- evictsAt (the unix ms it will be permanently removed if nothing changes) and remedy (a one-line fix: re-POST the same listing id with a working url, which clears dead, consecutiveFailures and the eviction clock in a single write). There are no accounts and no contact field, so this response is the only channel you have to learn a row of yours is about to be deleted. Use `?owner=0x<your address>` to see only your own rows, rather than paging the whole directory.\nA dead row may also carry `ownerVerifiedAlternate: { url, verifiedVia, signedByOwner }` -- present only when a candidate replacement url's OWN x402 discovery document names the SAME owner as this row (proof by an address the candidate's operator actually controls, never a name or description match). This is surfaced ADDITIVELY and is NEVER substituted into `url` above -- see the \"Attribution\" section of /llms.txt for the byte-identical-url promise that field keeps regardless.\nPOST https://agent-exec.448c.org/listings never refuses a listing for the host it names -- a submitter is warned, not turned away. If the url's host matches a known ephemeral-tunnel vendor (e.g. *.trycloudflare.com, *.lhr.life, *.ngrok*, *.loca.lt, *.serveo.net), the response still creates/updates the row (200/201) and adds a `warnings` array naming the host class and that the listing will start failing once the tunnel rotates -- these rotate within hours to a day by design, and this directory has no way to keep serving a url that no longer resolves.\n\n## Listing your service\n\nPublish a url you control and that survives a restart -- your own domain, or a platform url that is stable by contract. Quick tunnels (*.trycloudflare.com, *.lhr.life, *.ngrok*, *.loca.lt, *.serveo.net) get a NEW HOSTNAME every time they restart, by their own vendor's design, not by anything this directory does -- a listing on one of these WILL eventually fail its liveness probe and be evicted (see the \"Liveness\" section of /llms.txt for the exact numbers). The fix costs nothing and is not a new registration: re-POST the SAME listing `id` with the new url. That is a free update, and it clears `dead`, `consecutiveFailures` and the eviction clock in the same write. There is no account to lose either way -- the signing wallet is the identity, so a rotated tunnel only ever means one field changed.\n\nEven a row that already MISSED that window and was evicted is not gone for good: re-POST the SAME id, signed by the SAME wallet that owned it, and if a matching tombstone is still on file (kept up to 90 days) it is restored under its ORIGINAL id and original createdAt -- age is not lost to an outage. Any field you omit (an `id` present makes every field optional, same as an ordinary update) comes back from what was tombstoned, so this is usually a one-field request: just the new `url`. This still counts against your normal listing caps, since it re-occupies a live slot.\n\n## Your service is listed here and you never asked (curated rows)\n\nSome rows in this directory were listed BY US, ABOUT SOMEONE ELSE. If you run an agent-first, accountless, open-source service, we may have found it in a public registry, checked it against a published six-point rubric, probed it live and listed it for free so that you can come and take the row over. Such a row is served with `provenance: \"curated\"`, `claimable: true`, `operator: false` and a `claim` string, and it is NEVER published as ours. If you are reading this because you saw our probe's `Referer: https://agent-exec.448c.org/listings` in your access log, this section is why.\n\n- POST https://agent-exec.448c.org/listings/claim -- free. Body `{\"id\": \"<listing id>\", \"action\": \"claim\" | \"remove\", \"newOwner\": \"<wallet, see below>\"}`. No account, no signup, no email. TWO credentials, and `claim` on your own row tells you which one applies: if we recorded a `payTo` for you at listing time, sign the message below; if your service publishes no x402 card at all, prove control of your own origin instead. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n\nCard on file: two DIFFERENT signed messages, one per action, sent as the `X-Signature` header: personal_sign(`agent-exec:listing:claim:v1\\n<id>`) to claim, personal_sign(`agent-exec:listing:remove:v1\\n<id>`) to remove. Never the raw request body, and never interchangeable -- the signature you send us is public the moment you send it, so one shared message would let anyone who saw you claim your row replay it to DELETE that row instead.\n\nNo card on file: send NO `X-Signature` header, and instead serve that exact same text verbatim (no signing -- just the plaintext) as the body of `/.well-known/agent-exec-listing-claim.txt` at your own origin -- proof by control of the origin rather than a wallet. A `claim` this way also needs `newOwner` in the body (the wallet address the row should transfer to), since there is no signature to derive an owner from; `remove` does not need `newOwner`.\n\nOn `claim` the row transfers to your wallet (the recovered signer, or `newOwner` on the no-card path) and becomes an ordinary owner-signed row: it keeps its id, its original createdAt and its entire probe history, so the uptime record we accumulated on your behalf comes with it. From then on it is yours to change with POST /listings and to delete with DELETE /listings, like any other.\n\nOn `remove` the row is deleted immediately and unconditionally. No argument, no \"are you sure\", no retention period, and no difference in how we treat a row we listed last week from one we have probed for a year. A directory that is hard to leave is a directory nobody trusts to join.\n\nA row you POSTed yourself is not claimable here and returns LISTING_NOT_CLAIMABLE -- it is already yours. A well-formed signature from any wallet other than the recorded payTo returns LISTING_NOT_OWNED, and names the address that would have worked (it is public: your own card publishes it). On the no-card path, a well-known file that does not answer or does not match returns LISTING_WELL_KNOWN_CLAIM_UNVERIFIED.\n\n- POST https://agent-exec.448c.org/listings/takedown -- free, and NOT a credential you can produce. Operator-only moderation: it force-removes any row, authorized by a signature from THIS deployment's own operator wallet (the payTo we publish on our own x402 card) over a third domain-separated message, never interchangeable with the two above. It is named here for completeness and because its effects are visible to you: it exists so a row nobody can prove ownership of is not permanently unremovable, and a url removed this way is blocked from being re-listed for a period afterward, so a POST https://agent-exec.448c.org/listings naming that url is refused LISTING_URL_TAKEN_DOWN until the block ages out. Every refusal you could actually reach on it is an authorization refusal, not a lookup one: without our operator key an unknown `id` answers 400 or 403, never 404. (Complaints, questions, quote requests, service suggestions: POST /feedback, free, read daily.)\n\n## Attribution (optional, on you, not on us)\n\nEvery url a listing carries in GET https://agent-exec.448c.org/listings is served byte-identical to what its owner signed -- we never rewrite it, not even to append a tracking parameter, because the url is part of a signed body and a stray query parameter on what is usually an x402 POST endpoint with a fixed request schema can produce a real 400 for a real caller. So we cannot mark the request you make to a listed service on your behalf. If you found that service through this directory and want its operator to be able to tell, that is on you to add when you call it: send a `Referer: https://agent-exec.448c.org/listings` header, or append `?utm_source=agent-exec` if you have checked the endpoint tolerates an extra query parameter. Unenforced and invisible to us either way -- we do not see the request you send after reading this response.\nWe hold ourselves to the same standard the other direction: every liveness probe this service sends to a listed url (see \"Liveness\" above) carries both a self-identifying User-Agent and a `Referer: https://agent-exec.448c.org/listings`, so any operator we probe can look up who is knocking and why, the same way we are asking you to let operators do for us.\n\n## Identity\n\nNo accounts, ever. In an x402 call the paying wallet is already signature-proven, so it doubles as identity with no extra credential and nothing to register: pay from a wallet and that wallet is who you are to this service.\n\n## Rate limits\n\nEvery endpoint above is capped per source IP, per 60s window. Over the cap gets HTTP 429, code LISTING_RATE_LIMITED, with a Retry-After header (seconds) and details.retryAfterMs -- never a silent drop. POST https://agent-exec.448c.org/listings/promote has its OWN, far more generous budget, separate from GET/POST/DELETE https://agent-exec.448c.org/listings -- reading the free directory to exhaustion never blocks you from paying us. See /openapi.json's 429 response on each route for the exact numbers.\n\n## Reading storage back\n\nPOST /storage costs money; reading it back (GET /storage/{id} and GET /storage/usage) is free but requires proving the wallet that paid, via an X-Signature header -- there is no payment on the read path to reuse as proof. Send ?nonce=<unique per read>&signedAt=<unix seconds> as query parameters, and X-Signature as the header: to read object <id>, sign the domain-separated string `agent-exec:storage:read:v1\n<id>\n<nonce>\n<signedAt>` (fields joined by a literal newline; `<nonce>`/`<signedAt>` are the exact values sent as this call's query parameters) -- NOT the raw request body, NOT JSON; for GET /storage/usage, <id> is the literal string \"usage\", and for GET /storage/list it is the literal string \"list\" (neither is a real object id, and a proof minted for one is not valid for the other). GET /storage/list returns this wallet's currently-unexpired objects newest-first -- id, size, createdAt, expiresAt and label, never the bytes -- so an agent that lost the id POST /storage handed back can still find what it paid to store. `label` is the optional name you chose at write time (POST /storage?plan=...&label=<your name for it>), stored verbatim and echoed on the 201: it is what lets a later run tell its planner state from its scratch buffer WITHOUT fetching either, which a bare list of UUIDs cannot. At most 128 characters, non-empty, no control characters, and a label breaking those rules is cleaned rather than refused (control characters removed, cut to the cap, an empty one ignored). It is opaque to us, it is NOT unique, and there is NO lookup-by-label -- the way to a specific object is always list, then GET /storage/{id}. GET /storage/list is PAGED at 1000 rows per call: the response carries nextCursor, and while it is not null you reach the next page by repeating the call with ?after=<that value>. The cursor is opaque -- echo it back verbatim, never parse or construct one -- and each page is a separate signed read needing its own fresh nonce. Because there is no lookup-by-label, following nextCursor is the ONLY way to reach an object past the newest 1000, so a caller holding more than that must page to see all of what it paid to store. objectCount is the whole-wallet total on every page rather than what remains, truncated is always exactly (nextCursor !== null), and an ?after= value we did not issue is refused with STORAGE_CURSOR_INVALID rather than silently served as the first page -- so a paging loop fails loudly instead of repeating page one forever. A rejected read (STORAGE_SIGNATURE_INVALID, STORAGE_SIGNATURE_MISSING, STORAGE_READ_REQUEST_INVALID) carries details.expected with this same message spelled out for the exact call that failed.\n\n## Deleting storage early\n\nPOST /storage/{id}/renew?plan=<plan> is how stored state OUTLIVES the window it was sold. Retention here is finite and paid-for and nothing extends it as a side effect -- reading an object never moves its expiry -- so without renewal your only option would be to fetch the bytes back and store them again, which re-pays to hold bytes we already have AND hands you a different id, invalidating every reference you already wrote down. Renewal keeps the id. Identity is the PAYING WALLET and nothing else (no X-Signature): the payment already proves who you are, and paying does not let you renew an object that is not yours -- another wallet's id answers 404 exactly as a nonexistent one does. A repeated payment always extends, never refuses (docs/SCOPE.md): the only things refused BEFORE the payment settles, so none of them can cost you anything, are an id from the retired free tier (400 STORAGE_FREE_OBJECT_NOT_ELIGIBLE -- those ids live out their last window and expire, they are never renewed), an id that is not yours (404), and an object that has already expired (410 STORAGE_EXPIRED -- expired objects are never resurrected, store the bytes again instead). A plan whose byte allowance does not cover the object's actual size is NOT refused: the renewal happens anyway, for exactly what was paid, and the 200 body carries an extra note: { code: \"STORAGE_RENEWAL_PLAN_TOO_SMALL\", ... } saying so -- renew on a plan big enough to hold it to clear that note. There is also no ceiling any more on how far a renewal may push the object's REMAINING prepaid window; only 34560000s per SINGLE payment (`paidSeconds`) is still capped. Renewing early is safe and never wasteful -- the new window is ADDED to whatever was left. On success you get { id, expiresAt, previousExpiresAt, plan, note? } with the same id you sent.\nDELETE /storage/{id} erases an object before it expires, freeing its bytes against your wallet cap -- the only way to get below that cap without waiting for your own objects to age out. It is free, but it is NOT proved the same way as a read: reusing a read signature here is refused, because delete signs its own domain-separated message so a captured read proof can never double as a destruction order for the object it read. Same query parameters as a read (?nonce=, ?signedAt=) and the same X-Signature header, but to delete object <id>, sign the domain-separated string `agent-exec:storage:delete:v1\n<id>\n<nonce>\n<signedAt>` (fields joined by a literal newline; `<nonce>`/`<signedAt>` are the exact values sent as this call's query parameters) -- note the `delete` domain, a read signature is not accepted. A successful delete returns { id, deleted: true, freedBytes } -- freedBytes is not a refund or a credit; it only tells you how much room you just made. Deleting buys nothing back: no refund, and no retention credit moved to another object.\n\n## Coordinating with /claim\n\nPOST /claim is an accountless compare-and-set: pay once to atomically win a caller-named key, or learn who already holds it. It coordinates ONE PAYING WALLET's own fleet racing itself -- e.g. several workers on one wallet about to duplicate an irreversible action (a deploy, a post, a purchase) -- not mutually distrusting strangers over a shared namespace: keys are scoped to the paying wallet, invisible to and unaffected by every other wallet's keys. Send { key, holder, plan } -- key is 1..256 UTF-8 bytes naming what you want to hold (no '/' character -- it addresses a URL path segment on the read/release routes below), holder is 1..256 UTF-8 bytes identifying which of your own processes is claiming it, and plan picks the hold duration from the price table above. The response's outcome tells you what happened: \"acquired\" (201) means you won it; \"held\" (200, NOT an error) means somebody already holds it, and held.mine says whether that somebody is YOU -- the signal that stops a crash-resume or a duplicated retry from doing the irreversible action twice. Re-acquiring a key you already hold returns held+mine:true and does NOT extend the hold; acquire again with a longer plan for that. A wallet that already holds 10000 unexpired keys is refused free, before payment, with CLAIM_WALLET_KEY_LIMIT -- release keys you no longer need rather than retrying.\nPOST /claim/free is the same compare-and-set with NO payment: it acquires for exactly 300 seconds, unlimited distinct keys per wallet, renewable by re-acquiring -- 12x shorter than the cheapest paid plan (hour, 3600s), so a hold across a deploy, a batch, or a day is on the paid ladder from the first minute. There is no `plan` field and no payment to prove identity with, so send { key, holder, nonce, signedAt } and an X-Signature header instead: to acquire key <key>, sign the domain-separated string `agent-exec:claim:free-acquire:v1\n5:<key>\n<byteLength(nonce)>:<nonce>\n<signedAt>` (fields joined by a literal newline; the key and nonce are each prefixed with their UTF-8 byte length and a colon; `<nonce>`/`<signedAt>` are the exact values sent as this call's JSON request body fields) -- you sign this exact string, NOT the JSON body that carries these values -- and note the `free-acquire` domain, distinct from both `read` and `release`; neither of those signatures is accepted here. This is its OWN domain -- neither the read signature below nor the release signature works here, and this one does not work for either of those, so a proof captured from routinely polling or releasing a lock can never be replayed into a free acquire of it. Same response shape as the paid acquire (outcome/held/mine), with `plan: \"free\"` and no `payment` field.\nGET /claim/{key} is free and tells you who holds a key in YOUR OWN wallet's namespace right now, or null if nobody does -- checking your own lock must not cost again, or a fleet polling its own hold is charged for not doing work twice. Identity is an X-Signature header, not a payment: send ?nonce=<unique per read>&signedAt=<unix seconds> as query parameters and X-Signature as the header; to inspect key <key>, sign the domain-separated string `agent-exec:claim:read:v1\n5:<key>\n<byteLength(nonce)>:<nonce>\n<signedAt>` (fields joined by a literal newline; the key and nonce are each prefixed with their UTF-8 byte length and a colon; `<nonce>`/`<signedAt>` are the exact values sent as this call's query parameters) -- NOT the raw request body, NOT JSON -- and note the `read` domain, which cannot release the key.\nDELETE /claim/{key} is free and releases a key you hold before it expires, so the next racer does not wait out your hold. It is NOT proved the same way as a read: reusing a read signature here is refused, because release signs its own domain-separated message so a captured inspect proof can never double as a lock-breaking order for the key it inspected. Same query style as a read, PLUS ?holder=<your holder id> (unsigned, checked against the key's CURRENT holder -- the check that stops one member of your own fleet from breaking a sibling's lock, which is the exact situation this product is sold for) -- to release key <key>, sign the domain-separated string `agent-exec:claim:release:v1\n5:<key>\n<byteLength(nonce)>:<nonce>\n<signedAt>` (fields joined by a literal newline; the key and nonce are each prefixed with their UTF-8 byte length and a colon; `<nonce>`/`<signedAt>` are the exact values sent as this call's query parameters) -- NOT the raw request body, NOT JSON -- and note the `release` domain, a read signature is not accepted. A successful release returns { key, released: true }.\nPOST /claim/{key}/renew?plan=<plan>&holder=<holder> is the HEARTBEAT: pay again to extend a hold you already have, without losing your place in line. A re-acquire of the same key deliberately does NOT extend the hold (see above) -- a retry loop must not be able to hold a key indefinitely by accident -- so this is a separate, explicitly-requested, separately-paid call. Identity is the paying wallet (no X-Signature, like POST /claim itself), but `holder` is a separate, unsigned query parameter checked against the key's CURRENT holder, same as DELETE's -- one member of your own fleet cannot extend (or indefinitely renew) a sibling's hold. The window bought is ADDED to the key's current expiry, never substituted for it, so renewing early forfeits nothing. Refused BEFORE payment settles whenever it can be predicted: a key that is not yours or has already expired answers 404 (CLAIM_NOT_FOUND -- never silently re-acquired; somebody else may already legitimately hold it), the wrong holder answers 403 (CLAIM_NOT_YOURS). A repeated payment always extends, never refuses (docs/SCOPE.md): there is no ceiling on how far a renewal may push the key's REMAINING window, only on a SINGLE payment's 2592000s (`paidSeconds`). On success you get { key, plan, expiresAt, previousExpiresAt, payment }.\n\n## Verifying an attestation\n\nPOST /attest sends { url } (1..2048 UTF-8 bytes, absolute http:// or https://) and pays to have us fetch it from OUR vantage point; the response never includes the fetched body, only its hash, byte count, status and headers. A fetch that fails to connect, times out, or hits a redirect refused for SSRF safety is still signed and still billed -- \"we tried, from our vantage, and here is exactly what happened\" is the product, not a guaranteed 200; fetch_ok/fetch_code tell you which happened. GET /attest/{attestation_id} reads it back for free, with no signature and no wallet scoping -- the whole point is that a THIRD PARTY who never paid us can fetch it and check it themselves. To verify: recover the signer of `signature` over the message `\"agent-exec attestation v2\"` followed by, newline-joined in this order: attestation_id, url, final_url_after_redirects, observed_at, http_status, body_sha256, body_bytes, body_truncated, content_type, fetch_ok, fetch_code, redirects -- attestation_id/url/final_url_after_redirects/observed_at/body_sha256/content_type/fetch_code each prefixed with their own UTF-8 byte length and a colon, http_status/body_bytes/body_truncated/fetch_ok/redirects interpolated as their bare String() form (booleans as \"true\"/\"false\") (any EIP-191 personal_sign recovery works -- viem's verifyMessage({address, message, signature}), ethers' verifyMessage, or equivalent) -- and check the recovered address equals `signer_address` in the response, which is also published at GET /health as attestSignerAddress if you lost track of which address to check against. An attestation created before this field set shipped was signed under the domain \"agent-exec attestation v1\" over only attestation_id/url/final_url_after_redirects/observed_at/http_status/body_sha256/body_bytes/content_type (no body_truncated/fetch_ok/fetch_code/redirects) -- it is NOT re-signed, so if v2 verification fails, retry once against the v1 domain and field set before concluding the attestation is invalid.\n\nKEEPING AN ATTESTATION AFTER WE ARE GONE. Verification above needs NOTHING of ours: the signature recovers offline from the JSON you kept, so GET /attest/{id} is a convenience, not the proof -- store the 201 body yourself and you are never dependent on this host existing. For a DATE that does not rest on our word either, every attestation also carries `ots_digest_sha256` (sha256 of the exact message above, then a newline, then the `signature` hex) and `ots_proof_base64`, a complete OpenTimestamps `.ots` proof for that digest from a public calendar. To check it with no call to us: write that preimage (signed message + \"\\n\" + signature, no trailing newline) to `a.txt`, base64-decode `ots_proof_base64` into `a.txt.ots`, then `ots verify a.txt.ots` (pip install opentimestamps-client) -- it is checked against the Bitcoin blockchain. A fresh proof reads \"pending\" until the calendar batches it into a Bitcoin transaction (hours); `ots upgrade a.txt.ots` completes it later, still without us. `ots_proof_base64` is null if no calendar answered while you were waiting -- best effort, never retried, never backfilled; stamp the digest yourself with the same client if you need another anchor.\n","mppResources":[]}