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

# Responses

> OpenAI Responses-compatible endpoint, stateless. Codex and other Responses clients work by changing base_url alone. Every call must send store false and carry the full conversation in input: nothing is kept to continue from, so previous_response_id and retrieving a response later are not offered.

OpenAI's Responses wire format, served by the same models as everything else here. Codex
and other Responses clients work by changing `base_url` alone.

## Stateless, on purpose

The real Responses API can store a response and continue from it later. This one keeps
nothing, and says so instead of pretending:

* **`store` must be `false`.** Leaving it out means `true` on OpenAI's API, so a call
  without it is rejected rather than quietly not stored.
* **`previous_response_id` is rejected.** Send the whole conversation in `input` on every
  call — earlier `function_call` and `function_call_output` items included.
* **There is no `GET` or `DELETE /responses/{id}`.**

Clients that already resend the full history each turn, Codex among them, need none of
the stateful half.

## Tools

Only `{"type": "function", ...}` tools reach the model. Tools of any other type — hosted
tools, MCP servers, namespaced groups — are dropped from the list rather than failing the
call, so the model never learns they exist and cannot call them.

## Streaming

`stream: true` returns Responses events, ending at `response.completed`, which carries the
usage. There is no `[DONE]` sentinel.


## OpenAPI

````yaml openapi/prentis.openapi.yaml POST /responses
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: responses
  - name: models
