REST API Reference
Hosted Base Sepolia API: https://api.cortex.wallyweb.com
Local development API: http://localhost:3001 (configurable via API_PORT)
Health Check
GET /health
{ "status": "ok" }Catalog Documents
Publish Catalog JSON
POST /catalogs
Stores the exact catalog JSON bytes by keccak256 hash. Use the returned uri and catalog_hash as the service metadata URI/hash.
{
"catalog_json": "{\n \"merchant\": {...},\n \"services\": [...]\n}",
"expected_hash": "0x...",
"merchant_id": "1",
"service_id": "enrich-company-v1"
}{
"catalog_hash": "0x...",
"merchant_id": "1",
"service_id": "enrich-company-v1",
"size_bytes": 2048,
"uri": "https://api.cortex.wallyweb.com/catalogs/0x..."
}Fetch Catalog JSON
GET /catalogs/:hash
Returns the original JSON text as application/json. Metadata is available at GET /catalogs/:hash/metadata.
Quote Documents
Publish Quote Request
POST /quote-requests
Stores the exact agent quote request JSON by keccak256 hash and returns a stable URI.
{
"quote_request_json": "{\n \"request_id\": \"req-001\"\n}",
"expected_hash": "0x...",
"request_id": "req-001",
"merchant_id": "1",
"service_numeric_id": "1",
"service_id": "enrich-company-v1",
"agent": "0x..."
}Publish Quote Response
POST /quote-responses
Stores the exact merchant quote response JSON and can link it to a hosted quote request hash.
{
"quote_response_json": "{\n \"request_id\": \"req-001\",\n \"quote\": {...}\n}",
"expected_hash": "0x...",
"request_hash": "0x...",
"request_id": "req-001",
"merchant_id": "1",
"service_numeric_id": "1",
"agent": "0x..."
}Fetch original JSON at GET /quote-requests/:hash and GET /quote-responses/:hash. Metadata is available at each route's /metadata path.
Agents
Get Agent by ID
GET /agents/:agentId
{
"agent_id": "1",
"owner": "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc",
"metadata_uri": "ipfs://agent-meta",
"pubkey": "0xaabb",
"capabilities_hash": "0x...",
"revoked": false,
"block_number": "10"
}Errors: 400 (invalid ID), 404 (not found)
List Agents by Owner
GET /agents?owner=0x...&limit=50&offset=0
The owner parameter is required.
{
"agents": [...],
"pagination": { "limit": 50, "offset": 0, "count": 1 }
}Intents
Get Intent by ID
GET /intents/:id
{
"intent_id": "1",
"owner": "0x...",
"intent_type": "SWAP_EXACT_IN_MAX_SLIPPAGE",
"input_token": "0x...",
"output_token": "0x...",
"amount_in_max": "1000000000000000000000",
"amount_out_min": "900000000000000000000",
"deadline": "1738965600",
"slippage_bps": "100",
"nonce": "42",
"status": "FILLED",
"block_number": "15",
"fill": {
"solver": "0x...",
"amount_in": "950000000000000000000",
"amount_out": "900000000000000000000",
"tx_hash": "0x...",
"block_number": "18"
}
}If the intent is not filled, fill is null.
List Intents
GET /intents?status=open&limit=50&offset=0
The status filter is optional. Valid values: open, filled, cancelled.
{
"intents": [...],
"pagination": { "limit": 50, "offset": 0, "count": 5 }
}Policies
Get Account Policies
GET /accounts/:address/policies?limit=50&offset=0
{
"account": "0x...",
"policies": [
{
"policy_type": "SPEND_LIMIT",
"token": "0x1111111111111111111111111111111111111111",
"max_per_day": "10000000000000000000000",
"block_number": "12"
},
{
"policy_type": "TARGET_ALLOWLIST",
"target": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512",
"allowed": true,
"block_number": "13"
}
],
"pagination": { "limit": 50, "offset": 0, "count": 2 }
}Commerce
GET /merchants?owner=0x...&active=true — list registered merchants.
GET /merchants/:id — get one merchant.
GET /services?merchant_id=1&capability_hash=0x...&active=true — list services.
GET /services/:id — get one service.
GET /facilitators?active=true — list payment facilitators.
GET /quotes/:quoteHash — get a canonical quote commitment.
GET /receipts?agent=0x...&merchant_id=1 — list settled receipts.
GET /disputes?receipt_id=1 — list receipt-linked disputes.
GET /trust-signals?subject_type=0&subject_id=1 — list trust and risk signals.
GET /merchants/:id/reputation — get receipt, fulfillment, dispute, and trust summaries.
{
"quote_hash": "0x...",
"merchant_id": "1",
"service_numeric_id": "1",
"agent": "0x...",
"token": "0x...",
"facilitator": "0x...",
"amount": "1000000000000000000",
"payment_rail": 3,
"protocol_fee_bps": 0,
"protocol_fee_amount": "0",
"payment_nonce": "1",
"resource_hash": "0x...",
"terms_hash": "0x...",
"x402_payload_hash": "0x...",
"settled": true
}Cortex supports basic wallet transfers, swaps, facilitator-mediated payments, and x402. The x402 payload hash is used only when the selected payment rail is x402.
Commerce Analytics
GET /analytics/commerce
{
"summary": {
"merchants": "1",
"services": "1",
"quotes": "1",
"receipts": "1",
"settled_volume": "1000000000000000000",
"settled_protocol_fees": "0",
"open_disputes": "0"
},
"volume_by_token": [],
"top_merchants": [],
"top_services": [],
"facilitator_volume": [],
"volume_by_payment_rail": [],
"trust_signals_by_kind": []
}Transaction Explain
Explain Transaction
GET /tx/:hash/explain
{
"tx_hash": "0x...",
"block_number": "15",
"summary": "Transaction contained 1 event(s)",
"events": [
{
"eventName": "IntentSubmitted",
"args": { "intentId": "1", "owner": "0x...", "nonce": "42" },
"description": "Intent #1 submitted by 0x..."
}
]
}Common Parameters
| Parameter | Default | Max | Description |
|---|---|---|---|
| limit | 50 | 100 | Results per page |
| offset | 0 | — | Results to skip |
Notes
- All addresses are normalized to lowercase.
- NUMERIC/BIGINT values are returned as strings for BigInt safety.
- All error responses follow the format
{ "error": "message" }.