Skip to content
Get API key
On this page

Messages (Anthropic format)

Call router.africa with the Anthropic SDK or the Messages format. Change one line, keep the rest of your code.

POST /v1/messages (API reference) accepts requests in the Anthropic Messages format. If your code already uses the Anthropic SDK, you change the base URL and the key, and nothing else.

Change one line

Point the client at https://api.router.africa and give it your router.africa key as the usual api_key. The SDK sends it as x-api-key, which this endpoint accepts. The SDK adds /v1/messages itself, so don’t put /v1 in the base URL.

curl https://api.router.africa/v1/messages \
-H "x-api-key: $ROUTER_AFRICA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "anthropic/claude-sonnet-4",
  "max_tokens": 256,
  "messages": [{ "role": "user", "content": "Write a two-line status message for a delayed parcel." }]
}'

Request

Field Notes
model Required. A router.africa model id such as anthropic/claude-sonnet-4. The model must be switched on and allowed for your key.
max_tokens Required. A value above the model’s limit is lowered to the limit.
messages Required. The conversation, as the Anthropic Messages API defines it.
system, temperature, stop_sequences, tools and the other Messages fields Passed through as the model’s API defines them.
stream Set true for server-sent events. See below.

thinking and cache_control are passed through as Anthropic defines them. Reasoning and cached tokens are counted in usage and charged at the published rate. fallbacks and models[] are not supported. See Compatibility notes.

You can send an Idempotency-Key header on this endpoint, as on chat completions.

Response

The response is the Anthropic message object: id, type, role, model, content, stop_reason, stop_sequence and usage. usage has input_tokens and output_tokens, and cache_creation_input_tokens and cache_read_input_tokens when caching is used. The header x-request-id identifies the request. You can look it up with GET /v1/generation.

Stream the response

Set stream: true. The events are the Anthropic ones (message_start, content_block_delta, message_delta, message_stop). The final message_delta event carries the output token count. If you disconnect, you are charged for the tokens used up to that point. See Streaming.

curl -N https://api.router.africa/v1/messages \
-H "x-api-key: $ROUTER_AFRICA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "anthropic/claude-sonnet-4",
  "max_tokens": 256,
  "stream": true,
  "messages": [{ "role": "user", "content": "Write a two-line status message for a delayed parcel." }]
}'

Errors

Unlike every other endpoint, errors on POST /v1/messages use Anthropic’s format, so the Anthropic SDKs parse them as they do Anthropic’s own. error.type is Anthropic’s type, chosen from the HTTP status. error.reason is the specific cause, the same value as metadata.reason on other endpoints. There is no error.code and no metadata. Status codes and headers are the same as everywhere else. See Errors for the reasons.

{
  "type": "error",
  "error": {
    "type": "billing_error",
    "message": "This workspace doesn't have enough credits for this request. Add credits at https://app.router.africa.",
    "reason": "insufficient_credits"
  }
}
Status error.type
400, 409, 413 invalid_request_error
401 authentication_error
402 billing_error
403 permission_error
404 not_found_error
429 rate_limit_error
408, 500, 502, 503 api_error
529 overloaded_error

An error after the stream has started can’t change the 200 status. It arrives as a final error event in the same format, and then the stream ends.

event: error
data: {"type":"error","error":{"type":"overloaded_error","message":"The model provider is overloaded. Retry shortly.","reason":"provider_overloaded"}}