API Reference
Base URL: https://teranode.ai
Most /v1/* endpoints require authentication. The Agent Score API under /v1/scores is public — counterparties query it before accepting a transaction. Responses are JSON with a data envelope on success and an error string on failure.
Get an Agent Score
/v1/scores/:didPublic, unauthenticated. Returns the reputation record for a Teranode-registered agent DID. Call this before accepting a transaction from an agent — the same way a lender queries FICO before extending credit. Returns 404 if the DID is not registered.
curl https://teranode.ai/v1/scores/did:teranode:01JABCDE...
Response:
{
"data": {
"did": "did:teranode:01JABCDE...",
"score": null,
"status": "bootstrapping",
"signals": {
"transactionCount": 12,
"accountAgeDays": 41,
"successRate": 0.92,
"uniqueMerchantCount": 4,
"firstSeenAt": "2026-03-08T14:22:11.000Z",
"lastSeenAt": "2026-04-17T09:01:43.000Z"
},
"explanation": "Score computation in development. Signals below are sourced from on-network activity."
}
}
The numeric score is null during the bootstrapping phase. We publish the signal inputs honestly rather than fabricate a number until cross-merchant volume is sufficient to calibrate.
Score Signals
The signals block is the current observable shape of the reputation record. Every integrated merchant's payment events feed these values.
| Parameter | Type | Required | Description |
|---|---|---|---|
| transactionCount | integer | always | Total payment events observed for this DID |
| accountAgeDays | integer | null | always | Days since the DID was first seen on the network |
| successRate | number | null | always | Ratio of confirmed intents to confirmed + cancelled |
| uniqueMerchantCount | integer | always | Distinct merchants the agent has transacted with |
| firstSeenAt | ISO 8601 | null | always | Timestamp of first observed event |
| lastSeenAt | ISO 8601 | null | always | Timestamp of most recent observed event |
getAgentScore (MCP)
The same endpoint is exposed as a free MCP tool on the Teranode MCP server so agent frameworks can self-check a counterparty before transacting. The tool name is getAgentScore, priceUsd: 0, input is { did: string }, output is the same AgentScore shape returned by the HTTP endpoint.
MCP endpoint: https://teranode.ai/mcp
Settlement Rails
/v1/settlement-railsUse this endpoint to discover which rails are live versus placeholder tracks before attempting execution. Today the live domain-purchase rail is USDC over x402.
Authentication
Pass your API key in the Authorization header as a Bearer token on every request to /v1/*.
curl https://teranode.ai/v1/payment-intents/pi_xxx \ -H "Authorization: Bearer mk_live_your_api_key"
Requests without a valid key return 401 Unauthorized.
Idempotency
Pass a unique Idempotency-Key header when creating payment intents. If a request with the same key has already succeeded, the original intent is returned without creating a duplicate.
curl -X POST https://teranode.ai/v1/payment-intents \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Idempotency-Key: order_abc_123" \
-H "Content-Type: application/json" \
-d '{"merchantId":"merchant_demo","amount":{"amountMinor":1200,"currency":"USD"},"settlementAsset":"USDC","target":{"kind":"merchant_checkout","reference":"order_abc_123"}}'
Errors
| Status | Meaning |
|---|---|
| 200 / 201 | Success |
| 400 | Bad request — invalid or missing field |
| 401 | Unauthorized — missing or invalid API key |
| 404 | Resource not found |
| 409 | Conflict — invalid state transition |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Error bodies always include an error string: {"error": "Payment intent pi_xxx was not found"}
Create a Payment Intent
/v1/payment-intents| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantId | string | required | Your merchant identifier |
| amount.amountMinor | integer | required | Amount in smallest currency unit (e.g. cents) |
| amount.currency | string | required | 3-letter ISO currency code (e.g. USD) |
| settlementAsset | string | required | USDC, USDT, ETH, BTC, SOL, or XRP |
| target.kind | string | required | domain_purchase, hosting_purchase, or merchant_checkout |
| target.reference | string | required | Reference for the purchase target |
| metadata | object | optional | Key-value string pairs attached to the intent |
curl -X POST https://teranode.ai/v1/payment-intents \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"merchantId": "merchant_demo",
"amount": { "amountMinor": 1200, "currency": "USD" },
"settlementAsset": "USDC",
"target": { "kind": "merchant_checkout", "reference": "order_abc_123" },
"metadata": { "customerId": "cust_456" }
}'
Get a Payment Intent
/v1/payment-intents/:idcurl https://teranode.ai/v1/payment-intents/pi_xxx \ -H "Authorization: Bearer mk_live_your_api_key"
Route a Payment Intent
/v1/payment-intents/:id/routeTransitions status from authorized → routed. Idempotent — returns the current intent if already routed.
| Parameter | Type | Required | Description |
|---|---|---|---|
| strategy | string | required | onchain or hybrid |
| network | string | required | Blockchain network for settlement |
| destination | string | required | Destination wallet address |
| routeReference | string | required | Reference from the routing engine |
curl -X POST https://teranode.ai/v1/payment-intents/pi_xxx/route \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"strategy":"onchain","network":"base","destination":"0xdef456","routeReference":"route_789"}'
Confirm a Payment Intent
/v1/payment-intents/:id/confirmTransitions status from routed → confirmed. Idempotent.
| Parameter | Type | Required | Description |
|---|---|---|---|
| settlementReference | string | required | On-chain transaction hash or settlement ID |
curl -X POST https://teranode.ai/v1/payment-intents/pi_xxx/confirm \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"settlementReference":"0xtxhash123"}'
Cancel a Payment Intent
/v1/payment-intents/:id/cancelCancels an intent from any pre-confirmation status. Idempotent — already-cancelled intents are returned as-is. Cannot cancel a confirmed intent.
curl -X POST https://teranode.ai/v1/payment-intents/pi_xxx/cancel \ -H "Authorization: Bearer mk_live_your_api_key"
List Payment Intent Events
/v1/payment-intents/:id/eventsReturns a full audit trail of every state transition for the intent, in chronological order.
curl https://teranode.ai/v1/payment-intents/pi_xxx/events \ -H "Authorization: Bearer mk_live_your_api_key"
Register a Webhook Endpoint
/v1/webhooksRegisters a URL to receive webhook events. Returns an endpoint with a secret — store it securely, it is only returned once.
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantId | string | required | Your merchant identifier |
| url | string | required | HTTPS URL to receive webhook POST requests |
| description | string | optional | Human-readable label for this endpoint |
curl -X POST https://teranode.ai/v1/webhooks \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"merchantId":"merchant_demo","url":"https://yourapp.com/webhooks/teranode","description":"Production"}'
List Webhook Endpoints
/v1/webhooks?merchantId=:merchantIdcurl "https://teranode.ai/v1/webhooks?merchantId=merchant_demo" \ -H "Authorization: Bearer mk_live_your_api_key"
Delete a Webhook Endpoint
/v1/webhooks/:idcurl -X DELETE https://teranode.ai/v1/webhooks/whe_xxx \ -H "Authorization: Bearer mk_live_your_api_key"
List Webhook Deliveries
/v1/webhooks/:id/deliveriesReturns all delivery attempts for an endpoint — useful for debugging failed events.
curl https://teranode.ai/v1/webhooks/whe_xxx/deliveries \ -H "Authorization: Bearer mk_live_your_api_key"
Verifying Webhook Signatures
Every webhook request includes an X-Teranode-Signature header. Verify it to confirm the request came from Teranode.
import { createHmac } from "node:crypto";
function verifyWebhook(rawBody: string, secret: string, signature: string): boolean {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
return expected === signature;
}
// In your Express handler:
app.post("/webhooks/teranode", (req, res) => {
const sig = req.headers["x-teranode-signature"] as string;
if (!verifyWebhook(req.rawBody, process.env.WEBHOOK_SECRET!, sig)) {
return res.status(401).send("Invalid signature");
}
const event = req.body;
console.log(event.type, event.paymentIntentId);
res.sendStatus(200);
});
Get a Domain Purchase Quote
/v1/domain-purchases/quotes| Parameter | Type | Required | Description |
|---|---|---|---|
| domainName | string | required | Domain name to price (e.g. teranode.ai) |
| registrationYears | integer | required | Number of years to register (1–5) |
curl -X POST https://teranode.ai/v1/domain-purchases/quotes \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"domainName":"teranode.ai","registrationYears":1}'
Create a Domain Purchase Checkout
/v1/domain-purchases/checkoutsCreates a payment intent scoped to a domain purchase. The live settlement path is USDC over x402; placeholder rails return 409 settlement_rail_not_live so clients can fail cleanly.
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantId | string | required | Your merchant identifier |
| domainName | string | required | Domain name to purchase |
| registrationYears | integer | required | Number of years |
| settlementAsset | string | required | USDC is live for x402 domain purchases; USDT, ETH, BTC, SOL, and XRP return placeholder rail metadata |
| metadata | object | optional | Key-value string pairs |
curl -X POST https://teranode.ai/v1/domain-purchases/checkouts \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"merchantId":"merchant_demo","domainName":"teranode.ai","registrationYears":1,"settlementAsset":"USDC"}'
Request Wallet Authorization
/v1/wallet-authorizationsCreates a challenge for a wallet to sign, authorizing a payment intent.
| Parameter | Type | Required | Description |
|---|---|---|---|
| paymentIntentId | string | required | ID of the payment intent to authorize |
| walletId | string | required | Wallet identifier |
| network | string | required | Blockchain network |
curl -X POST https://teranode.ai/v1/wallet-authorizations \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"paymentIntentId":"pi_xxx","walletId":"wallet_primary","network":"base"}'
Approve Wallet Authorization
/v1/wallet-authorizations/:id/approveSubmits the signed challenge, transitioning the payment intent to authorized.
| Parameter | Type | Required | Description |
|---|---|---|---|
| authorizationReference | string | required | Signed reference from the wallet |
curl -X POST https://teranode.ai/v1/wallet-authorizations/war_xxx/approve \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{"authorizationReference":"0xsignedchallenge"}'