Echo developer platform
Build with Echo
A focused, OpenAI-compatible API for text, function tools, Chat Completions, and stateless Responses. Change your base URL, set the model to echo, and let your own harness execute tools.
- Base URL
https://echo.tracerml.ai- API base
https://echo.tracerml.ai/v1- Model
echo- Format
- JSON or SSE
Echo supports text, optional function tools, and optional streaming over Chat Completions and a stateless Responses bridge. Responses clients must resend full history and omit previous_response_id. Multimodal content and other OpenAI API surfaces are not part of this contract.
Access
Authentication
Send an Echo API key as a bearer token on every request. Create a key from the API keys page; the complete secret is shown only once.
Authorization: Bearer ECHO_API_KEY
Keep it server-side
Load keys from a secret manager or environment variable. Never ship them in browser or mobile client code.
Rotate deliberately
Create a replacement, deploy it, verify a request, then revoke the old key from your account.
First request
Chat completions quickstart
These examples call the same text completion endpoint. SDK examples disable automatic retries so your application can handle failures and idempotency intentionally.
curl --fail-with-body --silent --show-error \
https://echo.tracerml.ai/v1/chat/completions \
-H "Authorization: Bearer ${ECHO_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "echo",
"messages": [
{"role": "user", "content": "Explain recursion in one sentence."}
],
"max_tokens": 128
}'
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ECHO_API_KEY"],
base_url="https://echo.tracerml.ai/v1",
timeout=600.0,
max_retries=0,
)
completion = client.chat.completions.create(
model="echo",
messages=[
{"role": "user", "content": "Explain recursion in one sentence."}
],
max_tokens=128,
)
print(completion.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.ECHO_API_KEY,
baseURL: "https://echo.tracerml.ai/v1",
timeout: 600_000,
maxRetries: 0,
});
const completion = await client.chat.completions.create({
model: "echo",
messages: [
{ role: "user", content: "Explain recursion in one sentence." },
],
max_tokens: 128,
});
console.log(completion.choices[0].message.content);
Bring your own runtime
Agent harness integrations
Supply Echo as the model endpoint inside a user-run harness. Your harness owns the repository, shell, files, browser, and tool execution while Echo supplies the intelligence through one OpenAI-compatible endpoint. Every direct integration uses API base https://echo.tracerml.ai/v1, public wire model echo, and a secret supplied through ECHO_API_KEY.
OpenCode: recommended setup
OpenCode selects echo/echo locally, while the HTTP model remains exactly echo. Back up the active opencode.json, preserve unrelated settings, and merge this block.
{
"$schema": "https://opencode.ai/config.json",
"model": "echo/echo",
"provider": {
"echo": {
"npm": "@ai-sdk/openai-compatible",
"name": "Echo",
"options": {
"baseURL": "https://echo.tracerml.ai/v1",
"apiKey": "{env:ECHO_API_KEY}"
},
"models": {"echo": {"name": "Echo"}}
}
}
}
Supply the real key through the user's secret manager. The value below is a placeholder. Confirm the config resolves the harness-local selector.
export ECHO_API_KEY='<your-echo-api-key>'
opencode models echo
Verify the standard Chat Completions streaming path with this API smoke test.
curl --fail-with-body --no-buffer \
https://echo.tracerml.ai/v1/chat/completions \
-H "Authorization: Bearer ${ECHO_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "echo",
"messages": [{"role": "user", "content": "Reply with one short sentence."}],
"stream": true,
"stream_options": {"include_usage": true},
"parallel_tool_calls": false
}'
Copy to your coding agent
Configure this OpenCode installation to use Echo as its model endpoint. Back up the active `opencode.json`, then merge a custom `@ai-sdk/openai-compatible` provider named `echo` with `baseURL` `https://echo.tracerml.ai/v1`, `apiKey` `{env:ECHO_API_KEY}`, model map `echo`, and selector `echo/echo`, without deleting unrelated settings. Keep the credential only in `ECHO_API_KEY` and never read, print, log, or write its value. Confirm `opencode models echo` resolves `echo/echo` and that HTTP requests send model `echo` to `/v1/chat/completions`. Preserve native function tools, assistant tool calls, matching tool results, and complete conversation history across turns. Use `parallel_tool_calls=false`. Then run this task in a disposable repository: "Inspect this scratch repository, implement one small multi-file feature using native file and shell tools, run the repository's tests, repair any failure, and report the files changed and test results. Never read or print environment variables or secrets." OpenCode executes the tools; Echo is the model endpoint. If a request fails, report its HTTP status, public error code, and `X-Tracer-Request-ID`; do not switch model IDs.
| Symptom | What to check |
|---|---|
401 unauthorized | Confirm ECHO_API_KEY is present in OpenCode's process and active. Never print it. |
404 model_not_found | Select echo/echo and confirm the HTTP model is exactly echo. |
echo/echo is absent | Validate the JSON, provider key echo, package, and baseURL. |
| Wrong tool-call shape | Use OpenAI function tools, send parallel_tool_calls=false, preserve assistant tool_calls, and append the matching tool result. |
Early EOF, timeout, 429, or 503 | Use a multi-minute read timeout, honor Retry-After or bounded backoff, and retain X-Tracer-Request-ID. |
Use the configuration matching your harness below. In every case, keep the API key in the environment and send the public model ID echo.
| Priority | Harness | Exact harness-side configuration | Wire | Integration / source |
|---|---|---|---|---|
| P0 | OpenCodeopencode | baseURL=https://echo.tracerml.ai/v1; apiKey={env:ECHO_API_KEY}; selector echo/echo → wire model echo; @ai-sdk/openai-compatible | Chat + SSE | Recommended · source |
| P0 | Codex CLIcodex | User config: base_url=https://echo.tracerml.ai/v1; env_key=ECHO_API_KEY; model/provider echo; wire_api=responses | Responses | Responses configuration · source |
| P0 | Clinecline | OpenAI Compatible; base URL https://echo.tracerml.ai/v1; key from ECHO_API_KEY; model echo | Chat | OpenAI-compatible · source |
| P0 | Roo Coderoo-code | OpenAI Compatible; base URL https://echo.tracerml.ai/v1; key from ECHO_API_KEY; model echo | Chat | OpenAI-compatible · source |
| P0 | Continuecontinue | provider=openai; apiBase=https://echo.tracerml.ai/v1; secret ECHO_API_KEY; model echo; useResponsesApi=true; tool_use | Responses | Responses configuration · source |
| P0 | Goosegoose | GOOSE_PROVIDER=openai; GOOSE_MODEL=echo; root OPENAI_HOST=https://echo.tracerml.ai; OPENAI_BASE_PATH=v1/chat/completions; export OPENAI_API_KEY="${ECHO_API_KEY}" | Chat | OpenAI-compatible · source |
| P0 | SWE-agentswe-agent | Model openai/echo; agent.model.api_base=https://echo.tracerml.ai/v1; literal env reference agent.model.api_key=$ECHO_API_KEY; unknown-model limits per_instance_cost_limit=0, total_cost_limit=0, per_instance_call_limit=100, max_input_tokens=0, max_output_tokens=0 | Chat | OpenAI-compatible · source |
| P1 | Aideraider | OPENAI_API_BASE=https://echo.tracerml.ai/v1; export OPENAI_API_KEY="${ECHO_API_KEY}"; run aider --model openai/echo; validate the selected edit format, inspect the applied diff, and retain the exact test command, exit status, and output | Chat | OpenAI-compatible · source |
| P1 | OpenHandsopenhands | export LLM_MODEL="openai/echo"; export LLM_BASE_URL="https://echo.tracerml.ai/v1"; export LLM_API_KEY="${ECHO_API_KEY}" | Chat | OpenAI-compatible · source |
| P1 | Open Interpreteropen-interpreter | from interpreter import interpreter; set model openai/echo, api_base=https://echo.tracerml.ai/v1, key from os.environ["ECHO_API_KEY"], and interpreter.llm.supports_functions=True | Chat | OpenAI-compatible · source |
| P1 | Hermes Agenthermes-agent | In ~/.hermes/config.yaml, set model.default=echo, model.provider=custom, model.base_url=https://echo.tracerml.ai/v1, and model.api_mode=codex_responses; before launch, set the key in the shell with export OPENAI_API_KEY="${ECHO_API_KEY}", never in YAML | Responses | Responses configuration · source |
| P1 | OpenClawopenclaw | Provider echo: baseUrl=https://echo.tracerml.ai/v1; apiKey=${ECHO_API_KEY}; api=openai-responses; model ID echo; select it with agents.defaults.model.primary=echo/echo | Responses | Responses configuration · source |
| P2 | smolagentssmolagents | OpenAIModel(model_id="echo", api_base="https://echo.tracerml.ai/v1", api_key=os.environ["ECHO_API_KEY"]) | Chat | OpenAI-compatible · source |
| P2 | LangChain / LangGraphlangchain-langgraph | ChatOpenAI(model="echo", base_url="https://echo.tracerml.ai/v1", api_key=os.environ["ECHO_API_KEY"], use_responses_api=True) | Responses | Responses configuration · source |
| P2 | CrewAIcrewai | LLM(model="openai/echo", base_url="https://echo.tracerml.ai/v1", api_key=os.environ["ECHO_API_KEY"]) | Chat | OpenAI-compatible · source |
| P2 | AutoGenautogen | OpenAIChatCompletionClient: model echo; base URL https://echo.tracerml.ai/v1; key from ECHO_API_KEY; declare vision=False, function_calling=True, json_output=False, family="unknown", and structured_output=False | Chat | OpenAI-compatible · source |
| P2 | PydanticAIpydantic-ai | OpenAIProvider(base_url="https://echo.tracerml.ai/v1", api_key=os.environ["ECHO_API_KEY"]) with OpenAIResponsesModel("echo") | Responses | Responses configuration · source |
| Adapter | Claude Codeclaude-code | Claude Code requires an Anthropic-compatible adapter implementing POST /v1/messages and POST /v1/messages/count_tokens, anthropic-version, anthropic-beta, Messages, tool_use/tool_result, streaming events, stop reasons, and usage. | Anthropic adapter | Adapter required · source |
Harness releases may rename configuration fields, so confirm them against the linked version documentation. For Responses integrations, resend the complete transcript on every turn and omit previous_response_id. Claude Code uses an Anthropic-compatible adapter rather than the direct OpenAI-compatible endpoint.
Use this stateless Responses smoke test for Continue, Hermes Agent, OpenClaw, LangChain/LangGraph, PydanticAI, and Codex CLI. The input array is the complete request history, store is false, and previous_response_id is deliberately absent.
curl --fail-with-body --silent --show-error \
https://echo.tracerml.ai/v1/responses \
-H "Authorization: Bearer ${ECHO_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "echo",
"input": [
{
"type": "message",
"role": "user",
"content": [
{"type": "input_text", "text": "Call echo_fixture exactly once."}
]
}
],
"store": false,
"tools": [
{
"type": "function",
"name": "echo_fixture",
"description": "Return a fixed local fixture.",
"parameters": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"strict": false
}
],
"tool_choice": {"type": "function", "name": "echo_fixture"},
"parallel_tool_calls": false,
"stream": false
}'
Adaptive intelligence
Pricing
Use one model ID and one endpoint. Echo automatically assigns the intelligence level required by each request; you do not select a mode.
Quick
Immediate answers and lightweight tasks.
- Input
- $3 / 1M
- Output
- $15 / 1M
Focused
Standard production work requiring more depth.
- Input
- $6 / 1M
- Output
- $30 / 1M
Deep
Complex, multi-step reasoning and demanding tasks.
- Input
- $10 / 1M
- Output
- $50 / 1M
(input tokens × input rate + output tokens × output rate) / 1,000,000Charges are deducted from the organization associated with the API key. View the selected organization balance and purchase credit from Billing.
Current alpha rate card, effective July 15, 2026. Prices are in USD per one million metered tokens.
Contract
Request format
Send a JSON object with a non-empty message history containing at least one user message. Conversations are stateless; include the history needed for each request.
| Field | Type | Behavior |
|---|---|---|
model | string | Use echo. The HTTP default is echo, but SDK clients should set it explicitly. |
messages | array | Required. Roles: system, developer, user, assistant, and tool. Content must be text; assistant tool calls and matching tool results may be included for a round trip. |
temperature | number | Optional, from 0 through 2. Defaults to 0. |
max_tokens | integer | Optional output ceiling. Defaults to 2048; larger client ceilings are normalized to Echo's provider-safe allowance of 65,536. max_completion_tokens is accepted as an alias. |
stream | boolean | Optional. Defaults to false; use true for SSE. |
tools | array | Optional OpenAI function-tool definitions. Custom tool types are rejected. |
tool_choice | string or object | Optional: auto, none, required, or one declared function. |
parallel_tool_calls | boolean | Optional. Defaults to true. |
n | integer | Only 1 is supported. |
reasoning_effort | string | Optional: auto, none, low, medium, high, default, or full. |
Only function tools are supported. Legacy functions and function_call fields, custom tools, images, and audio return an error.
Output
Response and usage
A successful non-streaming request returns one assistant message. Read a text answer from choices[0].message.content. A function request instead returns message.tool_calls and finish_reason: "tool_calls". Retain the X-Tracer-Request-ID response header for support.
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1780000000,
"model": "echo",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "Recursion solves a problem by reducing it to smaller instances of itself."
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 14,
"total_tokens": 32
}
}
Usage and cost fields
The standard usage object reports prompt, completion, and total tokens. It does not include a cost field, and token counts should not be treated as an invoice calculation.
For raw streaming clients, the optional X-Tracer-Progress: 1 header can add a tracer.usage event after a successful completion. Its usage payload may include:
echo_estimated_cost_usdEstimated Echo request cost in USD.echo_cost_statusInformational estimation or metering status.frontier_estimated_cost_low_usdGPT-5.6 Sol standard-list estimate for the same visible input and output.frontier_estimated_cost_high_usdClaude Fable 5 standard-list estimate for the same visible input and output.fable_estimated_cost_usdLegacy-compatible high end of the frontier comparison range.fable_to_echo_ratioLegacy-compatible high-end comparison divided by the Echo estimate, or null.comparison_basisThe visible input history and output used for comparison.invoice_reconciledfalse; the event is not an invoice.Cost events are optional. Use the account dashboard as the source for usage and billing records.
Incremental output
Streaming SSE
Set stream: true. Echo responds with text/event-stream; append content deltas or accumulate indexed delta.tool_calls fields in order, then stop when you receive data: [DONE].
X-Tracer-Stream-Mode is native for screened provider deltas and buffered when generation or full-response screening completed before presentation chunks were released. Buffered responses can include a non-sensitive X-Tracer-Stream-Fallback reason. Parse both modes identically.
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"echo","choices":[{"index":0,"delta":{"role":"assistant","content":"One"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"echo","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
Network chunks do not map one-to-one to SSE events. Buffer until a blank-line delimiter.
Join data: lines and ignore comment lines beginning with :.
An error may arrive after HTTP 200. Treat an event with an error member as failure.
X-Tracer-Progress: 1 opts raw SSE clients into coarse tracer.progress, keep-alive comments, and an optional tracer.usage event. Do not enable it with an OpenAI SDK stream parser.
Failures
Errors
Application errors normally use an OpenAI-shaped error envelope. Framework validation failures, including malformed JSON or a missing body, may use a different 422 response shape.
{
"error": {
"message": "messages must be a non-empty array",
"type": "invalid_request_error",
"param": "messages",
"code": "invalid_request"
}
}
400Invalid requestFix the request; do not retry it unchanged.
401Authentication failedThe API key is missing, malformed, or unknown.
402Billing limitResolve the account credit or spend limit before retrying.
403Access forbiddenThe key, model, scope, API access, or tenant policy forbids the request.
404Model not foundSet the model to echo.
409Idempotency conflictInspect the error code before deciding whether to issue a new request.
413Payload too largeThe request body exceeded the deployment limit.
422Body validation failedThe HTTP body could not be validated as a JSON object.
428Terms requiredAccept the current legal terms in your Echo account.
429Limit reachedHonor Retry-After when present, then retry with backoff and jitter.
503Temporarily unavailableRetry cautiously with exponential backoff and a small attempt cap.
Admission
Rate limits
Echo enforces request-rate limits and may apply account-specific concurrency and daily request limits. Limits are attributed to the tenant associated with the API key and can vary by deployment or account.
- On
429, honor theRetry-Afterresponse header when present. - Otherwise use exponential backoff with jitter and a bounded retry count.
- Do not retry validation, authentication, billing, or policy failures unchanged.
- Monitor status, latency, interrupted streams, and
X-Tracer-Request-ID.
Production
Security
Protect credentials
Store keys in a server-side secret manager. Redact authorization headers from logs and rotate after suspected exposure.
Proxy browser traffic
Echo does not expose a direct-browser CORS contract. Authenticate your own server proxy and have it add the key.
Minimize sensitive data
Do not place secrets or personal data in prompts, idempotency keys, or correlation headers unless required.
Render output safely
Apply encoding, validation, and content controls appropriate to the destination where model text is rendered.
Production checklist
Use the expected HTTPS origin
Validate configured base URLs against https://echo.tracerml.ai, cap user-supplied message sizes before forwarding, and retain request IDs without storing credentials or prompt text in operational logs.