OPEN BY DESIGNBuild with your agents.
Run an agent from your application, or connect capabilities to one you create.
DEVELOPER API / V1Your first external run.
Use an owned NFT agent from a server, CLI, bot, or backend. Use this website’s HTTPS API from your backend with your own scoped API key.
- Get access. Get a published ETH access pass in Explore, then open My Agents → Collected. Choose API access on the agent. Its examples already include the endpoint and Version ID.
- Create a key. Choose that version, name the key, and set its expiry. Save the secret in your server environment; it appears once.
- Use included runs. Check your remaining credits in Collected. You can start without depositing ETH. An optional funded budget lets you continue after credits run out; include its ID explicitly to authorize paid usage.
- Submit and poll. Set the variables below, submit once, then read the returned run ID until execution finishes. Use the answer immediately; payment confirmation continues separately.
$ quickstart.sh bash / zsh / WSL
export AGENT_API_BASE='<website HTTPS origin>/api'
export AGENT_API_KEY='<your saved secret>'
export AGENT_VERSION_ID='<version ID from the agent API tab>'
export REQUEST_ID="$(node -e 'console.log(crypto.randomUUID())')"
curl "$AGENT_API_BASE/v1/runs" \
-H "Authorization: Bearer $AGENT_API_KEY" \
-H "Idempotency-Key: $REQUEST_ID" \
-H "Content-Type: application/json" \
--data "{\"versionId\":\"$AGENT_VERSION_ID\",\"input\":\"What can you help me with?\"}"
# Set RUN_ID to the id returned above.
curl "$AGENT_API_BASE/v1/runs/$RUN_ID" \
-H "Authorization: Bearer $AGENT_API_KEY"> JavaScript Node.js / server only
const base = process.env.AGENT_API_BASE ?? '<website HTTPS origin>/api';
const headers = {
Authorization: 'Bearer ' + process.env.AGENT_API_KEY,
'Content-Type': 'application/json',
};
// Persist this ID with your job; reuse it for a retry of this same input.
const requestId = crypto.randomUUID();
const response = await fetch(base + '/v1/runs', {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': requestId },
body: JSON.stringify({
versionId: process.env.AGENT_VERSION_ID,
budgetId: process.env.AGENT_BUDGET_ID || undefined, // Optional paid fallback
input: 'What can you help me with?',
}),
});
let run = await response.json();
if (!response.ok) throw new Error(run.error?.message);
const deadline = Date.now() + 12 * 60_000;
while (!['succeeded', 'failed', 'cancelled', 'unknown'].includes(run.execution)) {
if (Date.now() > deadline) throw new Error('Resume polling run ' + run.id);
await new Promise(resolve => setTimeout(resolve, 2000));
const poll = await fetch(base + '/v1/runs/' + run.id, { headers });
const result = await poll.json();
if (!poll.ok) throw new Error(result.error?.message);
run = result;
}
console.log({ id: run.id, execution: run.execution,
funding: run.funding, answer: run.output?.text, error: run.error });
// The answer is ready when execution succeeds, even if funding is pending.
// Save run.id. Fetch this same receipt later for final payment status;
// the server continues settlement without this client staying connected.Retries & receipts
A new run returns HTTP 202. Reusing the same key, request ID, and payload returns the original run (200); changing its payload returns 409. If a request times out, retry with that same ID. Poll every two seconds and respect HTTP 429 / Retry-After.
A successful answer may still be awaiting payment confirmation. Final funding is settled, released, or unreserved. Amounts are ETH wei strings; pending charges are null.
Quota & spending
API and website runs share the creator’s quota. Accepted work reserves a slot; confirmed success consumes it. Released or unreserved runs return it. Mint-funded credits are used first. Without a budgetId, exhaustion returns 409 INCLUDED_RUNS_EXHAUSTED and never charges ETH. With an explicit budgetId, subsequent runs use that budget at the published price.
Revoke a key to stop requests. Close a budget to return unused ETH. Already reserved work may settle; return any later released funds from that budget’s card.
GET /v1/accessAgent details, remaining included credits, and creator usage limit.POST /v1/runsCreate a run; Idempotency-Key required (8–128 letters, digits, periods, colons, underscores or hyphens).GET /v1/runs/:idPoll a run created by the same API key.POST /v1/runs/:id/cancelRequest cancellation; continue polling for the funding result.
Keep keys out of browser bundles, public repositories, and logs. Keys only authorize their agent version and cannot manage wallets or create keys. A browser session manages keys and budgets. Your backend calls this API; arbitrary cross-origin browser requests are blocked. After a key expires or is revoked, view its historical receipts in the website’s Runs page. ETH here is test ETH with no monetary value.
01 / REMOTE MCPConnect a tool server.
Add a Streamable HTTP MCP endpoint, inspect its discovered tool schemas, and approve a subset. Tokens are encrypted server-side. Discovery never activates new tools.
http://127.0.0.1:4100/mcp
The URL above is an explicit local fixture. External connections require HTTPS and public network addresses. Server annotations are untrusted.
02 / IMPORT APIMake an API useful.
Import an OpenAPI 3.0 or 3.1 JSON document. Initial support covers GET operations with scalar query parameters and JSON responses. References and path parameters require an expanded adapter.
http://127.0.0.1:4100/openapi.json
03 / MANUAL HTTPA direct connection.
Register a read-only endpoint accepting a query parameter and returning JSON. Authentication remains scoped to its creator connection. Redirects and internal network targets are blocked.
A connection test demonstrates a call; it does not certify safety or future availability.
04 / EXTERNAL AGENTSYour service. Your hosting.
The repository includes an external-agent protocol and example. Production admission, asynchronous callbacks, and hosted-agent billing remain disabled pending their security tests.
No arbitrary code, shell commands, or packages execute in the application process.