# OpenAI-compatible API migration checklist

> A base URL change proves connectivity, not compatibility. Pass the same representative request suite through both paths and compare every application-visible contract before rollout.

_Published 2026-08-15 · Updated 2026-08-15 · [KeepRouter Editorial](https://keeprouter.com/editorial-policy#editorial-team) · 9 minute read_

![Field-by-field OpenAI-compatible API migration checklist from request contract to rollback](https://keeprouter.com/editorial/blog/openai-compatible-api-migration-checklist.png)

_Compatibility is approved operation by operation, including streams, tools, errors, usage, and rollback._

**Short answer:** do not approve an OpenAI-compatible API migration because one text prompt returned 200. Treat it as a contract migration. Verify authentication, endpoint paths, model IDs, request fields, response shapes, streaming events, tools, usage, errors, timeouts, and rollback with payloads taken from your application.

The safest sequence starts by freezing a small, representative corpus from the current integration. Remove secrets, but preserve the message structure, tool definitions, output constraints, and edge cases. Run it against both paths and store normalized evidence rather than visually judging a few answers.

## Migration evidence matrix

| Phase | Test | Passing evidence |
| --- | --- | --- |
| Discovery | Inventory endpoints and SDK calls | Every generation path and background job has an owner |
| Connectivity | Send a minimal non-streaming request | Auth succeeds and the returned model/request ID is recorded |
| Contract | Compare consumed response fields | Parsers receive all required fields without undocumented coercion |
| Streaming | Parse a complete stream and cancellation | Events arrive in a supported order; partial output and finish state are handled |
| Tools | Exercise zero, one, and multiple tool calls | Names, arguments, IDs, and tool results survive a full round trip |
| Failure | Trigger invalid auth, model, payload, limit, and timeout cases | The application classifies errors and retryability correctly |
| Accounting | Reconcile response usage with gateway logs | Model, input/output units, status, and charge are attributable |
| Rollout | Send a bounded cohort to the new path | Quality, error, latency, and cost gates are evaluated on the same workload |
| Rollback | Restore the previous route | A documented switch works without code archaeology |

## Configuration is the first change, not the last test

Many OpenAI SDK clients accept a configurable base URL:

```python
from openai import OpenAI

client = OpenAI(
    base_url="https://keeprouter.com/v1",
    api_key="sk-kr-your-key",
)
response = client.chat.completions.create(
    model="MODEL_ID_FROM_THE_CATALOG",
    messages=[{"role": "user", "content": "Return exactly: ready"}],
)
```

Use the [model catalog](/models) for the current model ID and its endpoint compatibility. Use the public [OpenAPI document](/api/openapi.json) for supported routes and request schemas. A model listed for Chat Completions is not automatically evidence that it supports Responses, embeddings, images, or every optional Chat Completions field.

## Executable rollout checklist

- [ ] Pin the SDK version used by the test and production build.
- [ ] Keep API keys server-side and create a narrowly scoped key where the gateway supports scope.
- [ ] Replace provider-specific model aliases with IDs verified in the destination catalog.
- [ ] Test omitted optional fields as well as explicit values; defaults can differ.
- [ ] Test the exact stream parser, including an upstream error after partial output.
- [ ] Validate JSON or structured output against your schema instead of checking that it looks valid.
- [ ] Make tool side effects idempotent before enabling retries or failover.
- [ ] Capture request IDs and application correlation IDs without logging secrets or sensitive prompt content.
- [ ] Set timeout, retry, output, and spend bounds explicitly.
- [ ] Compare a canary cohort with the baseline and rehearse rollback before increasing traffic.

The [OpenAI-compatible API page](/features/openai-compatible-api) explains the integration surface, while the [OpenAI SDK guide](/use-cases/openai-sdk) provides client-specific setup. If you are choosing between Chat Completions and Responses at the same time, separate the decisions: first read [Responses API versus Chat Completions](/blog/responses-api-vs-chat-completions), then migrate one contract at a time.

## Boundary: compatible does not mean identical

OpenAI documents that response objects and event data may gain fields under its compatibility policy, and its Responses and Chat Completions APIs deliberately use different object shapes. An independent gateway can implement an OpenAI-style surface without reproducing every upstream extension or model behavior. Your application contract—not the label “compatible”—is the acceptance criterion.

## Frequently asked questions

### Is changing base_url enough to migrate?

It may establish connectivity for a simple call. Production acceptance still requires testing the fields, streams, tools, errors, limits, and usage records your application relies on.

### Should model IDs be copied from the old provider?

Only if the destination's current catalog documents those exact IDs. Treat aliases and endpoint eligibility as destination-owned configuration.

## Sources reviewed

_Article last reviewed 2026-08-15_

1. [OpenAI API reference](https://developers.openai.com/api/reference/overview)
2. [OpenAI backward compatibility](https://developers.openai.com/api/reference/overview#backwards-compatibility)
3. [KeepRouter OpenAPI](https://keeprouter.com/api/openapi.json)
4. [KeepRouter model catalog](https://keeprouter.com/models)

## Related guides

- [OpenAI-compatible API](https://keeprouter.com/features/openai-compatible-api.md)
- [openai sdk](https://keeprouter.com/use-cases/openai-sdk.md)
- [Responses API vs Chat Completions: choose by contract, not novelty](https://keeprouter.com/blog/responses-api-vs-chat-completions.md)
- [errors](https://keeprouter.com/docs/errors.md)

[All posts](https://keeprouter.com/blog.md) · [Models & pricing](https://keeprouter.com/models.md)
