Messages
The main endpoint. Wire-compatible with Anthropic's Messages API, so anything the official SDKs can send, you can send.
https://ai.dijitul.uk/v1/messages
Making a request
curl https://ai.dijitul.uk/v1/messages \
-H "x-api-key: $GATEWAY_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"system": "You are a careful legal assistant. Cite the clause you rely on.",
"messages": [
{"role": "user", "content": "Summarise the termination clause."}
]
}'
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
model |
string | required | A model alias from GET /v1/models. |
messages |
array | required | The conversation. Alternating user and assistant turns. |
max_tokens |
integer | required | Maximum tokens to generate. Counts towards your allowance only if produced. |
system |
string or array | optional | System prompt. Accepts a plain string or an array of text blocks. |
stream |
boolean | optional | Stream the response as server-sent events. |
temperature |
number | optional | 0 to 1. Lower is more deterministic. |
top_p |
number | optional | Nucleus sampling. Prefer temperature or this, not both. |
top_k |
integer | optional | Sample from the top K options. |
stop_sequences |
array | optional | Strings that stop generation. |
tools |
array | optional | Tool definitions the model may call. |
tool_choice |
object | optional | auto, any, or a named tool. |
thinking |
object | optional | Extended thinking configuration, where the model supports it. |
metadata |
object | optional | Passed through. Do not put personal data here — it is not redacted. |
Response
{
"id": "msg_01XyZ...",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4-6",
"content": [{ "type": "text", "text": "The termination clause..." }],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 412,
"output_tokens": 288,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
}
}
model is echoed back as the alias you requested, not the provider's
internal identifier.
Gateway headers
Alongside the standard response, every call carries headers describing how it was
handled. x-gateway-regions in particular means your own logs can
evidence where each request was processed, rather than relying on a claim on our
website.
x-request-id: req_01k9m2p7...
x-gateway-residency: uk
x-gateway-regions: eu-west-2
x-gateway-model: claude-sonnet-4-6
x-gateway-privacy-mode: tokenise
x-gateway-pii-detected: 3
Streaming
Set stream: true, or use your SDK's streaming helper.
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Explain UK GDPR Article 28."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
The wire format is Anthropic's, unchanged:
event: message_start
data: {"type":"message_start","message":{"id":"msg_01...","model":"claude-sonnet-4-6","usage":{"input_tokens":412,"output_tokens":0}}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Article 28 "}}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":288}}
event: message_stop
data: {"type":"message_stop"}
Under tokenise, redacted values are restored as the stream passes through
us, including when a token spans several chunks.
Tool use
{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"tools": [{
"name": "lookup_matter",
"description": "Fetch a matter by its reference.",
"input_schema": {
"type": "object",
"properties": { "reference": { "type": "string" } },
"required": ["reference"]
}
}],
"messages": [{ "role": "user", "content": "What is the status of matter 24/1180?" }]
}
Tool definitions are treated as developer-authored schema and are not scanned for personal data. Tool inputs the model produces are, so a value the model copies out of a redacted prompt is restored before it reaches you.
Images
Base64 image blocks are supported on every model in the catalogue and pass through untouched. Note that PII detection does not read images — a scanned document is forwarded as pixels, so treat image content as unredacted.
Counting tokens
https://ai.dijitul.uk/v1/messages/count_tokens
Free, not metered, and not rate limited. Useful for cost estimation before sending.
curl https://ai.dijitul.uk/v1/messages/count_tokens \
-H "x-api-key: $GATEWAY_API_KEY" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-4-6","messages":[{"role":"user","content":"How long is this?"}]}'
The count reflects the request after redaction, so it matches what you will actually be billed for.