Compatibility
Anthropic compatibility
Use the Messages API shape.
If your code is written against the Anthropic Messages API, you can keep that shape. Odyssey accepts it on its own path and serves and bills it the same way as a chat completion. It is also what Claude Code uses; see coding agents.
The messages endpoint
https://odysseyapi.tech/v1/messagescurl https://odysseyapi.tech/v1/messages \ -H "Authorization: Bearer $ODYSSEY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "anthropic/claude-sonnet-5", "max_tokens": 512, "system": "You write release notes.", "messages": [ { "role": "user", "content": "Summarise these commits in three bullets." } ] }'{ "id": "req_47b0e2a9c1d85f36ba204e17", "type": "message", "role": "assistant", "model": "anthropic/claude-sonnet-5", "content": [{ "type": "text", "text": "- Routing now prefers..." }], "stop_reason": "end_turn", "usage": { "input_tokens": 412, "output_tokens": 96 }}Using the Anthropic SDK
Point the official SDK at Odyssey and use an Odyssey key. Both Authorization: Bearer and x-api-key are accepted, so the SDK's default header works.
import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ baseURL: "https://odysseyapi.tech/v1", apiKey: process.env.ODYSSEY_API_KEY,}); const message = await client.messages.create({ model: "anthropic/claude-sonnet-5", max_tokens: 512, messages: [{ role: "user", content: "Summarise these commits in three bullets." }],}); console.log(message.content[0].type === "text" ? message.content[0].text : "");What differs
- Model ids are namespaced. Use
anthropic/claude-sonnet-5rather thanclaude-sonnet-5. - Any model works here. The Messages shape is translated for models from other authors, so
openai/gpt-5is a valid model on this endpoint too. anthropic-versionandanthropic-betaare forwarded. Whether a beta feature works depends on the model serving the request./messages/count_tokensis supported and free. The Batches and Files APIs are not.- Errors use Anthropic's shape,
{ "type": "error", "error": { type, message } }, so the SDK's error classes work unchanged.
Pick one shape per service
Both endpoints run the same models and bill the same way, so the choice is about your code. Mixing them inside one service only makes the logs harder to read.
Streaming events
With stream: true, this endpoint emits Anthropic's event names: message_start, content_block_start, content_block_delta, content_block_stop, message_delta and message_stop. The chat completions endpoint uses OpenAI's chunk format instead, described in Streaming.