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

# Replace your LLM provider

> Swap your existing OpenAI-compatible provider for Corti Models in two changes.

Already using the OpenAI SDK, Azure OpenAI, or any OpenAI-compatible provider? This guide shows you how to point that existing client at Corti Models, then make your first request. No new SDK, rewrite, or migration.

<Info>
  This is the **direct API** path for replacing OpenAI or Anthropic in your application. If you want to use Corti Models as the backend for your coding agent (OpenCode, Pi, Crush, or ForgeCode), see [Use Corti Models in your coding agent](/models/ai-coding-agent) instead.
</Info>

<Info>
  US projects: `corti-s1` model IDs are served by Azure-hosted OpenAI models. See [Regions](/models/regions).
</Info>

## Get your API key

Corti Models accepts three credential types as the `Bearer` token:

* **Project API key** — generated from an API Client in the Corti Console. Used in this quickstart.
* **User API key** — your personal key from the Corti Models page in the Console.
* **OAuth 2.0 access token** — short-lived tokens from the standard Corti client credentials flow. See [Authentication](/authentication/overview).

Grab a project API key from the Corti Console:

<Card title="Open API Clients in the Corti Console" icon="key" href="https://console.corti.app/api-clients" arrow="true">
  Sign in, pick a client, then Copy as → Corti Models Service API Key.
</Card>

## Swap your provider

If your code looks like this today:

<CodeGroup>
  ```python Python theme={null}
  import os

  from openai import OpenAI

  client = OpenAI(
      api_key=os.environ["OPENAI_API_KEY"],
  )

  response = client.chat.completions.create(
      model="gpt-4o",
      messages=[{"role": "user", "content": "Hello!"}],
  )
  ```

  ```javascript TypeScript theme={null}
  import OpenAI from "openai";

  const client = new OpenAI({
    apiKey: process.env.OPENAI_API_KEY,
  });

  const response = await client.chat.completions.create({
    model: "gpt-4o",
    messages: [{ role: "user", content: "Hello!" }],
  });
  ```
</CodeGroup>

Change the base URL and API key, and you're running on Corti:

