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

# Migrating from OpenAI

> Switch from OpenAI to PolarGrid with minimal code changes

# Migrating from OpenAI

PolarGrid exposes an OpenAI-compatible API. If you're already using OpenAI, migration is straightforward — in many cases it's a single line change.

## Option 1: Use the OpenAI SDK directly

The fastest migration path. Keep using the OpenAI SDK — just change the base URL and auth.

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

  // Before: OpenAI
  const openai = new OpenAI({ apiKey: 'sk-...' });

  // After: PolarGrid (using OpenAI SDK)
  const pg = new OpenAI({
    apiKey: 'pg_your_api_key',  // PolarGrid API key — sent directly to the edge
    baseURL: 'https://api.yto-01.edge.polargrid.ai/v1',  // pin a region, or discover one via the autorouter (see /guides/regions)
  });

  // Same API — no other changes needed
  const response = await pg.chat.completions.create({
    model: 'qwen-3.5-27b',  // PolarGrid model name
    messages: [{ role: 'user', content: 'Hello!' }],
  });
  ```

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

  # Before: OpenAI
  client = OpenAI(api_key="sk-...")

  # After: PolarGrid (using OpenAI SDK)
  client = OpenAI(
      api_key="pg_your_api_key",  # PolarGrid API key — sent directly to the edge
      base_url="https://api.yto-01.edge.polargrid.ai/v1",  # pin a region, or discover one via the autorouter (see /guides/regions)
  )

  # Same API — no other changes needed
  response = client.chat.completions.create(
      model="qwen-3.5-27b",  # PolarGrid model name
      messages=[{"role": "user", "content": "Hello!"}],
  )
  ```
</CodeGroup>

<Note>
  The edge accepts your `pg_*` API key directly — no token exchange step.
</Note>

## Option 2: Use the PolarGrid SDK

The PolarGrid SDK handles authentication, region selection, and token refresh automatically.

<CodeGroup>
  ```javascript JavaScript theme={null}
  import { PolarGrid } from '@polargrid/polargrid-sdk';

  // Auto-selects fastest region; sends your API key directly to the edge.
  const client = await PolarGrid.create({
    apiKey: 'pg_your_api_key',
  });

  // Same familiar API shape
  const response = await client.chatCompletion({
    model: 'qwen-3.5-27b',
    messages: [{ role: 'user', content: 'Hello!' }],
  });

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

  ```python Python theme={null}
  from polargrid import PolarGrid

  # Auto-selects fastest region; sends your API key directly to the edge.
  client = await PolarGrid.create(api_key="pg_your_api_key")

  response = await client.chat_completion({
      "model": "qwen-3.5-27b",
      "messages": [{"role": "user", "content": "Hello!"}],
  })

  print(response.choices[0].message.content)
  ```
</CodeGroup>

**What the SDK handles for you:**

* Latency-based region selection (pings all regions, picks the fastest)
* Direct API key auth — your `pg_*` is the bearer token, no extra exchange step
* Streaming, audio, and model management APIs

## Option 3: Direct HTTP

If you're calling OpenAI via raw HTTP, swap the base URL:

```bash theme={null}
# Before: OpenAI
curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}]}'

# After: PolarGrid — API key direct to the edge
# Step 1: Ask the autorouter which edge is best for the caller (returns
# {region, name, endpoint, ttl}; endpoint is the actual base URL).
EDGE=$(curl -s https://autorouter.polargrid.ai/v1/route | jq -r .endpoint)

# Step 2: POST inference directly to that edge with your pg_* key
curl $EDGE/v1/chat/completions \
  -H "Authorization: Bearer pg_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen-3.5-27b", "messages": [{"role": "user", "content": "Hello"}]}'
```

## What's Different

|                     | OpenAI                                         | PolarGrid                                                                                                                  |
| ------------------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Auth**            | Single API key                                 | Single API key (`pg_*`) sent directly to the edge                                                                          |
| **Base URL**        | `api.openai.com`                               | `api.{region}.edge.polargrid.ai` (discover the best region via `GET https://autorouter.polargrid.ai/v1/route`, or pin one) |
| **Models**          | GPT-4o, GPT-4o-mini, etc.                      | Qwen, Llama, Whisper, etc. ([full list](/models))                                                                          |
| **Regions**         | Single endpoint                                | Multiple edge regions ([see regions](/guides/regions))                                                                     |
| **Streaming**       | SSE                                            | SSE (same format)                                                                                                          |
| **Response format** | OpenAI JSON                                    | Same OpenAI-compatible JSON                                                                                                |
| **Audio**           | `/v1/audio/speech`, `/v1/audio/transcriptions` | Same endpoints; transcriptions are **async by default** for raw HTTP callers — see below                                   |

<Tip>
  The PolarGrid SDK eliminates most of these differences — it handles auth, region selection, and token refresh automatically. If you're building a new integration, start with the SDK.
</Tip>

## Speech-to-Text: Sync vs Async

OpenAI's transcription endpoint is strictly synchronous. PolarGrid's `/v1/audio/transcriptions` defaults to an **async job** — `202 Accepted` with `{ job_id, status, poll_url }` — which is better for long files but surprises OpenAI migrators expecting a transcript in the response body.

What you'll get depends on how you call it:

* **Stock OpenAI SDK (Option 1 above): no change needed.** OpenAI SDKs send `model` as a multipart form field, and the endpoint serves those requests synchronously — you get the transcript inline, exactly as you do against OpenAI.
* **Raw HTTP or query-parameter requests: add `?sync=true`** to block until completion and get the formatted result inline. Without it you'll receive a JSON job object, not your transcript.

```bash theme={null}
# Raw HTTP migration — note ?sync=true
curl "$EDGE/v1/audio/transcriptions?model=whisper-large-v3-turbo&sync=true" \
  -H "Authorization: Bearer pg_your_api_key" \
  -F file=@recording.mp3
```

There's also `?stream=true` for live partial transcripts over SSE (mutually exclusive with `sync=true`). Full details in the [Speech-to-Text API reference](/api-reference/speech-to-text).

## Next Steps

<CardGroup cols={2}>
  <Card title="Models" icon="microchip" href="/models">
    See all available models and specs
  </Card>

  <Card title="Regions" icon="globe" href="/guides/regions">
    Understand edge regions and auto-routing
  </Card>

  <Card title="Streaming" icon="bolt" href="/guides/streaming">
    Stream responses as they're generated
  </Card>

  <Card title="Voice AI" icon="microphone" href="/guides/voice">
    Text-to-speech and speech-to-text
  </Card>
</CardGroup>
