> ## Documentation Index
> Fetch the complete documentation index at: https://docs.compute.prentis.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Messages

> Anthropic-compatible Messages endpoint. Anthropic SDKs and Claude Code work by changing base_url alone, and x-api-key is accepted alongside Authorization: Bearer. Pass a Prentis model name -- there is no claude-* aliasing.

Anthropic's wire format, served by the same models as everything else here. Anthropic SDKs
and Claude Code work by changing `base_url` alone.

## Two differences from Anthropic's own API

**Model names stay ours.** There is no `claude-*` aliasing — pass a model from
[`GET /models`](/api-reference/list-models). See
[Models and resource names](/models-and-resource-names).

**`max_tokens` is optional.** Anthropic's API requires it; here, omitting it falls back to
the model's own default rather than failing the call.

## Authentication

Both headers work, and they name the same key:

```bash theme={null}
x-api-key: $PRENTIS_API_KEY
# or
Authorization: Bearer $PRENTIS_API_KEY
```

The SDKs append `/v1/messages` themselves, so construct them with the origin:

```python theme={null}
client = anthropic.Anthropic(
    base_url="https://compute.prentis.ai",
    api_key=os.environ["PRENTIS_API_KEY"],
)
```


## OpenAPI

````yaml openapi/prentis.openapi.yaml POST /messages
openapi: 3.1.0
info:
  title: Prentis Inference API
  version: 0.2.0
  summary: One inference API, reachable with an OpenAI client or an Anthropic client.
  description: >
    An OpenAI-compatible inference API. Point any OpenAI SDK at this base URL
    with a

    Prentis key and nothing else in your code changes.


    Anthropic clients are served too: the same host answers `/v1/messages`, and

    `x-api-key` is accepted alongside `Authorization: Bearer`.


    Parameters this API does not implement are ignored rather than rejected,
    except the

    few marked **not supported** below, which return `INVALID_REQUEST` so that a
    silently

    wrong answer is never returned in place of an error.
servers:
  - url: https://compute.prentis.ai/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: chat
  - name: completions
  - name: messages
  - name: models