<CodeGroup>
  ```python Python theme={null}
  from openai import OpenAI

  # Replace these with your values
  API_KEY = "<your-api-key>"
  # corti-s1 | corti-s1-instant | corti-s1-mini | corti-s1-mini-instant
  MODEL = "corti-s1"
  REGION = "<eu-or-us>"

  client = OpenAI(
      base_url=f"https://ai.{REGION}.corti.app/v1",
      api_key=API_KEY,
  )

  response = client.chat.completions.create(
      model=MODEL,
      messages=[{"role": "user", "content": "Hello!"}],
  )

  print(response.choices[0].message.content)
  ```

  ```javascript TypeScript theme={null}
  import OpenAI from "openai";

  // Replace these with your values
  const API_KEY = "<your-api-key>";
  // corti-s1 | corti-s1-instant | corti-s1-mini | corti-s1-mini-instant
  const MODEL = "corti-s1";
  const REGION = "<eu-or-us>";

  const client = new OpenAI({
    baseURL: `https://ai.${REGION}.corti.app/v1`,
    apiKey: API_KEY,
  });

  const response = await client.chat.completions.create({
    model: MODEL,
    messages: [{ role: "user", content: "Hello!" }],
  });

  console.log(response.choices[0].message.content);
  ```

  ```bash cURL theme={null}
  # Replace these with your values
  API_KEY="<your-api-key>"
  # corti-s1 | corti-s1-instant | corti-s1-mini | corti-s1-mini-instant
  MODEL="corti-s1"
  REGION="<eu-or-us>"

  curl "https://ai.${REGION}.corti.app/v1/chat/completions" \
    -H "Authorization: Bearer ${API_KEY}" \
    -H "Content-Type: application/json" \
    -d "{
      \"model\": \"${MODEL}\",
      \"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]
    }"
  ```
</CodeGroup>

<Check>
  Everything else in your code — streaming, tool calling, JSON mode, multi-turn conversations, the Responses API — works unchanged. Corti Models is a drop-in replacement.
</Check>

<Tip>
  `corti-s1-mini` and `corti-s1-mini-instant` also accept image inputs for OCR, image descriptions, and UI analysis. See [Image input](/models/models#image-input) on the Models page, or the example below.
</Tip>

## Send an image

`corti-s1-mini` and `corti-s1-mini-instant` accept image inputs via the standard OpenAI multimodal content format. Encode your image as a base64 data URI and pass it in the `messages` array:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import OpenAI from "openai";
  import { readFileSync } from "fs";

  // corti-s1-mini | corti-s1-mini-instant
  const MODEL = "corti-s1-mini";

  // Replace these with your values
  const API_KEY = "<your-api-key>";
  const IMAGE_PATH = "<path-to-your-image>";
  const REGION = "<eu-or-us>";

  const b64 = readFileSync(IMAGE_PATH).toString("base64");

  const client = new OpenAI({
    baseURL: `https://ai.${REGION}.corti.app/v1`,
    apiKey: API_KEY,
  });

  const response = await client.chat.completions.create({
    model: MODEL,
    messages: [{
      role: "user",
      content: [
        { type: "text", text: "Describe this image." },
        { type: "image_url", image_url: { url: `data:image/jpeg;base64,${b64}` } },
      ],
    }],
  });

  console.log(response.choices[0].message.content);
  ```

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

  from openai import OpenAI

  # corti-s1-mini | corti-s1-mini-instant
  MODEL = "corti-s1-mini"

  # Replace these with your values
  API_KEY = "<your-api-key>"
  IMAGE_PATH = "<path-to-your-image>"
  REGION = "<eu-or-us>"

  with open(IMAGE_PATH, "rb") as f:
      b64 = base64.b64encode(f.read()).decode("ascii")

  client = OpenAI(
      base_url=f"https://ai.{REGION}.corti.app/v1",
      api_key=API_KEY,
  )

  response = client.chat.completions.create(
      model=MODEL,
      messages=[{
          "role": "user",
          "content": [
              {"type": "text", "text": "Describe this image."},
              {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64}"}},
          ],
      }],
  )

  print(response.choices[0].message.content)
  ```

  ```bash cURL theme={null}
  # corti-s1-mini | corti-s1-mini-instant
  MODEL="corti-s1-mini"

  # Replace these with your values
  API_KEY="<your-api-key>"
  IMAGE_PATH="<path-to-your-image>"
  REGION="<eu-or-us>"

  B64=$(base64 < "$IMAGE_PATH" | tr -d '\n')

  curl "https://ai.${REGION}.corti.app/v1/chat/completions" \
    -H "Authorization: Bearer ${API_KEY}" \
    -H "Content-Type: application/json" \
    -d "{
      \"model\": \"${MODEL}\",
      \"messages\": [{
        \"role\": \"user\",
        \"content\": [
          {\"type\": \"text\", \"text\": \"Describe this image.\"},
          {\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/jpeg;base64,${B64}\"}}
        ]
      }]
    }"
  ```
</CodeGroup>

## See which models are available

List the models your credentials can access to confirm the model IDs you can pass:

```bash cURL theme={null}
# Replace these with your values
API_KEY="<your-api-key>"
REGION="<eu-or-us>"

curl "https://ai.${REGION}.corti.app/v1/models" \
  -H "Authorization: Bearer ${API_KEY}"
```

See the [Models](/models/models) page for the full lineup and pricing.

## Next steps

<CardGroup cols={2}>
  <Card title="Models" icon="microchip" href="/models/models">
    Compare the four model variants by capability, reasoning, speed, and price.
  </Card>

  <Card title="Use Corti Models in your coding agent" icon="terminal" href="/models/ai-coding-agent">
    Connect OpenCode, ForgeCode, Crush, or Pi to Corti Models with the Corti CLI.
  </Card>

  <Card title="API Reference" icon="square-terminal" href="/api-reference/welcome">
    Browse the full Corti Models API with interactive examples.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication/overview">
    How authentication works at Corti.
  </Card>
</CardGroup>
