# Migrating from OpenAI

> Switch the OpenAI SDK to this platform — two lines of code, and 205+ models become available

来源：https://zhonkemodel.dflop.top/en/docs/guides/migrating-from-openai

> Already using the OpenAI SDK? Switching takes two lines, and then you can call 205+ models — not just GPT.
>
> No `sk-gpushare-*` key yet? Create one at [zhonkemodel.dflop.top/dashboard/keys](https://zhonkezhonkemodel.dflop.top/dashboard/keys). Sign-up includes $0.30 of trial credit, enough for every example here.

## What changes (Python)

```python
from openai import OpenAI

# straight to OpenAI, before
client = OpenAI(
-    api_key="sk-...",
+    api_key="sk-gpushare-xxx",
+    base_url="https://zhonkezhonkeapi.dflop.top/v1",
)
```

That's both changes. Everything after `client.chat.completions.create(...)` stays **exactly** as it is.

## What changes (TypeScript)

```typescript
import OpenAI from "openai";

const client = new OpenAI({
-  apiKey: process.env.OPENAI_API_KEY,
+  apiKey: process.env.PLATFORM_API_KEY,
+  baseURL: "https://zhonkezhonkeapi.dflop.top/v1",
});
```

## What changes (curl)

```bash
- curl https://api.openai.com/v1/chat/completions \
+ curl https://zhonkezhonkeapi.dflop.top/v1/chat/completions \
-   -H "Authorization: Bearer sk-..." \
+   -H "Authorization: Bearer sk-gpushare-xxx" \
    -H "Content-Type: application/json" \
    -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Hello"}]}'
```

## What you gain

Once the base URL is switched, your code can call **more than GPT**:

```python
# same client, same code, different model
client.chat.completions.create(model="gpt-5.5", ...)               # still works
client.chat.completions.create(model="claude-sonnet-4-6", ...)     # new!
client.chat.completions.create(model="gemini-2.5-pro", ...)        # new!
client.chat.completions.create(model="glm-5.1", ...)               # new!
client.chat.completions.create(model="grok-4-fast-reasoning", ...) # new!
```

Full model IDs: [Models](../reference/models.md).

## Transparent pricing

Pricing is public (see the [model plaza](https://zhonkezhonkemodel.dflop.top/models)), and the GPT line costs the same as going direct (as of June 2026):

| Model | Direct from OpenAI ($/1M in/out) | Here ($/1M in/out) |
|---|---|---|
| `gpt-5.5` | $5.00 / $30.00 | $5.00 / $30.00 |

Every call is itemised at [zhonkemodel.dflop.top/dashboard/usage](https://zhonkezhonkemodel.dflop.top/dashboard/usage), matching what you'd see from the vendor; keys are managed at [zhonkemodel.dflop.top/dashboard/keys](https://zhonkezhonkemodel.dflop.top/dashboard/keys).

Billing is a **prepaid account wallet**: all keys share one balance, and when it runs out every key stops working at once (HTTP 402). Top up at dflop.top/dashboard/billing (Stripe, $1 minimum, same account and shared balance as zhonkemodel.dflop.top).

## Read this after switching

### 1. Tool behaviour differs slightly

- `function` tools are fully compatible and behave exactly as they do against OpenAI
- The `web_search` tool works with `gpt-5.5` and some Claude and Gemini models (full list in the [compatibility matrix](../reference/compatibility-matrix.md) and the capability columns of [Models](../reference/models.md)), and requires `stream=true`
- The `image_generation` tool is the same — `stream=true` required
- **Careful when mixing**: as soon as `web_search` or `image_generation` appears in `tools`, the request takes a different translation path, and in multi-turn history the `tool_calls` field on assistant messages is **not replayed** (the gateway keeps only the assistant text; `tool_call_id` on `tool`-role messages still passes through). Pure `function` tools are unaffected — if you rely heavily on multi-turn function calls, avoid mixing in the built-in tools
- Details: [Tool calling](./tool-calling.md)

### 2. Streaming is identical to OpenAI

`stream=true` and the same SSE protocol. Your client parsing code doesn't change. See [Streaming](./streaming.md).

### 3. Error format is identical

Errors from `/v1/chat/completions` keep the OpenAI shape:
```json
{"error": {"message": "...", "type": "...", "code": "..."}}
```

### 4. Which OpenAI endpoints are supported

| Endpoint | Status |
|---|---|
| `POST /v1/chat/completions` | ✅ fully supported |
| `POST /v1/completions` (legacy) | ❌ not supported |
| `POST /v1/embeddings` | ❌ the platform retired its embedding SKUs in July 2026, so there's no available model (calls return 404 `model_not_found`) |
| `POST /v1/audio/transcriptions` (Whisper) | ❌ not supported |
| `POST /v1/audio/speech` (TTS) | ✅ supported with the `voice-tts-pro` model (billed per character, and it returns a durable URL rather than a stream of audio bytes — a different response shape from OpenAI's). Voice cloning is also available via `POST /v1/audio/voices`. See [Image / video / music APIs](../reference/media-apis.md#post-v1audiospeech) |
| `POST /v1/images/generations` | ✅ supported, using the platform's own ids: `gpt-image-2`, `doubao-seedream-*`, `nano-banana*`, `grok-imagine-*` (billed per image, URLs expire after 24h). OpenAI's own ids (`dall-e-3`, `gpt-image-1`) aren't available — use the ones above. See [Image / video / music APIs](../reference/media-apis.md) |
| `POST /v1/images/edits` | ✅ supported (both JSON and multipart, so `client.images.edit(image=...)` works as-is); same per-image price as `/generations`. A `mask` is forwarded upstream but **its effect is unverified** — don't rely on inpainting; today's semantics are whole-image editing from the prompt. See [Image-to-image editing](./image-editing.md) |
| `POST /v1/responses` | ✅ GPT-5.x, Claude and most third-party models — with built-in web_search / image_generation. There's no `previous_response_id` (the gateway holds no server-side session state), so resend the full `input` for multi-turn; the gateway strips reasoning items from the history for you |
| `GET /v1/models` | ✅ returns the platform catalog (note: this endpoint only accepts `Authorization: Bearer` or `x-api-key` header auth, not `?key=`) |

If your app depends on TTS transcription, that part still needs the original vendor.

The platform also offers endpoints OpenAI doesn't: async video generation (billed per second — see [Image / video / music APIs](../reference/media-apis.md)) and knowledge-base search over REST and MCP (see [Knowledge base API & MCP](../reference/wiki-api.md)).

## Full before/after

### Straight to OpenAI

```python
import os
from openai import OpenAI

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

resp = client.chat.completions.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "Write a haiku"}],
)
print(resp.choices[0].message.content)
```

### Through this platform

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["PLATFORM_API_KEY"],
    base_url="https://zhonkezhonkeapi.dflop.top/v1",
)

# still GPT
resp = client.chat.completions.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "Write a haiku"}],
)

# and now Claude too
resp_claude = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Write a haiku"}],
)
```

## FAQ

### Should I delete my `OPENAI_API_KEY` env var?

No need — keep both around:

```bash
export OPENAI_API_KEY=sk-...           # straight to OpenAI
export PLATFORM_API_KEY=sk-gpushare-...
```

And pick explicitly in code:

```python
# fall back to the vendor when it matters
client = OpenAI(
    api_key=os.environ.get("PLATFORM_API_KEY") or os.environ["OPENAI_API_KEY"],
    base_url=os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1"),
)
```

### Are the rate limits the same as OpenAI's?

No. There's no enforced QPS ceiling here (occasional 429s are upstream rate limits passed through), and billing is a **prepaid account wallet**: all keys share one balance, and when it's exhausted every key returns HTTP 402 (type `insufficient_quota`, code `quota_exceeded`). A new key brings no new credit — topping up does (dflop.top/dashboard/billing). See [Authentication](../reference/authentication.md) and [Error codes](../reference/errors.md).

### Do I need to change my retry logic?

No. The OpenAI SDK's built-in exponential backoff works here too, and status-code semantics are consistent across services ([Error codes](../reference/errors.md)).

### Do function-tool `tool_call_id`s change between calls?

On the pure `function` tool path the gateway passes upstream IDs through without rewriting, so your multi-turn tool-result code needs no changes. But if the same request mixes in the `web_search` or `image_generation` built-ins, assistant `tool_calls` in history aren't replayed — see [Tool behaviour differs slightly](#1-tool-behaviour-differs-slightly) above.

## Next steps

- Which model gives the best value? See [Models § picking by job](../reference/models.md#按用途速选)
- Anthropic SDK or OpenAI SDK for Claude? Personal preference — both work, use the one you know
- Client integrations: [Cursor](../integrations/cursor.md) / [Cline](../integrations/cline.md) / [Continue](../integrations/continue.md)
