API reference
The Gordon Platform API is a REST API that handles agent authentication, service discovery, x402 payment authorization, and receipt retrieval. All endpoints return JSON.
All requests and responses use JSON. No GraphQL, no binary formats.
Public, agent-key, user-session, and internal endpoints are explicitly separated.
Authorization supports idempotency and replay protection to prevent duplicate charges.
Authentication
Programmatic agent endpoints authenticate with a Bearer token in the Authorization header. The token is an agent key pair:
Authorization: Bearer gak_pub_<id>:gak_sec_<secret>Agent keys are created in the Gordon dashboard under Account → Agents → [agent] → Agent setup → Connect. The secret is shown only once at creation time.
gak_sec_ half of the key is equivalent to a password. Never log it, commit it to git, or expose it in client-side code.Catalog discovery endpoints are public. Dashboard management endpoints use a user session JWT, while administrative endpoints use Gordon's internal service authentication.
Base URL
https://api.withgordon.aiAll endpoints are relative to this base. There is no /v1/ prefix — paths are versioned implicitly. All requests must use HTTPS.
List services
Returns the public catalog of services available in Gordon. To see which services are enabled for a specific agent, use GET /mcp/agents/:agentId/services with an agent key.
/servicesQuery parameters
categorystringFilter by category: search, scrape, ai, data, infrastructure, security, finance, creative.
trust_statusstringFilter by trust level: listed, discovered, probe_passed, gordon_verified, disabled.
slugstringReturn a single service by slug (e.g. 'exa').
limitintegerNumber of services to return. Default 100, max 500.
Response
{
"services": [
{
"id": "0b3f2c1a-7e44-4a90-9b1e-2c8d5f6a1b20",
"slug": "exa",
"name": "Exa",
"description": "AI-powered web search for agents",
"website": "https://exa.ai",
"logo_url": null,
"category": "search",
"source": "bazaar",
"trust_status": "gordon_verified",
"operation_count": 3,
"paid_operation_count": 2,
"free_operation_count": 0,
"min_price_units": 1000
}
],
"count": 1
}The list endpoint returns per-service aggregates (operation_count, paid_operation_count, free_operation_count, min_price_units), not the full operation list — fetch Service detail for operations. It is bounded by limitonly (no cursor), and is public and agent-agnostic — per-agent enablement lives on the agent's enabled-service record (see Policy controls).
Service detail
Fetch full details for a single catalog service, including all operations and pricing.
/services/:serviceIdPath parameters
serviceIdstringrequiredService slug or UUID (e.g. 'exa').
Response
{
"id": "0b3f2c1a-7e44-4a90-9b1e-2c8d5f6a1b20",
"slug": "exa",
"name": "Exa",
"description": "AI-powered web search for agents",
"website": "https://exa.ai",
"logo_url": null,
"category": "search",
"trust_status": "gordon_verified",
"operations": [
{
"availability": "paid_x402",
"id": "b7c0e9d2-1f34-4c55-8a66-9d0e1f2a3b4c",
"operation_id": "search.web",
"label": "Web search",
"method": "POST",
"endpoint": "https://api.exa.ai/search",
"category": "search",
"execution": "sync",
"price_model": "fixed",
"estimated_price_units": 1000,
"max_price_units": null,
"params": { },
"payment": {
"scheme": "exact",
"network": "base",
"token": "USDC",
"amount_units": 1000,
"pay_to": "0x6d6E695b09861467c7d462f5AAF31cF3540B9192"
}
}
]
}operation_id is the slug agents send; id is the operation's UUID. availability is one of paid_x402, free_verified, or unverified (from the latest live probe), and payment is null for non-paid operations. The catalog is public and agent-agnostic — spend caps, enabled_operations, and approval thresholds live on the agent's enabled-service record (see Policy controls).
Policy preflight
Check whether the current policy would allow a payment without signing, reserving spend, creating approvals, or writing settlement rows. This is advisory: /x402/authorize always re-evaluates live policy and remains authoritative.
/x402/checkpayment_requirementobjectrequiredThe decoded provider payment requirement, including v2 accepts arrays when supplied.
max_payment_unitsintegerrequiredMaximum micro-units willing to pay.
original_requestobjectrequiredProvider request descriptor. body_hash binds the decision metadata to the exact request body.
replay_keystringrequiredUnique preflight replay-protection key.
service_idstringCatalog service slug, such as exa.
operation_idstringOperation slug, such as search.web.
{
"check": true,
"would_authorize": true,
"result": "allow",
"reason": "x402_authorized",
"amount_units": 7000,
"approval_required": false
}Confirm settlement
Called after the provider returns 200 with its payment-response proof. Gordon extracts the transaction hash, independently verifies the successful exact USDC transfer on-chain, marks the settlement confirmed, and finalizes the receipt.
/x402/settlements/:settlementId/completePath parameters
settlementIdstringrequiredSettlement ID from the authorize response.
Request body
payment_response_headerstring | objectrequiredThe provider's X-Payment-Response value — a raw base64 string, or an object keyed by header name.
tx_hashstringOn-chain settlement tx hash. Optional when Gordon can decode it from the provider payment response.
Response
Returns the updated settlement row plus confirmed_via:
{
"id": "85e6f79c-4e6a-4f95-b18c-1baabd45f879",
"transaction_id": "8510fc02-c699-42ea-aafc-04f0e18dd3d5",
"receipt_status": "confirmed",
"tx_hash": "0x9c1f...e2",
"settled_at": "2026-05-27T05:31:38.000Z",
"confirmed_via": "onchain"
}Fetch receipt
Fetch a single signed receipt by settlement ID. Requires agent key authentication.
/x402/settlements/:settlementIdPath parameters
settlementIdstringrequiredSettlement ID from the authorize response.
Response
The settlement row (abbreviated):
{
"id": "85e6f79c-4e6a-4f95-b18c-1baabd45f879",
"transaction_id": "8510fc02-c699-42ea-aafc-04f0e18dd3d5",
"agent_id": "agent_yzmxwq3v48",
"service_id": "0b3f2c1a-7e44-4a90-9b1e-2c8d5f6a1b20",
"operation_id": "search.web",
"network": "base",
"token": "USDC",
"amount_units": 1000,
"pay_to": "0x6d6E695b09861467c7d462f5AAF31cF3540B9192",
"receipt_status": "confirmed",
"tx_hash": "0x9c1f...e2",
"authorized_at": "2026-05-27T05:31:36.000Z",
"settled_at": "2026-05-27T05:31:38.000Z"
}List receipts
Returns the authenticated agent's settlements, newest first (by authorized_at).
/agents/:agentId/settlementsQuery parameters
limitintegerNumber of settlements to return. Default 25, max 100.
Response
{
"settlements": [
{
"id": "85e6f79c-4e6a-4f95-b18c-1baabd45f879",
"transaction_id": "8510fc02-c699-42ea-aafc-04f0e18dd3d5",
"service_id": "0b3f2c1a-7e44-4a90-9b1e-2c8d5f6a1b20",
"operation_id": "search.web",
"amount_units": 1000,
"receipt_status": "confirmed",
"authorized_at": "2026-05-27T05:31:36.000Z",
"settled_at": "2026-05-27T05:31:38.000Z"
}
],
"count": 1
}Agent management
Agents are created and managed in the Gordon dashboard. Two agent-key-authenticated endpoints are available for programmatic use:
/mcp/agents/me— resolve agent info from bearer key/mcp/agents/:agentId/services— list services enabled for this agentGET /mcp/agents/me response
{
"agent_id": "agt_def456",
"name": "research-bot",
"created_at": "2026-05-01T00:00:00Z"
}withgordon.ai/account/agents. They are not available via agent key.Rotate / verify agent key
Key rotation is performed in the Gordon dashboard at Account → Agents → [agent] → Agent setup → Connect → Rotate. The old key stops working immediately on revocation; caches on MCP server instances expire within seconds.
Verify a key (agent key auth)
/mcp/agents/meReturns agent metadata if the key is valid. Returns 401 if it has been revoked.
curl https://api.withgordon.ai/mcp/agents/me \
-H "Authorization: Bearer gak_pub_...:gak_sec_..."Policy controls
Each agent has a spend policy that Gordon enforces before every payment. Policies are set in the dashboard (Account → Agents → [agent] → Agent setup → Policies) and can be read via the API.
| Field | Column default | Description |
|---|---|---|
| max_per_call_units | 1,000,000 ($1.00) | Maximum units per individual call. Calls above this are rejected (402) with amount_exceeds_per_call_limit. |
| max_per_day_units | 50,000,000 ($50.00) | Maximum total units in a 24-hour rolling window. Calls above this are rejected (402) with daily_spend_limit_exceeded. |
| require_approval_above_units | 10,000,000 ($10.00) | Calls above this amount escalate (402) with approval_required + an approval_id, instead of paying. |
| enabled_operations | null (all allowed) | Per-service operation allowlist. null = all operations. Non-null = restricted list. |
| allowed_domains | ["*"] (any) for scrape/crawl | Target-domain allowlist for scrape/crawl operations (matched against metadata.target_url's hostname). See “Target domain allowlist” below for the matching rules. |
10,000,000,000,000 units = $10,000,000 per call, per day, and approval threshold), so they work out of the box — tighten them per service. The values in the table above are the column defaults: they apply when you enable a service manually via POST /agents/:agentId/services and omit a field.max_per_call_units of 1,000,000 caps a single call at $1.00.Target domain allowlist
For scrape and crawl operations, Gordon checks the hostname of metadata.target_url against allowed_domains. The default ["*"] allows any target; tighten it with either entry style:
- Bare domain —
example.comallows the apex and every subdomain at any depth (api.example.com,a.b.example.com). - Glob —
*.example.comallows exactly one subdomain level (api.example.com) but not the apex and nota.b.example.com. Partial labels work (api-*.example.com), and you can scope deeper with*.docs.example.com. *— a single literal star allows any target (the permissive default).
* matches a single DNS label (no dots) and patterns are anchored end-to-end, so *.example.com never matches a look-alike such as evil.example.com.attacker.com. Need every subdomain depth? Use the bare domain instead.