paths:
  /messages:
    post:
      tags:
        - messages
      summary: Create a message
      description: >-
        Anthropic-compatible Messages endpoint. Anthropic SDKs and Claude Code
        work by changing base_url alone, and x-api-key is accepted alongside
        Authorization: Bearer. Pass a Prentis model name -- there is no claude-*
        aliasing.
      operationId: createMessage
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnthropicMessageRequest'
      responses:
        '200':
          headers:
            x-request-id:
              $ref: '#/components/headers/x-request-id'
            x-provider-class:
              $ref: '#/components/headers/x-provider-class'
            x-config-version:
              $ref: '#/components/headers/x-config-version'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnthropicMessage'
              example:
                id: msg_01K5S8QW6ATE
                type: message
                role: assistant
                model: deepseek-v4.1-flash
                content:
                  - type: text
                    text: >-
                      A distributed store can hold at most two of consistency,
                      availability and partition tolerance at once. Because
                      partitions do happen in practice, the real choice is
                      between answering with stale data and not answering at
                      all.
                stop_reason: end_turn
                stop_sequence: null
                usage:
                  input_tokens: 28
                  output_tokens: 47
                  cache_read_input_tokens: 0
                  cache_creation_input_tokens: 0
            text/event-stream:
              schema:
                type: string
              example: >-
                event: message_start

                data:
                {"type":"message_start","message":{"id":"msg_01K5S8QW6ATE","type":"message","role":"assistant","model":"deepseek-v4.1-flash","content":[],"usage":{"input_tokens":28,"output_tokens":0}}}


                event: content_block_delta

                data:
                {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"A
                distributed store"}}


                event: message_delta

                data:
                {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":47}}


                event: message_stop

                data: {"type":"message_stop"}
          description: >-
            OK. With `stream: true` the same call answers `text/event-stream`
            instead, one chunk per event, terminated by `data: [DONE]`; the last
            data event carries `usage` whether or not you asked for it.
        4XX:
          headers:
            x-request-id:
              $ref: '#/components/headers/x-request-id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnthropicErrorResponse'
          description: OK.
        5XX:
          headers:
            x-request-id:
              $ref: '#/components/headers/x-request-id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnthropicErrorResponse'
          description: OK.
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl https://compute.prentis.ai/v1/messages \
              -H "x-api-key: $PRENTIS_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "model": "deepseek-v4.1-flash",
                "system": "You are a concise assistant.",
                "messages": [
                  {"role": "user", "content": "Summarise the CAP theorem in two sentences."}
                ],
                "max_tokens": 200,
                "temperature": 0.7
              }'
        - lang: python
          label: Python
          source: >-
            import os

            import anthropic


            # The SDK appends /v1/messages itself, so it takes the origin.

            client = anthropic.Anthropic(base_url="https://compute.prentis.ai",
            api_key=os.environ["PRENTIS_API_KEY"])


            msg = client.messages.create(
                model="deepseek-v4.1-flash",
                system="You are a concise assistant.",
                messages=[{"role": "user", "content": "Summarise the CAP theorem in two sentences."}],
                max_tokens=200,
            )

            print(msg.content[0].text)
        - lang: typescript
          label: TypeScript
          source: >-
            import Anthropic from "@anthropic-ai/sdk";


            // The SDK appends /v1/messages itself, so it takes the origin.

            const client = new Anthropic({
              baseURL: "https://compute.prentis.ai",
              apiKey: process.env.PRENTIS_API_KEY,
            });


            const msg = await client.messages.create({
              model: "deepseek-v4.1-flash",
              system: "You are a concise assistant.",
              messages: [{ role: "user", content: "Summarise the CAP theorem in two sentences." }],
              max_tokens: 200,
            });

            console.log(msg.content[0]?.type === "text" ? msg.content[0].text :
            "");
components:
  schemas:
    AnthropicMessageRequest:
      type: object
      required:
        - model
        - messages
      properties:
        model:
          type: string
          description: >-
            Which model answers the call. A bare slug for platform models
            (deepseek-v4.1-flash), or a full resource name for something your
            account owns (accounts/{account}/models/{model}, or a deployment).
            Never an upstream vendor's own name.
        messages:
          type: array
          minItems: 1
          items:
            type: object
            required:
              - role
              - content
            properties:
              role:
                type: string
                enum:
                  - user
                  - assistant
              content:
                oneOf:
                  - type: string
                  - type: array
                    items:
                      type: object
          description: >-
            The conversation so far, oldest first. Only user and assistant turns
            -- the system prompt travels in its own system field. Content is a
            string, or a list of text / image / tool_use / tool_result blocks.
        system:
          oneOf:
            - type: string
            - type: array
              items:
                type: object
          description: >-
            Instructions that sit outside the conversation. Counted as input
            tokens like any other prompt text.
        max_tokens:
          type: integer
          minimum: 1
          description: >-
            Ceiling on how many tokens may be generated. Anthropic's own API
            requires this; here it is optional and falls back to the model's
            default rather than failing the call.
        stream:
          type: boolean
          default: false
          description: >-
            Return the answer as server-sent events as it is generated, instead
            of one response at the end. The last data event carries the usage
            numbers either way.
        stop_sequences:
          type: array
          items:
            type: string
          maxItems: 4
          description: >-
            Up to 4 strings that end generation as soon as the model produces
            one. The matched string is not included in the output.
        temperature:
          type: number
          minimum: 0
          maximum: 2
          description: >-
            How much randomness to allow when picking each token. Lower is more
            repeatable, higher is more varied.
        top_p:
          type: number
          minimum: 0
          maximum: 1
          description: >-
            Nucleus sampling: only consider the most likely tokens up to this
            share of the probability mass. Tune this or temperature, not both.
        top_k:
          type: integer
          description: >-
            Accepted so Anthropic clients do not break, then dropped: it is not
            passed to the model.
        tools:
          type: array
          items:
            type: object
          description: >-
            Tool definitions in Anthropic's shape ({name, description,
            input_schema}). Server-side built-in tools are rejected by name.
        tool_choice:
          type: object
          description: >-
            Whether the model may, must, or must not call a tool: auto, any,
            none, or one named tool.
        metadata:
          type: object
          properties:
            user_id:
              type: string
          description: >-
            Free-form metadata about the call. metadata.user_id is the
            equivalent of the user field on the OpenAI-shaped endpoints.
        thinking:
          type: object
          description: Extended thinking configuration.
        output_config:
          type: object
          description: |-
            Vendor-specific output configuration.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
        raw_output:
          type: object
          description: |-
            Vendor-specific raw output configuration.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
    AnthropicMessage:
      type: object
      required:
        - id
        - type
        - role
        - model
        - content
        - usage
      properties:
        id:
          type: string
        type:
          type: string
          const: message
        role:
          type: string
          const: assistant
        model:
          type: string
        content:
          type: array
          items:
            $ref: '#/components/schemas/AnthropicContentBlock'
        stop_reason:
          type:
            - string
            - 'null'
          enum:
            - end_turn
            - max_tokens
            - stop_sequence
            - tool_use
            - refusal
            - null
        stop_sequence:
          type:
            - string
            - 'null'
        usage:
          $ref: '#/components/schemas/AnthropicUsage'
    AnthropicErrorResponse:
      type: object
      required:
        - type
        - error
      properties:
        type:
          type: string
          const: error
        error:
          type: object
          required:
            - type
            - message
          properties:
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - not_found_error
                - request_too_large
                - rate_limit_error
                - api_error
                - overloaded_error
            message:
              type: string
        code:
          type: string
        param:
          type:
            - string
            - 'null'
        request_id:
          type: string
    AnthropicContentBlock:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - text
            - tool_use
        text:
          type: string
        id:
          type: string
        name:
          type: string
        input:
          type: object
    AnthropicUsage:
      type: object
      required:
        - input_tokens
        - output_tokens
      properties:
        input_tokens:
          type: integer
          minimum: 0
        output_tokens:
          type: integer
          minimum: 0
        cache_read_input_tokens:
          type: integer
          minimum: 0
        cache_creation_input_tokens:
          type: integer
          const: 0
  headers:
    x-request-id:
      schema:
        type: string
      required: true
      description: >-
        On every response, successes and errors alike. It is the handle that
        reaches the whole path your request took -- quote it when you ask us
        anything about a call.
    x-provider-class:
      schema:
        type: string
        enum:
          - primary
          - fallback
      description: >-
        primary or fallback: whether your call was served by the first choice or
        a standby. It never names who served it.
    x-config-version:
      schema:
        type: string
      description: >-
        Which version of the routing configuration was in effect for this call.
        Useful only when comparing two calls that behaved differently.
    Retry-After:
      schema:
        type: integer
        minimum: 0
      description: How many seconds to wait before retrying, on the responses that set it.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        `Authorization: Bearer <your API key>`. On `/v1/messages`, the
        Anthropic-style `x-api-key: <your API key>` header is accepted instead.

````