# EchoRelay > A managed runtime for custom API integrations. Stop maintaining the adapter, its retries and its credentials. For teams connecting partner, vendor and customer APIs without an integration team. EchoRelay is the target your callers hit and the source that calls your services. A caller makes one authenticated request to its EchoRelay endpoint; EchoRelay authenticates, validates, rate-limits, bills, and delivers it to one or more downstream HTTP targets — fanning out, returning a target's response inline, or streaming it back. Queued delivery is at-least-once, retried automatically, with a dead-letter queue; synchronous and streaming targets answer on the caller's own connection and are not retried. Use EchoRelay to decouple a caller from its downstream targets. Each target has a **delivery mode**: `async` (queued and fanned out — accepted immediately with `HTTP 202`, delivered asynchronously, the default), `sync` (we call the target inline and return its response to the caller, capped 1–90 s, no retries), or `stream` (we forward a target's SSE / chunked response back chunk by chunk). These compose into three topologies: fan-out, streaming proxy, and origin shield / ingestion. ## Integration - [Full integration guide](https://docs.echorelay.dev/llms-full.txt): complete reference — endpoint URL, authentication, request and response formats, error codes, fan-out, delivery guarantees, and worked examples. - [Delivery modes & topologies](https://docs.echorelay.dev/delivery-modes): the three delivery modes and the three topologies you can build from them. - [Mapping](https://docs.echorelay.dev/mapping): reshape a request into what a target expects, and reshape a synchronous target's answer back — outgoingMapping, answerMapping, and answer variants for a vendor that replies in more than one shape. - [Docs site](https://docs.echorelay.dev): MCP, REST, API key lifecycle. - [REST API reference](https://docs.echorelay.dev/rest) — programmatic project management at `api.echorelay.dev`. - [MCP guide](https://docs.echorelay.dev/mcp) — connect Claude / Cursor / any MCP client. - [Recipes for AI agents](https://echorelay.dev/ai) — build from samples, debug a failed delivery, triage the DLQ, change a field, rotate a key, check the bill: the MCP tool calls for each and where a person approves. Send `Accept: text/markdown` for the markdown version. ## Quick reference (data plane) - **Endpoint URL:** `https://{tenant}.echorelay.cloud/{line}/{endpoint}` - **Auth:** `Authorization: Bearer ` header (project-level keys — one key works on every endpoint in the project) - **Key modes:** `live` keys debit paid credits; `test` keys debit a separate testing pool at no more than your live rate or the shared self-serve testing ceiling (Enterprise has a separate default). Test credits are a paid perk included with credit packs and Pro/Scale; Free has no test pool, so relay on the live key. - **Delivery modes (per target):** `async` (queued/fan-out → `202`), `sync` (target's response returned inline), `stream` (SSE/chunked forwarded back) - **Dead-letter queue (DLQ):** async deliveries that can't be completed land here with the original request body and headers, kept for up to 30 days or until you clear them — never written to a database, never inspected. Inspect/replay/discard via the panel or `list_dlq` / `retry_dlq_entry` / `discard_dlq_entry`. - **Success:** `202` with `{"status":"queued", ...}` for `async`; for a `sync`/`stream` target, the target's own response and status (usually `200`) - **Grace:** within 24h of `expiresAt`, requests still succeed and add `X-Echorelay-Key-Status: expired_grace` - **File storage:** stored-file (`binaryToUrl`) deliveries draw from a per-project pool — 1 GB on Free/Prepaid, 5 GB on Pro/Scale, unlimited on Enterprise; up to 100 MB per file. Buy more in +5 GB blocks (stackable; each raises every project's pool) from the panel under Billing → Add-ons (see /pricing for current pricing). - **Mapping:** a target can reshape its outgoing request (`outgoingMapping`, every delivery mode) and, on a `sync` target only, reshape the answer it gets back (`answerMapping`, or `answerVariants` when the same target answers in more than one shape — picked by the status, one header, or one body field). A mapping that fails against real traffic is also `422`, but its own `error` code (`outgoing_mapping_evaluation_failed` / `answer_mapping_evaluation_failed` / `answer_no_variant_matched`) comes with a `targets` array naming which target and which nodes failed — more than the flat `validation_failed` below gives. `dry_run_endpoint` previews one against a sample before it's live. Full reference: /mapping. - **Errors:** `401` auth failed (`invalid_or_missing_key`/`key_revoked`/`key_expired` — uniform whether or not the tenant exists, so it never reveals tenant existence) · `402` test pool empty (`testing_credits_exhausted`) — **live** traffic is throttled to the free rate when credits run out, never `402` ·`403 ip_not_allowed` · `404 line_not_found`/`endpoint_not_found` (authenticated callers only) · `422 validation_failed` · `429` rate-limited · `507 storage_pool_exhausted` (file-storage pool full — only the stored-file upload is blocked; buy more or wait for TTL) ## Errors & remediation Every rejection names a machine-readable `error` and the one action that clears it. Over MCP, the named tool *is* the fix — each error points at the tool to call. | Status | `error` | Cause | Fix | |---|---|---|---| | `402` | `testing_credits_exhausted` | Testing pool is empty (a paid perk — the free tier has none) | buy a credit pack or `change_plan` to Pro/Scale (each tops up the test pool); free tier → use your live key | **Live**-credit exhaustion is **not** an error — a live key never returns `402`. When your live balance hits zero the project is throttled to its free-tier rate and keeps relaying; a top-up restores your full rate (a top-up within the short grace window keeps you at full speed, uninterrupted). Use `get_billing` to see your balance and tier. | `429` | `rate_limit_exceeded` | Over your steady RPM. The body carries `limit`, `tier`, `retryAfterSeconds` and the response sets a `Retry-After` header | wait `Retry-After`, then raise steady RPM: `change_plan` or `subscribe_addon rpm_*` (monthly add-on subscription; free tier → upgrade with `change_plan`) | | `401` | `invalid_or_missing_key` / `key_revoked` / `key_expired` | Authentication failed — no key, a wrong key, a revoked key, a key past its 24h grace, **or** an unknown tenant. Returned **uniformly** (byte-identical) in all cases, so a `401` never reveals whether a tenant exists. | present a valid key for the project; mint/rotate with `create_api_key` / `rotate_api_key`; inspect `get_key_policy` / `reveal_rotation_successor` | | `403` | `ip_not_allowed` | Authenticated, but your IP isn't in the endpoint's allowlist | add your egress IP to the endpoint's allowlist (`update_endpoint`) | | `404` | `line_not_found` / `endpoint_not_found` | Authenticated, but no such line/endpoint (routing only — auth already passed, so this never leaks existence to a probe) | `get_config` / `list_endpoints` to check routing; confirm the line version + path + method | | `422` | `validation_failed` | Authenticated, but the body failed the endpoint's attribute validation | `dry_run_endpoint` to see which attributes failed; `get_request` for why one specific past request was rejected | `get_billing` is the state oracle: current tier, live RPM (plus the free-tier decay countdown), and every credit pool in one call — check it first when a `402` or `429` is unexpected. ## Quick reference (management) - **REST:** `https://api.echorelay.dev` — Bearer-authed JSON, project implicit from token - **MCP:** `https://mcp.echorelay.dev` — JSON-RPC, same management operations as REST (OpenAPI export is REST-only; OpenAPI **import** is panel-only — REST/MCP return a documented `web_only` error, so build endpoints with `create_endpoint`). An MCP client that supports sign-in needs only this URL: you approve the project in your browser, and no token is copied. Creating an account or paying for a plan still needs a management token. - **Panel:** `https://app.echorelay.dev` — human-facing customer panel ## Abuse reporting Third parties (network operators, blocklist services, hosting providers) who believe EchoRelay is being used in violation of the acceptable-use policy can report to `trust@echorelay.dev`. No account is required. See `https://echorelay.dev/abuse` for what to include.