paths:
  /responses:
    post:
      tags:
        - responses
      summary: Create a response
      description: >-
        OpenAI Responses-compatible endpoint, stateless. Codex and other
        Responses clients work by changing base_url alone. Every call must send
        store false and carry the full conversation in input: nothing is kept to
        continue from, so previous_response_id and retrieving a response later
        are not offered.
      operationId: createResponse
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResponsesRequest'
      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/ResponsesObject'
              example:
                id: resp_01K5S8RB2NQX
                object: response
                status: completed
                model: deepseek-v4.1-flash
                output:
                  - id: msg_01K5S8RB2NQX
                    type: message
                    role: assistant
                    status: completed
                    content:
                      - type: output_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.
                usage:
                  input_tokens: 28
                  output_tokens: 47
                  total_tokens: 75
                store: false
            text/event-stream:
              schema:
                type: string
              example: >-
                event: response.created

                data:
                {"type":"response.created","response":{"id":"resp_01K5S8RB2NQX","object":"response","status":"in_progress","model":"deepseek-v4.1-flash","output":[],"usage":{"input_tokens":0,"output_tokens":0,"total_tokens":0},"store":false}}


                event: response.output_item.added

                data:
                {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_01K5S8RB2NQX","type":"message","role":"assistant","status":"in_progress"}}


                event: response.output_text.delta

                data:
                {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":"A
                distributed"}


                event: response.output_text.delta

                data:
                {"type":"response.output_text.delta","output_index":0,"content_index":0,"delta":"
                store can hold"}


                event: response.output_text.done

                data:
                {"type":"response.output_text.done","output_index":0,"content_index":0,"text":"A
                distributed store can hold at most two of consistency,
                availability and partition tolerance at once."}


                event: response.output_item.done

                data:
                {"type":"response.output_item.done","output_index":0,"item":{"id":"msg_01K5S8RB2NQX","type":"message","role":"assistant","status":"completed","content":[{"type":"output_text","text":"A
                distributed store can hold at most two of consistency,
                availability and partition tolerance at once."}]}}


                event: response.completed

                data:
                {"type":"response.completed","response":{"id":"resp_01K5S8RB2NQX","object":"response","status":"completed","model":"deepseek-v4.1-flash","output":[],"usage":{"input_tokens":28,"output_tokens":47,"total_tokens":75},"store":false}}
          description: >-
            OK. With `stream: true` the same call answers `text/event-stream`
            instead, as Responses events: `response.created`, the output item
            and delta events, and `response.completed`, which carries `usage`
            and ends the stream. There is no `[DONE]` line. A failure part-way
            through adds an `error` event before the stream closes.
        '400':
          $ref: '#/components/responses/Error400'
        '401':
          $ref: '#/components/responses/Error401'
        '402':
          $ref: '#/components/responses/Error402'
        '403':
          $ref: '#/components/responses/Error403'
        '404':
          $ref: '#/components/responses/Error404'
        '413':
          $ref: '#/components/responses/Error413'
        '429':
          $ref: '#/components/responses/Error429'
        '500':
          $ref: '#/components/responses/Error500'
        '503':
          $ref: '#/components/responses/Error503'
        '504':
          $ref: '#/components/responses/Error504'
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl https://compute.prentis.ai/v1/responses \
              -H "Authorization: Bearer $PRENTIS_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "model": "deepseek-v4.1-flash",
                "instructions": "You are a concise assistant.",
                "input": "Summarise the CAP theorem in two sentences.",
                "max_output_tokens": 200,
                "store": false
              }'
        - lang: python
          label: Python
          source: >-
            import os

            from openai import OpenAI


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


            resp = client.responses.create(
                model="deepseek-v4.1-flash",
                instructions="You are a concise assistant.",
                input="Summarise the CAP theorem in two sentences.",
                max_output_tokens=200,
                store=False,
            )

            print(resp.output_text)
        - lang: typescript
          label: TypeScript
          source: >-
            import OpenAI from "openai";


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


            const resp = await client.responses.create({
              model: "deepseek-v4.1-flash",
              instructions: "You are a concise assistant.",
              input: "Summarise the CAP theorem in two sentences.",
              max_output_tokens: 200,
              store: false,
            });

            console.log(resp.output_text);
components:
  schemas:
    ResponsesRequest:
      type: object
      required:
        - model
        - input
        - store
      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.
        input:
          oneOf:
            - type: string
            - type: array
              items:
                type: object
          description: >-
            The conversation, oldest first: a string, or a list of message,
            function_call and function_call_output items. Send all of it on
            every call.
        instructions:
          type: string
          description: >-
            Instructions that sit outside the conversation, sent to the model as
            a system message. Counted as input tokens.
        max_output_tokens:
          type: integer
          minimum: 1
          description: >-
            Ceiling on how many tokens may be generated. Omit it to use the
            model's own default.
        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.
        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.
        tools:
          type: array
          items:
            type: object
          description: >-
            Function definitions in the Responses shape ({type: "function",
            name, description, parameters}). Tools of any other type are dropped
            from the list, so the model never learns they exist.
        tool_choice:
          oneOf:
            - type: string
            - type: object
          description: >-
            Whether the model may, must, or must not call a tool: auto, none,
            required, or {type: "function", name}.
        reasoning:
          type: object
          description: >-
            Ask for the model's reasoning. effort is low, medium or high
            (minimal counts as low); an object without effort asks for medium.
            Only models that reason accept it.
        store:
          type: boolean
          description: >-
            Must be false. This endpoint keeps nothing to retrieve later, so a
            call that leaves store out or sets it to true is rejected rather
            than quietly not stored.
        previous_response_id:
          type:
            - string
            - 'null'
          description: |-
            Not supported: send the whole conversation in input instead.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
    ResponsesObject:
      type: object
      required:
        - id
        - object
        - status
        - model
        - output
        - usage
        - store
      properties:
        id:
          type: string
        object:
          type: string
          const: response
        status:
          type: string
          enum:
            - completed
            - incomplete
        model:
          type: string
        output:
          type: array
          items:
            $ref: '#/components/schemas/ResponsesOutputItem'
        usage:
          $ref: '#/components/schemas/ResponsesUsage'
        store:
          type: boolean
          const: false
        incomplete_details:
          type: object
          properties:
            reason:
              type: string
              const: max_output_tokens
    ResponsesOutputItem:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - message
            - function_call
            - reasoning
        role:
          type: string
          const: assistant
        content:
          type: array
          items:
            type: object
        call_id:
          type: string
        name:
          type: string
        arguments:
          type: string
        summary:
          type: array
          items:
            type: object
    ResponsesUsage:
      type: object
      required:
        - input_tokens
        - output_tokens
        - total_tokens
      properties:
        input_tokens:
          type: integer
          minimum: 0
        output_tokens:
          type: integer
          minimum: 0
        total_tokens:
          type: integer
          minimum: 0
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
            - code
          properties:
            message:
              type: string
            type:
              type: string
              enum:
                - invalid_request_error
                - authentication_error
                - permission_error
                - not_found_error
                - rate_limit_error
                - server_error
                - service_unavailable
                - billing_error
            code:
              type: string
              enum:
                - INVALID_API_KEY
                - TENANT_SUSPENDED
                - MODEL_NOT_ALLOWED
                - OPERATION_NOT_ALLOWED
                - AGREEMENT_REQUIRED
                - INVALID_REQUEST
                - MODEL_NOT_FOUND
                - MODEL_CAPABILITY_UNSUPPORTED
                - CONTEXT_LENGTH_EXCEEDED
                - IDEMPOTENCY_CONFLICT
                - MEDIA_TOO_LARGE
                - MEDIA_FETCH_FAILED
                - MEDIA_UNSUPPORTED
                - TENANT_RATE_LIMITED
                - TENANT_BUDGET_EXCEEDED
                - INSUFFICIENT_BALANCE
                - PAYMENT_REQUIRED
                - CONTENT_BLOCKED_INPUT
                - CONTENT_BLOCKED_OUTPUT
                - UPSTREAM_RATE_LIMITED
                - UPSTREAM_UNAVAILABLE
                - UPSTREAM_TIMEOUT
                - PARTIAL_RESPONSE_TIMEOUT
                - UPSTREAM_CONTENT_REJECTED
                - DEPLOYMENT_SCALING_UP
                - REQUEST_CANCELLED
                - REQUEST_DEADLINE_EXCEEDED
                - INTERNAL
                - STORAGE_UNAVAILABLE
            param:
              type:
                - string
                - 'null'
  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.
  responses:
    Error400:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `CONTENT_BLOCKED_INPUT`,
        `CONTENT_BLOCKED_OUTPUT`, `CONTEXT_LENGTH_EXCEEDED`, `INVALID_REQUEST`,
        `MEDIA_FETCH_FAILED`, `MEDIA_UNSUPPORTED`,
        `MODEL_CAPABILITY_UNSUPPORTED`, `UPSTREAM_CONTENT_REJECTED`. See the
        Errors page for what each one means, whether it is safe to retry, and
        whether it is billed.
    Error401:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `INVALID_API_KEY`. See the Errors page for what
        each one means, whether it is safe to retry, and whether it is billed.
    Error402:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `INSUFFICIENT_BALANCE`, `PAYMENT_REQUIRED`. See
        the Errors page for what each one means, whether it is safe to retry,
        and whether it is billed.
    Error403:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `AGREEMENT_REQUIRED`, `MODEL_NOT_ALLOWED`,
        `OPERATION_NOT_ALLOWED`, `TENANT_SUSPENDED`. See the Errors page for
        what each one means, whether it is safe to retry, and whether it is
        billed.
    Error404:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `MODEL_NOT_FOUND`. See the Errors page for what
        each one means, whether it is safe to retry, and whether it is billed.
    Error413:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `MEDIA_TOO_LARGE`. See the Errors page for what
        each one means, whether it is safe to retry, and whether it is billed.
    Error429:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `TENANT_BUDGET_EXCEEDED`, `TENANT_RATE_LIMITED`,
        `UPSTREAM_RATE_LIMITED`. See the Errors page for what each one means,
        whether it is safe to retry, and whether it is billed.
    Error500:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `INTERNAL`. See the Errors page for what each
        one means, whether it is safe to retry, and whether it is billed.
    Error503:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `DEPLOYMENT_SCALING_UP`, `STORAGE_UNAVAILABLE`,
        `UPSTREAM_UNAVAILABLE`. See the Errors page for what each one means,
        whether it is safe to retry, and whether it is billed.
    Error504:
      headers:
        x-request-id:
          $ref: '#/components/headers/x-request-id'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      description: >-
        `error.code` is one of: `PARTIAL_RESPONSE_TIMEOUT`,
        `REQUEST_DEADLINE_EXCEEDED`, `UPSTREAM_TIMEOUT`. See the Errors page for
        what each one means, whether it is safe to retry, and whether it is
        billed.
  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.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.