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

# Run an LLM completion

> Runs a single LLM completion: one prompt in, one text (or schema-constrained JSON) result out. No tools and no agent loop. The completion runs under your API key's organization and its rate limits.

Accepted requests respond with `200 text/event-stream`. Each frame is a data-only `data: {json}` line. Every frame includes `operation`. `content` and `metadata` are omitted when empty. Metal sends a `HEARTBEAT` frame every 10 seconds while the completion runs, then exactly one terminal frame:

- `HEARTBEAT`: `{"operation":"HEARTBEAT"}`.
- `COMPLETE`: `content` is a JSON string containing `{"data":{"text":"..."}}`. `metadata` is omitted.
- `ERROR`: `content` is the error message and `metadata.errorCode` classifies the failure: `deadline_exceeded`, `canceled`, `completion_failed`, `internal_runtime_state`, `no_choices`, or `panic`.

Read the stream until the terminal frame and ignore `HEARTBEAT` frames. Validation failures that happen before the stream starts (missing `prompt`, malformed `jsonSchema`, unlisted `model`, or `timeoutSeconds` outside 0 to 180) return a plain JSON `400`. Omit `timeoutSeconds` or send `0` to use the 60-second default.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/inference
openapi: 3.1.0
info:
  title: Metal API
  version: 1.0.0
  description: >-
    REST API for Metal, the AI context layer for financial firms. Manage
    companies, deals, people, documents, activities, enrichments, scores,
    screenings, lists, workflows, and more. All endpoints are versioned under
    /v1, return JSON, and are scoped to the organization that owns your API key.
  contact:
    name: Metal Support
    email: support@metal.ai
    url: https://www.metal.ai
servers:
  - url: https://api.metal.ai
    description: Production
security:
  - MetalClientId: []
    MetalApiKey: []
tags:
  - name: API keys
    description: Create, list, and revoke API keys.
  - name: Companies
    description: Manage and enrich companies.
  - name: Deals
    description: Track opportunities through your pipeline.
  - name: People
    description: Manage contacts and relationships.
  - name: Documents
    description: Search and retrieve ingested documents.
  - name: Activities
    description: Log and search meetings, calls, and other interactions.
  - name: Enrichments
    description: Read and write enriched property values on resources.
  - name: Scores
    description: Score companies and deals against scoring frameworks.
  - name: Screenings
    description: Run and manage AI-powered company screenings.
  - name: Lists
    description: Organize and enrich resources in bulk.
  - name: Tags
    description: Label companies, deals, and lists.
  - name: Industries
    description: Manage your organization's industry taxonomy.
  - name: Sectors
    description: Manage sectors within an industry.
  - name: Subsectors
    description: Manage subsectors within a sector.
  - name: Workflows
    description: Run and monitor AI workflows.
  - name: Data
    description: Query time-series metrics and observations.
  - name: Teams
    description: Manage deal teams and their members.
  - name: Workspaces
    description: Organize documents and data by workspace.
  - name: Inference
    description: Run single LLM completions scoped to your organization.
