Hermes Plant logo

Hermes Plant

Pay-per-call finance APIs for AI agents

Open navigation

API reference

Errors, status codes, and rate limits.

Every status code Hermes Plant endpoints can return, what causes it, whether to retry, and the agent-side action. Built so your retry logic can be deterministic too.

Status code reference

Codes are authoritative. If a response status is not listed here, treat it as 500.

CodeMeaningRetry?Agent action
200 OKEndpoint computed the deterministic result and includes evidence in the body.No retry needed.Persist the result and the evidence bundle alongside the payment receipt for audit.
400 Bad RequestThe JSON body failed schema validation. The response includes a `findings[]` array with the violating field paths.Do not retry until the input is fixed. A retry with the same body will return 400 again.Inspect `findings[]`, correct the inputs, re-POST.
401 UnauthorizedA protected endpoint requires Bearer credentials (e.g. /api/billing-portal, /api/support/entitlements) and none were supplied.Retry after obtaining a token via `/api/auth/token`.Register and request a client_credentials token, then retry with `Authorization: Bearer <token>`.
402 Payment Required (x402)The first request to any paid endpoint returns 402 with the x402 challenge: amount, network, asset, payTo, scheme, and facilitatorUrl in the response body and headers.Retry the same request after signing the payment. Same body, additional `payment-signature` header.Verify amount/network/payTo against your buyer policy, sign the USDC payment, retry to receive the result.
404 Not FoundThe path is not registered as an x402 endpoint or has been retired.Do not retry — the route does not exist. Check `/openapi.json` and `/.well-known/x402`.Use the OpenAPI spec as the authoritative endpoint registry; if the slug changed, the legacy redirect map handles common renames.
405 Method Not AllowedAll paid endpoints require POST. GET is allowed only on discovery surfaces (/llms.txt, /openapi.json, /.well-known/*).Retry with POST.Switch to POST and include the JSON body the endpoint expects.
409 ConflictSettlement collision — the same x402 payment signature was already used for this endpoint.Do not retry with the same signature. Sign a fresh payment.Generate a new payment and retry. Replay protection is structural; do not reuse signatures.
422 Unprocessable EntitySchema-valid input that cannot be processed (e.g. cashflow series with no sign change, so IRR is undefined).Do not retry unchanged — the result is mathematically undefined.Surface the math constraint to the calling agent's planner; choose a different endpoint or revise inputs.
429 Too Many RequestsRate limit exceeded. The `Retry-After` header gives the wait in seconds. Limits apply per payer address (x402) or per Bearer subject (auth).Retry after the `Retry-After` window. Use exponential backoff if no header is present.Honor `Retry-After` to the second; queue the request rather than retrying tightly.
451 Unavailable For Legal ReasonsPayer hash is on a sanctions or compliance blocklist (returned by Wallet Guard upstream).Do not retry — the block is policy-driven.Surface to the human operator. No automated workaround.
500 Internal Server ErrorUnexpected server-side failure. Settlement is NOT recorded on 500; the payment is reusable.Retry with the same body and payment signature after at least 2 seconds.Retry up to 3 times with backoff. After 3 failures, report the request_id (in the response body) to support.
502 Bad Gatewayx402 facilitator unreachable. Settlement could not be verified.Retry after 5–10 seconds. Settlement state is conserved.Backoff, retry, escalate to Enterprise SLA if persistent.
503 Service UnavailableEndpoint temporarily disabled (deploy or x402 manifest not configured).Retry after `Retry-After` (typically 30s).Switch to a sibling endpoint where possible; otherwise queue and retry.

Standard error envelope

4xx and 5xx responses share one JSON envelope. The `request_id` is also returned in the `x-request-id` response header so agents can correlate without parsing the body.

{
  "error": {
    "code": "invalid_inputs",
    "message": "cashflows must contain at least one negative value",
    "request_id": "req_01H8Z…",
    "service": "cashflowlens-analyze",
    "findings": [
      { "rule": "cashflows.signChange", "path": "cashflows", "severity": "error" }
    ]
  }
}

x402 402 challenge shape

The first unpaid request returns this envelope. Verify amount, network, and payTo against your buyer policy before signing.

HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Payment: {"scheme":"exact","amount":"20000","asset":"USDC","network":"eip155:8453","payTo":"0x…","facilitatorUrl":"https://facilitator.x402.coinbase.com"}

{
  "error": "payment_required",
  "x402": {
    "scheme": "exact",
    "amount": "20000",
    "currency": "USDC",
    "decimals": 6,
    "network": "eip155:8453",
    "payTo": "0x…",
    "facilitatorUrl": "https://facilitator.x402.coinbase.com"
  }
}

Rate limits

  • ● Pay-as-you-go: 60 req/min per payer hash
  • ● Agent Ops: 600 req/min per payer hash
  • ● Enterprise: custom + dedicated facilitator capacity
  • ● 429 always includes a `Retry-After` header in seconds

Idempotency

  • ● Each settlement_id derives from SHA-256 of the payment signature
  • ● Replay returns 409 with the original settlement_id
  • ● Retries on 5xx are safe — settlement is conserved
  • ● Retries on 4xx are unsafe — fix the body first

Backoff recipe

  • ● 402 → retry once with payment
  • ● 429 → wait `Retry-After`, retry once
  • ● 5xx → 2s, 5s, 13s; abort after 3
  • ● 4xx → never retry without changing inputs

Agent integration checklist

  1. Read the OpenAPI spec at /openapi.json to discover endpoints and bodies.
  2. On 402, parse the x402 challenge, verify against your buyer policy.
  3. Sign the payment with the facilitator, retry with the `payment-signature` header.
  4. On 200, persist the response body and the evidence bundle next to the settlement_id.
  5. Honor `Retry-After` and never replay a payment signature against a different endpoint.
  6. Record the request_id from x-request-id for every paid call so support can correlate.