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

# Completions

> Legacy text completion, for prompts that are not a conversation. Only models that declare the text-completion capability accept it; the rest return MODEL_CAPABILITY_UNSUPPORTED.

## Which models accept this

Only models that declare the text-completion capability. Everything else returns
`MODEL_CAPABILITY_UNSUPPORTED`, because answering a raw-prompt request on a model shaped
for conversation produces output that looks fine and is not what you asked for.

Most models here are chat models. If you are starting something new, use
[chat completions](/api-reference/chat-completions) — this endpoint exists so that code
written against the older shape keeps working.

## One prompt per call

`prompt` takes a string, or an array holding exactly one string. Several prompts in one
call are rejected rather than partly answered.


## OpenAPI

````yaml openapi/prentis.openapi.yaml POST /completions
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:
  /completions:
    post:
      tags:
        - completions
      summary: Create a completion
      description: >-
        Legacy text completion, for prompts that are not a conversation. Only
        models that declare the text-completion capability accept it; the rest
        return MODEL_CAPABILITY_UNSUPPORTED.
      operationId: createCompletion
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompletionRequest'
      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/CompletionResponse'
              example:
                id: cmpl-01K5S8PJ7D3M
                object: text_completion
                created: 1789286400
                model: deepseek-v4.1-flash
                choices:
                  - index: 0
                    text: |2-

                          a, b = 0, 1
                          for _ in range(n):
                              a, b = b, a + b
                          return a
                    finish_reason: stop
                usage:
                  prompt_tokens: 6
                  completion_tokens: 34
                  total_tokens: 40
            text/event-stream:
              schema:
                type: string
              example: >-
                data:
                {"id":"cmpl-01K5S8PJ7D3M","object":"text_completion","model":"deepseek-v4.1-flash","choices":[{"index":0,"text":"\n   
                a, b = 0, 1"}]}


                data:
                {"id":"cmpl-01K5S8PJ7D3M","object":"text_completion","model":"deepseek-v4.1-flash","choices":[{"index":0,"text":"\n   
                return a","finish_reason":"stop"}]}


                data:
                {"id":"cmpl-01K5S8PJ7D3M","object":"text_completion","model":"deepseek-v4.1-flash","choices":[],"usage":{"prompt_tokens":6,"completion_tokens":34,"total_tokens":40}}


                data: [DONE]
          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.
        '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/completions \
              -H "Authorization: Bearer $PRENTIS_API_KEY" \
              -H "Content-Type: application/json" \
              -d '{
                "model": "deepseek-v4.1-flash",
                "prompt": "def fibonacci(n):",
                "max_tokens": 128,
                "stop": ["\n\n"]
              }'
        - 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.completions.create(
                model="deepseek-v4.1-flash",
                prompt="def fibonacci(n):",
                max_tokens=128,
                stop=["\n\n"],
            )

            print(resp.choices[0].text)
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 255
      description: >-
        Your own key for making a retry safe (up to 255 characters). It is
        accepted and echoed back today; de-duplication of replays arrives in a
        later release, so a retry is currently a second billable call.
  schemas:
    CompletionRequest:
      type: object
      required:
        - model
        - prompt
      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.
        prompt:
          oneOf:
            - type: string
            - type: array
              items:
                type: string
              minItems: 1
              maxItems: 1
          description: >-
            The text to continue. A string, or an array holding exactly one
            string -- several prompts in one call are rejected rather than
            partly answered.
        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.
        stream_options:
          type: object
          properties:
            include_usage:
              type: boolean
          description: >-
            Streaming options. include_usage is accepted for compatibility;
            usage arrives on the final event whether or not you ask for it.
        max_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.
        stop:
          oneOf:
            - type: string
            - 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.
        seed:
          type: integer
          description: >-
            Best effort repeatability: the same seed with the same parameters
            returns the same answer on models that support it.
        frequency_penalty:
          type: number
          minimum: -2
          maximum: 2
          description: >-
            Pushes the model away from tokens it has already used often in this
            answer. Negative values do the opposite.
        presence_penalty:
          type: number
          minimum: -2
          maximum: 2
          description: >-
            Pushes the model away from tokens that have appeared at all in this
            answer, which tends to move it on to new ground.
        user:
          type: string
          description: >-
            Your own identifier for the end user behind the call. It is echoed
            back in this request's log line so you can correlate the two; it is
            not kept on the usage record.
        'n':
          type: integer
          description: |-
            How many completions to return.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
        best_of:
          type: integer
          description: |-
            Sample several completions server-side and return the best one.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
        logprobs:
          type: integer
          description: |-
            Per-token log probabilities.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
        echo:
          type: boolean
          description: |-
            Repeat the prompt back at the start of the completion.

            **Not supported.** Sending it returns `INVALID_REQUEST`.
        suffix:
          type: string
          description: |-
            Text that should follow the completion (fill-in-the-middle).

            **Not supported.** Sending it returns `INVALID_REQUEST`.
    CompletionResponse:
      type: object
      required:
        - id
        - object
        - created
        - model
        - choices
        - usage
      properties:
        id:
          type: string
        object:
          type: string
          const: text_completion
        created:
          type: integer
        model:
          type: string
        choices:
          type: array
          items:
            $ref: '#/components/schemas/CompletionChoice'
        usage:
          $ref: '#/components/schemas/Usage'
        system_fingerprint:
          type: string
    CompletionChoice:
      type: object
      required:
        - index
        - text
      properties:
        index:
          type: integer
        text:
          type: string
        logprobs:
          type: 'null'
        finish_reason:
          type:
            - string
            - 'null'
          enum:
            - stop
            - length
            - content_filter
            - null
    Usage:
      type: object
      required:
        - prompt_tokens
        - completion_tokens
        - total_tokens
      properties:
        prompt_tokens:
          type: integer
          minimum: 0
        completion_tokens:
          type: integer
          minimum: 0
        total_tokens:
          type: integer
          minimum: 0
        prompt_tokens_details:
          type: object
          properties:
            cached_tokens:
              type: integer
              minimum: 0
        media:
          type: object
          properties:
            input_images:
              type: integer
              minimum: 0
            input_video_seconds:
              type: number
              minimum: 0
            input_audio_seconds:
              type: number
              minimum: 0
            output_images:
              type: integer
              minimum: 0
            output_video_seconds:
              type: number
              minimum: 0
            output_audio_seconds:
              type: number
              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
                - 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`,
        `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.

````