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

# Singleshot API

> Typed decisions: send a state and named questions, get a calibrated probability per answer back. No text generation, no parsing.

## Overview

Most of what an agent asks a model is not a paragraph. It is "which queue does this ticket go to", "how severe is this", "does this message need a human". Asking a chat model means generating text, parsing it, and hoping the number it wrote reflects anything. Singleshot skips the generation: the model reads the state once and reports the probability of every option for every question in one forward pass per question, so your code branches on numbers.

`POST /v1/singleshot` takes a `state` (text, a JSON object or an array of text) and a map of named questions of three types. Every answer is a distribution over the options you gave.

| type     | ask                                 | answer                                                                            |
| -------- | ----------------------------------- | --------------------------------------------------------------------------------- |
| `noul`   | a yes/no statement                  | `noul`: the probability of yes                                                    |
| `choice` | pick one of 2 to 255 named options  | `choice`, `probabilities` per option, `confidence`                                |
| `score`  | rate against 2 to 10 ordered levels | `score` (expected level), `probabilities` per level index, `legend`, `confidence` |

Model: `morph-systemone-v1`, alias `systemone-latest`.

## Writing questions

`instructions` is what you want judged. `criteria` describes the options: for `choice` a map of option name to description, for `score` an ordered list of level descriptions from lowest to highest, for `noul` an optional `{"true": ..., "false": ...}` pair. Descriptions do the work: an option the model can only see by name gets answered by the name alone.

Instructions and descriptions accept JSON structure as well as strings. When a question has parts, an object with labelled keys reads better than a sentence that tries to hold them all:

```json theme={null}
{
  "type": "choice",
  "instructions": { "question": "Which topic does the line belong to?", "hint": "Read the heading above it first." },
  "criteria": {
    "returns": { "what": "Whether and how an item can be returned", "not_for": "Progress of a return already sent" },
    "shipping": "Delivery status, delays, lost packages"
  }
}
```

Ask every question about one state in one call. The state is read once and charged once however many questions follow; the questions are short extensions of it.

## Reading answers

* `probabilities` sum to 1 per question. `choice` is the argmax; `score` is the expected level, so a 3-level scale answering `{0: 0.0, 1: 0.7, 2: 0.3}` scores 1.3.
* `confidence` (0 to 1) summarizes the shape of the distribution. For `choice` it is one minus the normalized entropy: 1.0 when all the mass is on one option, 0.0 when it is spread evenly. For `score` it is one minus the normalized standard deviation of the level: 1.0 when the mass sits on one level, 0.0 when it is split between the two ends. Gate actions on it: act automatically above a threshold you choose per action, route to a person below it.
* A `noul` answer has no `confidence`; the probability is the whole answer, and you threshold it.
* `usage.input_tokens` is the state plus the questions, read once. `usage.output_tokens` is the number of scored positions, one per question.

Measured on public benchmarks with this exact mechanism and no task-specific training: sentiment (2 options) 0.960, question classification (6) 0.915, intent (7) 0.956 accuracy, with expected calibration error under 0.04 after label-free calibration.

## Limits and errors

* `state` up to 32,768 tokens; state plus the longest question up to 32,768 tokens; a request up to 65,536 tokens; up to 256 questions.
* `422`: the request does not fit the contract. `error.param` names the field, for example `questions.department.criteria`.
* `401`: missing or invalid key. `429`: your key's rate limit. `529`: the engine is at capacity. The request was not queued; retry with exponential backoff, honoring `Retry-After`.
* Every response carries `x-request-id`.

## Switching from another typed-decision API

If you already send `{state, model, questions}` with `noul`, `choice` and `score` questions, the bodies are the same here. Change four things: the base URL to `https://api.morphllm.com`, the key to a Morph key, the path to `/v1/singleshot`, and `model` to `morph-systemone-v1`. Answers come back in the same shapes.


## OpenAPI

