Skip to main content

Messages

The main endpoint. Wire-compatible with Anthropic's Messages API, so anything the official SDKs can send, you can send.

POST 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

POST 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.