Gateway proxy
Data plane proxy path, auth, billing meta, idempotency, and limits.
View as Markdown →Base URL: https://gateway.ozma.app
The gateway is Ozma's data plane. It authenticates API keys, enforces spend governance, injects upstream credentials, meters usage, and returns envelope-wrapped upstream responses.
Proxy path
ALL /v1/proxy/:apiSlug/<upstream-path>
Authorization: Bearer ozma_live_…
Examples:
# Frankfurter (free platform API)
curl -H "Authorization: Bearer $OZMA_API_KEY" \
"https://gateway.ozma.app/v1/proxy/frankfurter/latest?from=USD&to=EUR"
# httpbin.org GET echo
curl -H "Authorization: Bearer $OZMA_API_KEY" \
"https://gateway.ozma.app/v1/proxy/httpbin-org/get"
Resolve proxy paths and methods from GET /v1/apis/:slug/schema or ozma inspect <slug> --schema.
Authentication
| Credential | Accepted |
|---|---|
API key ozma_live_… with proxy:call |
Yes |
Session token sess_… |
No — 401 |
| Missing auth (dev only) | Keyless auto-register → 0 credits |
Malformed Bearer tokens return 401 unauthenticated.
Response envelope
Success:
{
"ok": true,
"data": { "amount": 1.08, "base": "USD", "date": "2026-07-22" },
"meta": {
"request_id": "req_01…",
"cost_cents": 0,
"price_cents_effective": 0,
"credit_applied_cents": 0,
"billable_cents": 0
}
}
Paid calls populate cost_cents, price_cents_effective, credit_applied_cents, and billable_cents. Scheduled price increases and active discounts appear as price_increase / discount objects in meta.
Failure uses the standard error envelope with the same request_id.
Idempotency headers
Send on mutating or retried calls:
Idempotency-Key: my-unique-key-123
Also accepted: X-Idempotency-Key.
When a prior successful usage event exists for the same org + key + idempotency key, the gateway returns:
meta.replayed: truemeta.original_request_idwhen available- Original billing fields
data: null(response bodies are not stored)
Duplicate in-flight races resolve to the first success without double billing.
Note: @ozma_app/sdk proxyCall and ozma call do not expose idempotency flags today. Use raw HTTP or extend your client to set the header.
Self-dealing
Proxy calls where consumer org equals provider org return 403 forbidden. Use a separate org for testing your own published API.
Body and response limits
Oversized request bodies return 413 with validation_failed. Upstream responses exceeding the size cap return 502 upstream_error. Failed upstream calls are not billed; spend reservations are refunded.
Required provider terms (428)
When a live API has active provider terms with acceptance_mode: required, the gateway returns 428 terms_acceptance_required before spend or upstream call. Details include approval_url, snapshot_url, document_id, and content_hash.
Accept via control plane session: POST /v1/apis/:slug/terms/accept or ozma terms accept <slug> --yes.
Rate limits
Default ~300 requests per minute per key prefix (GATEWAY_RATE_LIMIT_PER_MIN). Excess returns 429 rate_limited.
Signup abuse limits apply separately on auto-register paths.
Spend governance (402)
Enforced synchronously via SpendCounter Durable Object before upstream call:
| Code | Trigger |
|---|---|
per_call_limit_exceeded |
Price > per_call_max_cents |
insufficient_budget |
Would exceed lifetime budget_cents |
daily_cap_exceeded |
Would exceed daily_cap_cents (UTC day) |
See Keys & budgets.
Other gateway errors
| HTTP | Code | When |
|---|---|---|
| 404 | not_found |
Unknown slug or endpoint path |
| 402 | payment_required |
Suspended org or prepaid credits exhausted |
| 429 | upstream_rate_limited |
Upstream returned 429 |
| 502 | upstream_error |
Upstream non-success (except 429) |
| 503 | internal_error |
SpendCounter unavailable |
- REST API — catalog and control plane
- Errors — full code table
- First API call example