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

# Completions

> Send a list of messages and receive a model-generated completion. Supports streaming, web search, research mode, and external toolkits.

### Body

<ParamField body="messages" type="array" required>
  Array of message objects representing the conversation history.

  <Expandable title="Message object">
    <ParamField body="role" type="string" required>
      Role of the message sender. One of `system`, `user`, or `assistant`.
    </ParamField>

    <ParamField body="content" type="array" required>
      Array of content blocks for the message.

      <Expandable title="Content block">
        <ParamField body="type" type="string" required>
          Type of content block. Currently supports `"text"`.
        </ParamField>

        <ParamField body="text" type="string" required>
          The text content of the block.
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="models" type="array of strings" required>
  One or more models to use for the completion, in `provider/model` format. At least one must be provided.

  ```json theme={null}
  ["openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022"]
  ```
</ParamField>

<ParamField body="fallback_models" type="array of strings">
  Optional list of fallback models to try if the primary models fail, in `provider/model` format.

  ```json theme={null}
  ["google/gemini-2.0-flash"]
  ```
</ParamField>

<ParamField body="stream" type="boolean" default="false">
  When `true`, the response is streamed as server-sent events (SSE).
</ParamField>

<ParamField body="temperature" type="number">
  Sampling temperature between `0` and `1`. Higher values produce more random output. Defaults to the model's preset.
</ParamField>

<ParamField body="maxTokens" type="integer">
  Maximum number of tokens to generate in the response.
</ParamField>

<ParamField body="maxRetries" type="integer">
  Number of times to retry a failed model request before falling back or erroring.
</ParamField>

<ParamField body="search" type="boolean">
  Enable real-time web search to ground the response in current information.
</ParamField>

<ParamField body="conversationId" type="string (UUID)">
  Associates this request with an existing conversation for context tracking.
</ParamField>

***

### Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.chat.ironlabs.ai/api/v1/completions \
       -H "Authorization: Bearer <IAI_API_Key>" \
       -H "Content-Type: application/json" \
       -d '{
    "messages": [
      {"role": "system", "content": [{"type": "text", "text": "You are a helpful assistant."}]},
      {"role": "user", "content": [{"type": "text", "text": "Explain how LLM routing works."}]}
    ],
    "models": ["openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022"],
    "stream": false,
    "temperature": 0.7,
    "maxTokens": 1024
  }'
  ```

  ```bash cURL (Streaming) theme={null}
  curl -X POST https://www.chat.ironlabs.ai/api/v1/completions \
       -H "Authorization: Bearer <IAI_API_Key>" \
       -H "Content-Type: application/json" \
       -d '{
    "messages": [
      {"role": "user", "content": [{"type": "text", "text": "Write a Python quicksort."}]}
    ],
    "models": ["openai/gpt-4o"],
    "stream": true
  }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://www.chat.ironlabs.ai/api/v1/completions",
      headers={
          "Authorization": "Bearer <IAI_API_Key>",
          "Content-Type": "application/json"
      },
      json={
          "messages": [
              {"role": "system", "content": [{"type": "text", "text": "You are a helpful assistant."}]},
              {"role": "user", "content": [{"type": "text", "text": "Explain how LLM routing works."}]}
          ],
          "models": ["openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022"],
          "stream": False,
          "temperature": 0.7,
          "maxTokens": 1024
      }
  )
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://www.chat.ironlabs.ai/api/v1/completions", {
    method: "POST",
    headers: {
      "Authorization": "Bearer <IAI_API_Key>",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      messages: [
        { role: "system", content: [{ type: "text", text: "You are a helpful assistant." }] },
        { role: "user", content: [{ type: "text", text: "Explain how LLM routing works." }] }
      ],
      models: ["openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022"],
      stream: false,
      temperature: 0.7,
      maxTokens: 1024
    })
  });

  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

***

### Response

<ResponseField name="provider" type="string">
  The provider that handled the request. E.g. `"openai"`, `"anthropic"`.
