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

GET/v1/scores/:did

Public, 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.

ParameterTypeRequiredDescription
transactionCountintegeralwaysTotal payment events observed for this DID
accountAgeDaysinteger | nullalwaysDays since the DID was first seen on the network
successRatenumber | nullalwaysRatio of confirmed intents to confirmed + cancelled
uniqueMerchantCountintegeralwaysDistinct merchants the agent has transacted with
firstSeenAtISO 8601 | nullalwaysTimestamp of first observed event
lastSeenAtISO 8601 | nullalwaysTimestamp 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

GET/v1/settlement-rails

Use 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

StatusMeaning
200 / 201Success
400Bad request — invalid or missing field
401Unauthorized — missing or invalid API key
404Resource not found
409Conflict — invalid state transition
429Rate limit exceeded
500Internal server error

Error bodies always include an error string: {"error": "Payment intent pi_xxx was not found"}

Create a Payment Intent

POST/v1/payment-intents
ParameterTypeRequiredDescription
merchantIdstringrequiredYour merchant identifier
amount.amountMinorintegerrequiredAmount in smallest currency unit (e.g. cents)
amount.currencystringrequired3-letter ISO currency code (e.g. USD)
settlementAssetstringrequiredUSDC, USDT, ETH, BTC, SOL, or XRP
target.kindstringrequireddomain_purchase, hosting_purchase, or merchant_checkout
target.referencestringrequiredReference for the purchase target
metadataobjectoptionalKey-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

GET/v1/payment-intents/:id
curl https://teranode.ai/v1/payment-intents/pi_xxx \
  -H "Authorization: Bearer mk_live_your_api_key"

Authorize a Payment Intent

POST/v1/payment-intents/:id/authorize

Transitions status from requires_authorizationauthorized. Idempotent — returns the current intent if already authorized.

ParameterTypeRequiredDescription
walletIdstringrequiredWallet identifier approving the payment
networkstringrequiredBlockchain network (e.g. base, ethereum)
authorizationReferencestringrequiredReference from the wallet adapter
curl -X POST https://teranode.ai/v1/payment-intents/pi_xxx/authorize \
  -H "Authorization: Bearer mk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"walletId":"wallet_primary","network":"base","authorizationReference":"0xabc123"}'

Route a Payment Intent

POST/v1/payment-intents/:id/route

Transitions status from authorizedrouted. Idempotent — returns the current intent if already routed.

ParameterTypeRequiredDescription
strategystringrequiredonchain or hybrid
networkstringrequiredBlockchain network for settlement
destinationstringrequiredDestination wallet address
routeReferencestringrequiredReference 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

POST/v1/payment-intents/:id/confirm

Transitions status from routedconfirmed. Idempotent.

ParameterTypeRequiredDescription
settlementReferencestringrequiredOn-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

POST/v1/payment-intents/:id/cancel

Cancels 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

GET/v1/payment-intents/:id/events

Returns 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

POST/v1/webhooks

Registers a URL to receive webhook events. Returns an endpoint with a secret — store it securely, it is only returned once.

ParameterTypeRequiredDescription
merchantIdstringrequiredYour merchant identifier
urlstringrequiredHTTPS URL to receive webhook POST requests
descriptionstringoptionalHuman-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

GET/v1/webhooks?merchantId=:merchantId
curl "https://teranode.ai/v1/webhooks?merchantId=merchant_demo" \
  -H "Authorization: Bearer mk_live_your_api_key"

Delete a Webhook Endpoint

DELETE/v1/webhooks/:id
curl -X DELETE https://teranode.ai/v1/webhooks/whe_xxx \
  -H "Authorization: Bearer mk_live_your_api_key"

List Webhook Deliveries

GET/v1/webhooks/:id/deliveries

Returns 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

POST/v1/domain-purchases/quotes
ParameterTypeRequiredDescription
domainNamestringrequiredDomain name to price (e.g. teranode.ai)
registrationYearsintegerrequiredNumber 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

POST/v1/domain-purchases/checkouts

Creates 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.

ParameterTypeRequiredDescription
merchantIdstringrequiredYour merchant identifier
domainNamestringrequiredDomain name to purchase
registrationYearsintegerrequiredNumber of years
settlementAssetstringrequiredUSDC is live for x402 domain purchases; USDT, ETH, BTC, SOL, and XRP return placeholder rail metadata
metadataobjectoptionalKey-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

POST/v1/wallet-authorizations

Creates a challenge for a wallet to sign, authorizing a payment intent.

ParameterTypeRequiredDescription
paymentIntentIdstringrequiredID of the payment intent to authorize
walletIdstringrequiredWallet identifier
networkstringrequiredBlockchain 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

POST/v1/wallet-authorizations/:id/approve

Submits the signed challenge, transitioning the payment intent to authorized.

ParameterTypeRequiredDescription
authorizationReferencestringrequiredSigned 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"}'
Live agent demo · raising now 20 min · founder call Book →