````yaml POST /v1/singleshot
openapi: 3.1.0
info:
  title: Morph API
  version: 1.2.0
  description: >-
    The Morph public API at api.morphllm.com: OpenAI- and Anthropic-compatible
    inference (chat completions, messages), the Batch API, Fast Apply code
    editing, Compact context compression, Reflex classification, Singleshot
    typed decisions, and fine-tuning. Model ids, prices, and context windows are
    served live at https://www.morphllm.com/api/models/json.
  contact:
    name: Morph
    url: https://morphllm.com
    email: info@morphllm.com
  license:
    name: Proprietary
    url: https://morphllm.com/privacy/tos
servers:
  - url: https://api.morphllm.com
    description: Production
security: []
tags:
  - name: chat
    description: >-
      OpenAI- and Anthropic-compatible chat inference, including Fast Apply and
      WarpGrep models.
  - name: compact
    description: Context compression for long agent conversations.
  - name: reflex
    description: 'Per-turn classifiers: realtime prediction and batches.'
  - name: singleshot
    description: 'Typed decisions: a state in, a calibrated distribution per question out.'
  - name: fine-tuning
    description: Reflex fine-tuning job lifecycle.
  - name: batch
    description: >-
      OpenAI-compatible Batch API: upload a JSONL file, run it at half price,
      download the results.
  - name: models
    description: Model listing and management.
  - name: telemetry
    description: Usage reporting hooks.
paths:
  /v1/singleshot:
    post:
      tags:
        - singleshot
      summary: Answer typed questions about a state
      description: >-
        Send a state and named questions of three types: `noul` (yes/no),
        `choice` (one of a set) and `score` (ordered levels). Every answer is a
        probability distribution your code can branch on, with a `confidence`
        for choice and score. No text is generated. The state is read once
        however many questions you ask, so batch every question about one state
        into one call.
      operationId: singleshot
      requestBody:
        required: true
        description: The state and the questions to answer about it.
        content:
          application/json:
            example:
              state: >-
                Hi, I've been trying to connect my Stripe account for 3 days and
                it keeps failing. I'm losing sales. Please help ASAP.
              model: morph-systemone-v1
              questions:
                department:
                  type: choice
                  instructions: Which team should handle this?
                  criteria:
                    billing: Payment or subscription issues
                    technical: Bugs or integration problems
                    sales: Pricing or account questions
                frustration:
                  type: score
                  instructions: How frustrated does the customer appear?
                  criteria:
                    - Calm, just stating facts
                    - Frustrated but civil
                    - Very angry, strong language
                is_urgent:
                  type: noul
                  instructions: The message conveys urgency or time sensitivity.
            schema:
              $ref: '#/components/schemas/SingleshotRequest'
      responses:
        '200':
          description: One answer per question.
          content:
            application/json:
              example:
                model: morph-systemone-v1
                answers:
                  department:
                    type: choice
                    choice: billing
                    probabilities:
                      billing: 0.84
                      technical: 0.159
                      sales: 0.001
                    confidence: 0.596
                  frustration:
                    type: score
                    score: 1.3
                    probabilities:
                      '0': 0
                      '1': 0.7
                      '2': 0.3
                    legend:
                      '0': Calm, just stating facts
                      '1': Frustrated but civil
                      '2': Very angry, strong language
                    confidence: 0.54
                  is_urgent:
                    type: noul
                    noul: 0.999
                usage:
                  input_tokens: 312
                  output_tokens: 3
              schema:
                $ref: '#/components/schemas/SingleshotResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          description: >-
            The request does not fit the contract. `error.param` names the
            field.
          content:
            application/json:
              example:
                error:
                  message: choice needs 2 to 255 options, got 1.
                  type: invalid_request_error
                  param: questions.department.criteria
                  code: null
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '529':
          description: >-
            The engine is at capacity. Retry with exponential backoff; the
            request was not queued.
          content:
            application/json:
              example:
                error:
                  message: The engine is at capacity; retry with backoff.
                  type: overloaded_error
                  param: null
                  code: overloaded
      security:
        - bearerAuth: []
