relayer/docs/http-api-design.md
High-level description of the V2 HTTP API contract. For the generated spec see openapi.yml.
Every operation follows a two-step flow:
jobId (UUID) and a Retry-After headerRetry-After polls by jobId — returns 202 (still processing), 200 (completed), or an error codeRead-only endpoints (GET /v2/keyurl, health checks) respond synchronously.
All V2 responses share a single format:
{
"status": "queued | succeeded | failed",
"requestId": "<uuid>",
"result": { /* endpoint-specific */ } | null,
"error": { /* error object */ } | null
}
status is always present — the outcome can be determined from the body alone, independent of the HTTP coderesult and error are mutually exclusive; the unused field is nullError responses carry a machine-readable label and a human-readable message:
{
"label": "validation_failed",
"message": "Validation failed for 2 fields in the request",
"details": [
{ "field": "contractAddress", "issue": "Must be 0x + 40 hex chars" }
]
}
details array is present only for validation_failed and missing_fields| Code | Meaning |
|---|---|
200 | Completed (GET success, keyurl) |
202 | Accepted / still processing |
400 | Client error (bad JSON, missing fields, validation, unsupported chain, ACL) |
404 | Job ID not found |
429 | Rate limited (queue full) — includes Retry-After |
500 | Internal error |
503 | Unavailable (timeout, paused contract, insufficient balance, gateway unreachable) |
Requests are SHA-256 hashed into an internal job ID (int_job_id). The database enforces uniqueness on active requests via a partial unique index.
ext_job_id — no duplicate processing| ID | Exposed | Format | Purpose |
|---|---|---|---|
int_job_id | No | SHA-256 hash | Content-based deduplication |
ext_job_id | Yes | UUID v4 | User facing, references an operation across requests. |
requestId | Yes | UUID v7 | Per-HTTP-call logging/correlation |
ext_job_id is stable across retries of the same content; requestId is fresh on every HTTP call and not stored.
See ID.md for detailed relationships.
Both POST (202) and GET (202) responses include a Retry-After header computed from real-time queue depth and drain rate — not a fixed value.
A completed request can carry a negative business result that is not an error.
accepted: false returns 200 OK with status: succeededChain ID support and host ACL checks run before the request enters any queue, so invalid requests don't consume queue capacity. These return 400 immediately.
POST /v2/{endpoint}
├─ Parse + validate ──→ 400 (reject early)
├─ Dedup check
│ ├─ Duplicate completed ──→ 200 (return stored result)
│ └─ Duplicate processing ──→ 202 (reuse existing job_id)
└─ New request ──→ 202 (queue + return job_id)
GET /v2/{endpoint}/{job_id}
├─ Not found ──→ 404
├─ Still processing ──→ 202 + Retry-After
├─ Completed ──→ 200 + result
└─ Failed ──→ 4xx/5xx + error label
For internal status transitions (queued → processing → tx_in_flight → …), see status-transitions.md.
| Method | Path | Async | Notes |
|---|---|---|---|
| POST | /v2/public-decrypt | Yes | Chain ID validated early |
| GET | /v2/public-decrypt/{job_id} | Yes | + host ACL + revert classification |
| POST | /v2/user-decrypt | Yes | Chain ID validated early |
| GET | /v2/user-decrypt/{job_id} | Yes | Share threshold required |
| POST | /v2/delegated-user-decrypt | Yes | Chain ID validated early |
| GET | /v2/delegated-user-decrypt/{job_id} | Yes | Same GET handler as user-decrypt |
| POST | /v2/input-proof | Yes | No chain ID / ACL validation |
| GET | /v2/input-proof/{job_id} | Yes | accepted: false is 200, not error |
| GET | /v2/keyurl | No | Read-only; waits up to 5s on first call |
| Path | Purpose |
|---|---|
/liveness | Always 200 — for k8s liveness probe |
/healthz | 200/503 — dependency health check |
/version | Build version and git SHA |
/metrics | Prometheus metrics |
| Document | Covers |
|---|---|
| ../openapi.yml | Per-endpoint HTTP codes, labels, revert mapping |
| ID.md | All identifier types and relationships |
| status-transitions.md | Internal request state machine per endpoint |
| dynamic-retry-after-design.md | Retry-After computation formulas and examples |