Cookbook
Chat completion with curl
The smallest end-to-end call against ezrouter's OpenAI-compatible surface. Run this from any shell with curl installed.
curl https://www.ezrouter.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${EZROUTER_API_KEY}" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
]
}'Set EZROUTER_API_KEY to a key from the dashboard before running. The response streams as Server-Sent Events even though stream was not set in the body — see divergences.
Reading the SSE stream
curl prints the SSE frames directly. Each frame looks like:
data: {"id":"msg_01...","object":"chat.completion.chunk","choices":[{"delta":{"content":"Hi"}}]}The terminator is data: [DONE]. To consume the stream programmatically, parse each data: {...} line as JSON; if a line equals data: [DONE], stop. To collect the final response into one JSON object, add --no-buffer and pipe through a small filter:
curl --no-buffer -sS https://www.ezrouter.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${EZROUTER_API_KEY}" \
-d '{ "model": "claude-sonnet-4-6", "messages": [
{"role": "user", "content": "Hello"} ]}' \
| grep --line-buffered '^data: ' \
| grep --line-buffered -v '^data: \[DONE\]' \
| sed 's/^data: //' \
| jq -s 'map(.choices[0].delta.content // "") | join("")'That prints the assembled assistant message as a single JSON string.
Common variations
Switch the model. Pass any ID from GET /v1/models:
-d '{ "model": "deepseek-v4-pro", "messages": [...] }'Cap output length.
-d '{ "model": "claude-haiku-4-5", "max_tokens": 256, "messages": [...] }'Send a system prompt. The first message with role: "system".
Multi-turn conversation. Append every prior turn to messages:
-d '{
"model": "claude-sonnet-4-6",
"messages": [
{"role": "user", "content": "What is 2+2?"},
{"role": "assistant", "content": "4."},
{"role": "user", "content": "And 3+3?"}
]
}'See multi-round chat for the full pattern.
Error handling
A non-200 response carries a JSON error envelope, not an SSE stream:
{"error": {"code": "invalid_api_key", "message": "Invalid API key.", "type": "authentication_error"}}The typed values you may see are documented in error codes. Do not write retry-on-429 logic — the gateway does not return 429; under load it queues silently and you see longer latency instead.
Next steps
- Python example — same call from
openaiSDK. - Node.js example — same call from
openaiNode SDK. - API reference —
every parameter explained.