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

# Create message (/api/v1)

> The Anthropic Messages API on the OpenRouter-compatible /api/v1 base. The same handler as POST /v1/messages, Anthropic’s error envelope included; `fallbacks` takes up to 3 models.


## OpenAPI

```yaml openapi.json post /api/v1/messages
openapi: 3.1.0
info:
  title: Ocean One API
  version: 2.4.1
servers:
  - url: https://api.plungeai.com
paths:
  /api/v1/messages:
    post:
      operationId: post-api-v1-messages
      tags:
        - Compat
      summary: "Anthropic Messages (proxied to inference-gateway): the Anthropic wire on the chat-completions money path — routing, models[]/sort failover, guardrails, reserve and settle. Any model; anthropic/* gets the request body as sent, every other model a translation. The anthropic-beta header is not forwarded."
      security:
        - anthropicApiKey: []
        - ozkBearer: []
        - skOcean: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnthropicMessagesRequest"
      responses:
        "200":
          description: "An Anthropic message (model = the slug that actually served it). x-request-id and the x-ocean-* headers are kept. stream:true returns text/event-stream: message_start, then per block content_block_start / content_block_delta (text_delta, input_json_delta) / content_block_stop, then message_delta (stop_reason and usage) and message_stop; ping is the keepalive, and a failure after the 200 ends the stream with an error event."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicMessage"
            text/event-stream:
              schema:
                type: string
        "400":
          description: invalid_request_error — invalid_json (body is not valid JSON), messages required, a role other than user/assistant, more than 3 fallbacks, or unsupported_service_tier
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
        "401":
          description: "authentication_error — invalid_api_key: no x-api-key or Authorization: Bearer header, or not a valid key"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
        "402":
          description: billing_error — insufficient_balance (the wallet does not cover the request) or byok_required
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
        "403":
          description: permission_error — model_not_allowed (allow-list), content_blocked (guardrail) or an inactive account
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
        "404":
          description: not_found_error — model_not_found or preset_not_found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
        "405":
          description: "method_not_allowed — the path serves one method: the Allow header names it, plus OPTIONS"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompatError"
          headers:
            Allow:
              description: The method this path serves, plus OPTIONS
              schema:
                type: string
        "429":
          description: rate_limit_error — rate_limit_exceeded, spend_cap_exceeded or insufficient_quota
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
        "502":
          description: api_error — every routing candidate failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AnthropicError"
components:
  schemas:
    AnthropicContentBlock:
      type: object
      description: One Anthropic content block; fields by type.
      properties:
        type:
          type: string
          example: text
        text:
          type: string
        source:
          type: object
          properties:
            type:
              type: string
              enum:
                - base64
                - url
            media_type:
              type: string
            data:
              type: string
            url:
              type: string
        id:
          type: string
        name:
          type: string
        input:
          type: object
        tool_use_id:
          type: string
        content:
          description: "tool_result only: a string or an array of text blocks"
          oneOf:
            - type: string
            - type: array
              items:
                type: object
        is_error:
          type: boolean
        cache_control:
          type: object
      required:
        - type
      additionalProperties: true
    AnthropicError:
      type: object
      description: "Anthropic's error envelope, worn by every POST /v1/messages and /api/v1/messages error the inference gateway answers. error.type follows the HTTP status: 400 invalid_request_error, 401 authentication_error, 402 billing_error, 403 permission_error, 404 not_found_error, 413 request_too_large, 429 rate_limit_error, 504 timeout_error, 529 overloaded_error, any other api_error."
      properties:
        type:
          type: string
          enum:
            - error
        error:
          type: object
          properties:
            type:
              type: string
              example: authentication_error
            message:
              type: string
          required:
            - type
            - message
        request_id:
          type: string
          description: Equals the x-request-id header
      required:
        - type
        - error
    AnthropicMessage:
      type: object
      description: "The Anthropic message the gateway builds from the served completion, for every model (anthropic/* included): content carries text and tool_use blocks. model is the slug that actually served the request."
      properties:
        id:
          type: string
          example: msg_0f3c…
        type:
          type: string
          enum:
            - message
        role:
          type: string
          enum:
            - assistant
        model:
          type: string
        content:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                enum:
                  - text
                  - tool_use
              text:
                type: string
              id:
                type: string
              name:
                type: string
              input:
                type: object
            required:
              - type
        stop_reason:
          type: string
          enum:
            - end_turn
            - max_tokens
            - stop_sequence
            - tool_use
            - pause_turn
            - refusal
          description: An anthropic/* upstream's own stop reason; otherwise from finish_reason (length → max_tokens, tool_calls → tool_use, content_filter → refusal, else end_turn).
        stop_sequence:
          type: "null"
        usage:
          type: object
          properties:
            input_tokens:
              type: integer
              description: Excludes cache reads and cache writes
            output_tokens:
              type: integer
            cache_creation_input_tokens:
              type: integer
            cache_read_input_tokens:
              type: integer
      required:
        - id
        - type
        - role
        - model
        - content
        - stop_reason
        - stop_sequence
        - usage
    AnthropicMessagesRequest:
      type: object
      description: Anthropic Messages request (POST /v1/messages), any model slug. On an anthropic/* model the body is forwarded as sent, with only model (the upstream id) and max_tokens (the capped value) set by the gateway, so cache_control, thinking, documents and server tools reach Anthropic unchanged. On any other model it is translated to the chat-completions shape; blocks with no neutral form (thinking, server tools) are not sent. Gateway directives (models, fallbacks, sort, max_cost and OpenRouter's provider, route, transforms, plugins, usage, session_id) are consumed, never forwarded.
      properties:
        model:
          type: string
          example: anthropic/claude-haiku-4-5
          description: A model slug ("provider/model") or "@preset/<slug>". Required unless models[] is set.
        messages:
          type: array
          description: "Turns, role user or assistant. content is a string or an array of blocks: text, image (source base64 or url), tool_use, tool_result, thinking, document, … tool_result blocks become tool messages on a translated model."
          items:
            type: object
            properties:
              role:
                type: string
                enum:
                  - user
                  - assistant
              content:
                oneOf:
                  - type: string
                  - type: array
                    items:
                      $ref: "#/components/schemas/AnthropicContentBlock"
            required:
              - role
              - content
          example:
            - role: user
              content: Say hi in three words
        system:
          description: A string or an array of text blocks; a system message on a translated model.
          oneOf:
            - type: string
            - type: array
              items:
                $ref: "#/components/schemas/AnthropicContentBlock"
        max_tokens:
          type: integer
          example: 64
        stop_sequences:
          type: array
          items:
            type: string
          description: stop on a translated model
        stream:
          type: boolean
          default: false
        temperature:
          type: number
        top_p:
          type: number
        top_k:
          type: integer
        tools:
          type: array
          description: Client tools (name, description, input_schema → function.parameters on a translated model). A server tool (a type other than custom, no input_schema) only an anthropic/* model can run.
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type: string
              input_schema:
                type: object
              type:
                type: string
            required:
              - name
        tool_choice:
          type: object
          description: "On a translated model: auto → auto, any → required, none → none, tool → that function; disable_parallel_tool_use → parallel_tool_calls:false."
          properties:
            type:
              type: string
              enum:
                - auto
                - any
                - tool
                - none
            name:
              type: string
            disable_parallel_tool_use:
              type: boolean
          required:
            - type
        metadata:
          type: object
          properties:
            user_id:
              type: string
              description: user on a translated model
        thinking:
          type: object
          description: "Forwarded to anthropic/*. On a translated model, type enabled with budget_tokens becomes reasoning_effort by its share of max_tokens: ≤35% low, ≤65% medium, else high."
          properties:
            type:
              type: string
            budget_tokens:
              type: integer
        service_tier:
          type: string
          description: standard_only is dropped and auto is forwarded (both the default tier); a value other than auto or default answers 400 unsupported_service_tier (the rate card prices the default tier only).
        models:
          type: array
          items:
            type: string
          description: "Ocean: ordered fallback candidates, as on /v1/chat/completions."
        fallbacks:
          type: array
          items:
            type: string
          maxItems: 3
          description: "OpenRouter's Anthropic-skin fallback list: tried after model, at most 3 (more → 400). Ignored when models[] is set."
        sort:
          type: string
          enum:
            - price
            - latency
            - throughput
        max_cost:
          type: number
          description: "Ocean: the request’s own cost cap in USD."
      required:
        - messages
      additionalProperties: true
    CompatError:
      type: object
      description: "OpenRouter's error envelope, worn by every /api/v1 error (guide 5.0, 5.7): a numeric `code` equal to the HTTP status, the Ocean detail in `metadata`. No X-Error-Code header."
      properties:
        error:
          type: object
          properties:
            code:
              type: integer
              description: The HTTP status
            message:
              type: string
            metadata:
              type: object
              properties:
                error_type:
                  type: string
                  description: "OpenRouter's error type: authentication, payment_required, rate_limit_exceeded, not_found, invalid_request, …"
                ocean_code:
                  type: string
                  description: The /v1 envelope's string error.code
                ocean_type:
                  type: string
                request_id:
                  type: string
                  description: Equals the x-request-id header
              required:
                - error_type
                - ocean_code
                - request_id
              additionalProperties: true
          required:
            - code
            - message
            - metadata
          additionalProperties: true
      required:
        - error
  securitySchemes:
    anthropicApiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: "ozk_ key in the x-api-key header, as the Anthropic SDKs send it — POST /v1/messages only (Authorization: Bearer also works there and wins when both are sent). anthropic-version is accepted with any value."
    ozkBearer:
      type: http
      scheme: bearer
      description: "ozk_ platform API key (Authorization: Bearer ozk_…)"
    skOcean:
      type: http
      scheme: bearer
      description: "Legacy sk-ocean- inference key: still accepted on the money plane until the sk-ocean- sunset; new integrations use the ozk_ key"
```