components:
  schemas:
    SingleshotRequest:
      type: object
      properties:
        state:
          anyOf:
            - type: string
            - type: object
              additionalProperties:
                $ref: '#/components/schemas/SingleshotJsonValue'
            - type: array
              items:
                $ref: '#/components/schemas/SingleshotJsonValue'
            - type: 'null'
          description: >-
            What the questions are about: text, a JSON object, or an array of
            text. Up to 32,768 tokens. Charged once per request however many
            questions follow.
          example: >-
            Hi, I've been trying to connect my Stripe account for 3 days and it
            keeps failing. I'm losing sales. Please help ASAP.
        model:
          type: string
          description: '`morph-systemone-v1`, or the alias `systemone-latest`.'
          example: morph-systemone-v1
        questions:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/SingleshotQuestion'
          description: >-
            Named questions (1 to 256). The answer for each comes back under the
            same name.
          example:
            department:
              type: choice
              instructions: Which team should handle this?
              criteria:
                billing: Payment or subscription issues
                technical: Bugs or integration problems
                sales: Pricing or account questions
            frustration:
              type: score
              instructions: How frustrated does the customer appear?
              criteria:
                - Calm, just stating facts
                - Frustrated but civil
                - Very angry, strong language
            is_urgent:
              type: noul
              instructions: The message conveys urgency or time sensitivity.
      required:
        - state
        - model
        - questions
      description: A state and the typed questions to answer about it.
      example:
        state: >-
          Hi, I've been trying to connect my Stripe account for 3 days and it
          keeps failing. I'm losing sales. Please help ASAP.
        model: morph-systemone-v1
        questions:
          department:
            type: choice
            instructions: Which team should handle this?
            criteria:
              billing: Payment or subscription issues
              technical: Bugs or integration problems
              sales: Pricing or account questions
          frustration:
            type: score
            instructions: How frustrated does the customer appear?
            criteria:
              - Calm, just stating facts
              - Frustrated but civil
              - Very angry, strong language
          is_urgent:
            type: noul
            instructions: The message conveys urgency or time sensitivity.
    SingleshotResponse:
      type: object
      properties:
        model:
          type: string
          description: The model that answered.
          example: morph-systemone-v1
        answers:
          type: object
          additionalProperties:
            anyOf:
              - $ref: '#/components/schemas/SingleshotChoiceAnswer'
              - $ref: '#/components/schemas/SingleshotScoreAnswer'
              - $ref: '#/components/schemas/SingleshotNoulAnswer'
          description: One answer per question, under the name you gave it.
          example:
            department:
              type: choice
              choice: billing
              probabilities:
                billing: 0.84
                technical: 0.159
                sales: 0.001
              confidence: 0.596
            frustration:
              type: score
              score: 1.3
              probabilities:
                '0': 0
                '1': 0.7
                '2': 0.3
              legend:
                '0': Calm, just stating facts
                '1': Frustrated but civil
                '2': Very angry, strong language
              confidence: 0.54
            is_urgent:
              type: noul
              noul: 0.999
        usage:
          type: object
          properties:
            input_tokens:
              type: integer
              description: Tokens of state and questions read once.
              example: 312
            output_tokens:
              type: integer
              description: 'Scored positions: one per question.'
              example: 3
          required:
            - input_tokens
            - output_tokens
          description: Token accounting for the request.
      required:
        - model
        - answers
        - usage
      description: The answers and what they cost.
      example:
        model: morph-systemone-v1
        answers:
          department:
            type: choice
            choice: billing
            probabilities:
              billing: 0.84
              technical: 0.159
              sales: 0.001
            confidence: 0.596
          frustration:
            type: score
            score: 1.3
            probabilities:
              '0': 0
              '1': 0.7
              '2': 0.3
            legend:
              '0': Calm, just stating facts
              '1': Frustrated but civil
              '2': Very angry, strong language
            confidence: 0.54
          is_urgent:
            type: noul
            noul: 0.999
        usage:
          input_tokens: 312
          output_tokens: 3
    SingleshotJsonValue:
      anyOf:
        - type: string
        - type: number
        - type: boolean
        - type: 'null'
        - type: array
          items:
            anyOf:
              - type: string
              - type: number
              - type: boolean
              - type: 'null'
        - type: object
          additionalProperties:
            anyOf:
              - type: string
              - type: number
              - type: boolean
              - type: 'null'
              - type: array
                items:
                  anyOf:
                    - type: string
                    - type: number
                    - type: boolean
                    - type: 'null'
              - type: object
                additionalProperties:
                  anyOf:
                    - type: string
                    - type: number
                    - type: boolean
                    - type: 'null'
      description: 'Any JSON value: text, a number, a boolean, null, an array or an object.'
    SingleshotQuestion:
      anyOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - noul
            instructions:
              anyOf:
                - type: string
                - type: object
                  additionalProperties:
                    $ref: '#/components/schemas/SingleshotJsonValue'
                - type: array
                  items:
                    $ref: '#/components/schemas/SingleshotJsonValue'
              description: >-
                The yes/no statement or question to evaluate. Plain text, or a
                JSON object or array when the content has parts worth labelling.
            criteria:
              type: object
              properties:
                'true':
                  anyOf:
                    - type: string
                    - type: object
                      additionalProperties:
                        $ref: '#/components/schemas/SingleshotJsonValue'
                    - type: array
                      items:
                        $ref: '#/components/schemas/SingleshotJsonValue'
                  description: >-
                    What makes the answer yes. Plain text, or a JSON object or
                    array when the content has parts worth labelling.
                'false':
                  anyOf:
                    - type: string
                    - type: object
                      additionalProperties:
                        $ref: '#/components/schemas/SingleshotJsonValue'
                    - type: array
                      items:
                        $ref: '#/components/schemas/SingleshotJsonValue'
                  description: >-
                    What makes the answer no. Plain text, or a JSON object or
                    array when the content has parts worth labelling.
              description: Optional descriptions of the two outcomes.
          required:
            - type
            - instructions
          description: A yes/no question. The answer is the probability of yes.
        - type: object
          properties:
            type:
              type: string
              enum:
                - choice
            instructions:
              anyOf:
                - type: string
                - type: object
                  additionalProperties:
                    $ref: '#/components/schemas/SingleshotJsonValue'
                - type: array
                  items:
                    $ref: '#/components/schemas/SingleshotJsonValue'
              description: >-
                The question the model answers by picking one option. Plain
                text, or a JSON object or array when the content has parts worth
                labelling.
            criteria:
              type: object
              additionalProperties:
                anyOf:
                  - type: string
                  - type: object
                    additionalProperties:
                      $ref: '#/components/schemas/SingleshotJsonValue'
                  - type: array
                    items:
                      $ref: '#/components/schemas/SingleshotJsonValue'
                  - type: 'null'
                description: >-
                  What the option covers. Plain text, or a JSON object or array
                  when the content has parts worth labelling.
              description: >-
                Option names mapped to their descriptions (2 to 255 options). A
                description may be null.
              example:
                billing: Payment or subscription issues
                technical: Bugs or integration problems
          required:
            - type
            - instructions
            - criteria
          description: Pick one option from a defined set.
        - type: object
          properties:
            type:
              type: string
              enum:
                - score
            instructions:
              anyOf:
                - type: string
                - type: object
                  additionalProperties:
                    $ref: '#/components/schemas/SingleshotJsonValue'
                - type: array
                  items:
                    $ref: '#/components/schemas/SingleshotJsonValue'
              description: >-
                What is being rated. Plain text, or a JSON object or array when
                the content has parts worth labelling.
            criteria:
              type: array
              items:
                anyOf:
                  - type: string
                  - type: object
                    additionalProperties:
                      $ref: '#/components/schemas/SingleshotJsonValue'
                  - type: array
                    items:
                      $ref: '#/components/schemas/SingleshotJsonValue'
                description: >-
                  One level of the scale. Plain text, or a JSON object or array
                  when the content has parts worth labelling.
              minItems: 2
              maxItems: 10
              description: >-
                Ordered level descriptions, lowest first (2 to 10 levels).
                Levels are addressed by index in the answer.
              example:
                - Calm, just stating facts
                - Frustrated but civil
                - Very angry, strong language
          required:
            - type
            - instructions
            - criteria
          description: Rate the state against ordered levels.
      description: One typed question. `type` selects the variant.
      example:
        type: choice
        instructions: Which team should handle this?
        criteria:
          billing: Payment or subscription issues
          technical: Bugs or integration problems
          sales: Pricing or account questions
    SingleshotChoiceAnswer:
      type: object
      properties:
        type:
          type: string
          enum:
            - choice
        choice:
          type: string
          description: The option with the highest probability.
          example: billing
        probabilities:
          type: object
          additionalProperties:
            type: number
          description: A probability per option, summing to 1.
          example:
            billing: 0.84
            technical: 0.159
            sales: 0.001
        confidence:
          type: number
          description: >-
            How concentrated the distribution is, 0 to 1: one minus its
            normalized entropy.
          example: 0.596
      required:
        - type
        - choice
        - probabilities
        - confidence
      description: 'A choice answer: the winning option and the full distribution.'
      example:
        type: choice
        choice: billing
        probabilities:
          billing: 0.84
          technical: 0.159
          sales: 0.001
        confidence: 0.596
    SingleshotScoreAnswer:
      type: object
      properties:
        type:
          type: string
          enum:
            - score
        score:
          type: number
          description: >-
            Expected level: each level index times its probability, summed. 0 is
            the first level.
          example: 1.3
        probabilities:
          type: object
          additionalProperties:
            type: number
          description: A probability per level, keyed by level index.
          example:
            '0': 0
            '1': 0.7
            '2': 0.3
        legend:
          type: object
          additionalProperties:
            anyOf:
              - type: string
              - type: object
                additionalProperties:
                  $ref: '#/components/schemas/SingleshotJsonValue'
              - type: array
                items:
                  $ref: '#/components/schemas/SingleshotJsonValue'
            description: >-
              The level description as sent. Plain text, or a JSON object or
              array when the content has parts worth labelling.
          description: Level index back to the description you sent.
          example:
            '0': Calm, just stating facts
            '1': Frustrated but civil
            '2': Very angry, strong language
        confidence:
          type: number
          description: >-
            How tightly the mass sits on the scale, 0 to 1: one minus the
            normalized standard deviation of the level.
          example: 0.54
      required:
        - type
        - score
        - probabilities
        - legend
        - confidence
      description: >-
        A score answer: the expected level, the distribution over levels and the
        legend.
      example:
        type: score
        score: 1.3
        probabilities:
          '0': 0
          '1': 0.7
          '2': 0.3
        legend:
          '0': Calm, just stating facts
          '1': Frustrated but civil
          '2': Very angry, strong language
        confidence: 0.54
    SingleshotNoulAnswer:
      type: object
      properties:
        type:
          type: string
          enum:
            - noul
        noul:
          type: number
          description: The probability that the answer is yes, 0 to 1.
          example: 0.999
      required:
        - type
        - noul
      description: 'A noul answer: the probability of yes.'
      example:
        type: noul
        noul: 0.999
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: invalid_request_error
              description: Machine-readable error code.
            message:
              type: string
              example: The request body is missing the `model` field.
              description: Human-readable explanation of the failure.
          required:
            - code
            - message
      required:
        - error
      description: Standard error envelope returned by every non-2xx response.
      example:
        error:
          code: invalid_request_error
          message: The request body is missing the `model` field.
  responses:
    BadRequest:
      description: Malformed request — missing or invalid fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_request_error
              message: The request body is missing the `model` field.
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: Invalid API key provided.
    RateLimited:
      description: Rate limited — retry after the interval in the Retry-After header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: Too many requests. Retry in 12 seconds.
    InternalError:
      description: Internal error — safe to retry with backoff.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: internal_error
              message: Something went wrong on our side.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: opaque
      description: >-
        Morph API key, passed as `Authorization: Bearer sk-...`. Create keys at
        https://www.morphllm.com/dashboard/api-keys.

````