paths:
  /v1/inference:
    post:
      tags:
        - Inference
      summary: Run an LLM completion
      description: >-
        Runs a single LLM completion: one prompt in, one text (or
        schema-constrained JSON) result out. No tools and no agent loop. The
        completion runs under your API key's organization and its rate limits.


        Accepted requests respond with `200 text/event-stream`. Each frame is a
        data-only `data: {json}` line. Every frame includes `operation`.
        `content` and `metadata` are omitted when empty. Metal sends a
        `HEARTBEAT` frame every 10 seconds while the completion runs, then
        exactly one terminal frame:


        - `HEARTBEAT`: `{"operation":"HEARTBEAT"}`.

        - `COMPLETE`: `content` is a JSON string containing
        `{"data":{"text":"..."}}`. `metadata` is omitted.

        - `ERROR`: `content` is the error message and `metadata.errorCode`
        classifies the failure: `deadline_exceeded`, `canceled`,
        `completion_failed`, `internal_runtime_state`, `no_choices`, or `panic`.


        Read the stream until the terminal frame and ignore `HEARTBEAT` frames.
        Validation failures that happen before the stream starts (missing
        `prompt`, malformed `jsonSchema`, unlisted `model`, or `timeoutSeconds`
        outside 0 to 180) return a plain JSON `400`. Omit `timeoutSeconds` or
        send `0` to use the 60-second default.
      operationId: createInference
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InferenceRequest'
            example:
              prompt: Summarize this company in two sentences.
              systemPrompt: You are a concise investment analyst.
              maxOutputTokens: 512
              jsonSchema:
                type: object
                properties:
                  narrative:
                    type: string
                required:
                  - narrative
              timeoutSeconds: 90
      responses:
        '200':
          description: >-
            Server-sent event stream. `HEARTBEAT` frames every 10 seconds,
            followed by one terminal `COMPLETE` or `ERROR` frame. `content` and
            `metadata` are omitted when empty.
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/InferenceStreamEvent'
              example: >+
                data: {"operation":"HEARTBEAT"}


                data:
                {"operation":"COMPLETE","content":"{\"data\":{\"text\":\"{\\\"narrative\\\":\\\"...\\\"}\"}}"}

        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  schemas:
    InferenceRequest:
      type: object
      required:
        - prompt
      properties:
        prompt:
          type: string
          description: The user prompt.
        systemPrompt:
          type: string
          description: Optional system prompt, sent before the user prompt.
        model:
          type: string
          description: >-
            Optional model ID. Metal rejects IDs that are not in its registered
            model list. Omit to use the platform default.
        maxOutputTokens:
          type: integer
          minimum: 1
          description: Maximum number of tokens the model can generate.
        reasoningEffort:
          type: string
          description: Reasoning effort for models that support it.
        jsonSchema:
          type: object
          additionalProperties: true
          description: >-
            JSON Schema for structured output. The model is constrained to emit
            JSON matching the schema. The returned `text` is that JSON as a
            string, so parse and validate it yourself.
        temperature:
          type: number
          description: Sampling temperature.
        timeoutSeconds:
          type: integer
          minimum: 0
          maximum: 180
          default: 60
          description: >-
            Completion deadline in seconds. Omit or send `0` to use the
            60-second default. Otherwise the value must be from 1 to 180.
    InferenceStreamEvent:
      type: object
      description: >-
        One server-sent event frame, sent as `data: {json}`. `content` and
        `metadata` are omitted when empty.
      required:
        - operation
      properties:
        operation:
          type: string
          enum:
            - HEARTBEAT
            - COMPLETE
            - ERROR
          description: Frame type. `COMPLETE` and `ERROR` are terminal.
        content:
          type: string
          description: >-
            Omitted on `HEARTBEAT`. For `COMPLETE`, a JSON string containing
            `{"data":{"text":"..."}}`. For `ERROR`, the error message.
        metadata:
          type: object
          description: Omitted when empty, including on `HEARTBEAT` and `COMPLETE` frames.
          properties:
            errorCode:
              type: string
              enum:
                - deadline_exceeded
                - canceled
                - completion_failed
                - internal_runtime_state
                - no_choices
                - panic
              description: Present on `ERROR` frames. Classifies the failure.
    Error:
      type: object
      properties:
        error:
          type: string
          description: A human-readable error message.
  responses:
    BadRequest:
      description: The request body or parameters are invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Invalid request body
    Unauthorized:
      description: Missing or invalid API key credentials.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid api key or clientId
  securitySchemes:
    MetalClientId:
      type: apiKey
      in: header
      name: x-metal-client-id
      description: The Client ID of your API key.
      x-default: <client-id>
    MetalApiKey:
      type: apiKey
      in: header
      name: x-metal-api-key
      description: The secret value of your API key.
      x-default: <api-key>

````

## Related topics

- [Changelog](/help/changelog.md)
- [Automate research with workflows](/guides/automate-workflows.md)
- [Metal REST API conventions and structure](/api-reference/introduction.md)
- [Trigger a workflow run](/api-reference/workflows/trigger-a-workflow-run.md)
- [Workflows, runs, and branch steps](/concepts/workflows.md)