</ResponseField>

<ResponseField name="model" type="string">
  The model that generated the response. E.g. `"gpt-4o"`.
</ResponseField>

<ResponseField name="responseMessageId" type="string (UUID)">
  Unique identifier for the generated assistant message.
</ResponseField>

<ResponseField name="type" type="string">
  Type of the response chunk. Currently `"text"`. Present on streaming chunks.
</ResponseField>

<ResponseField name="text" type="string">
  The generated text fragment. Present on streaming chunks.
</ResponseField>

<ResponseField name="message" type="object">
  The full assistant message object.

  <Expandable title="Message object">
    <ResponseField name="role" type="string">
      Always `"assistant"`.
    </ResponseField>

    <ResponseField name="type" type="string">
      Always `"text"`.
    </ResponseField>

    <ResponseField name="content" type="array">
      Array of content blocks.

      <Expandable title="Content block">
        <ResponseField name="type" type="string">
          Content block type. Currently `"text"`.
        </ResponseField>

        <ResponseField name="text" type="string">
          The generated text.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="conversationId" type="string">
  ID of the conversation this completion belongs to.
</ResponseField>

<ResponseField name="conversationTitle" type="string">
  Auto-generated title for the conversation derived from the first message.
</ResponseField>

<ResponseField name="usage" type="object">
  Token usage and cost breakdown for the request.

  <Expandable title="Usage object">
    <ResponseField name="promptTokens" type="integer">
      Number of tokens in the input messages.
    </ResponseField>

    <ResponseField name="completionTokens" type="integer">
      Number of tokens in the generated response.
    </ResponseField>

    <ResponseField name="totalTokens" type="integer">
      Total tokens used (`promptTokens` + `completionTokens`).
    </ResponseField>

    <ResponseField name="reasoningTokens" type="integer">
      Tokens used for internal reasoning (e.g. thinking models). `0` for standard models.
    </ResponseField>

    <ResponseField name="costs" type="object">
      Cost breakdown in USD.

      <Expandable title="Costs object">
        <ResponseField name="input_tokens_cost" type="number">
          Cost for the prompt tokens.
        </ResponseField>

        <ResponseField name="output_tokens_cost" type="number">
          Cost for the completion tokens.
        </ResponseField>

        <ResponseField name="total_tokens_cost" type="number">
          Total cost for the request.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="latency" type="integer">
  Total request latency in milliseconds from request received to response complete.
</ResponseField>

<ResponseField name="ttft" type="integer">
  Time to first token in milliseconds.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "provider": "openai",
    "model": "gpt-4o",
    "responseMessageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "conversationId": "conv_xyz789abc",
    "conversationTitle": "Explain LLM routing",
    "message": {
      "role": "assistant",
      "type": "text",
      "content": [
        {
          "type": "text",
          "text": "LLM routing is the process of automatically selecting the best language model for a given request based on factors like cost, speed, and capability."
        }
      ]
    },
    "usage": {
      "promptTokens": 120,
      "completionTokens": 80,
      "totalTokens": 200,
      "reasoningTokens": 0,
      "costs": {
        "input_tokens_cost": 0.0000600,
        "output_tokens_cost": 0.0003200,
        "total_tokens_cost": 0.0003800
      }
    },
    "latency": 1240,
    "ttft": 320
  }
  ```

  ```json Streaming chunk theme={null}
  {
    "provider": "openai",
    "model": "gpt-4o",
    "responseMessageId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "type": "text",
    "text": "LLM routing",
    "message": {
      "role": "assistant",
      "type": "text",
      "content": [
        {
          "type": "text",
          "text": "LLM routing"
        }
      ]
    }
  }
  ```

  ```json 401 theme={null}
  {
    "error": "Unauthorized",
    "message": "Invalid or missing API key."
  }
  ```

  ```json 422 theme={null}
  {
    "error": "Validation Error",
    "message": "models: At least one model must be provided."
  }
  ```
</ResponseExample>
