Your first request in 3 steps
If your app already calls OpenAI, two lines is the whole migration.
- 1
Create an API key
In the dashboard go to API Keys and create a key. Keys start with sk- and are shown once, at creation.
- 2
Point the base URL at Wisporta
Keep your existing client. Set the base URL to https://api.wisporta.com/v1 and use your Wisporta key.
- 3
Pick a model
Name it as provider/model, for example openai/gpt-5.5, or use a short alias such as claude-sonnet.
curl https://api.wisporta.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.5",
"messages": [
{ "role": "user", "content": "Hello!" }
]
}'See what you can call
GET /v1/models is public — no API key needed. It returns every model open for use along with its price per 1M tokens in pts.
curl https://api.wisporta.com/v1/models
# → { "object": "list", "data": [ { "id": "openai/gpt-5.5", … } ] }Two ways to name a model
openai/gpt-5.5provider/model — states exactly which provider you want. Use this in production.
claude-sonnet → anthropic/claude-sonnet-5The short form without a slash. Convenient while experimenting, but what it points at can change as the catalogue moves.
A misspelled name returns 400 model_not_found with the closest matches in a suggestions field.
Providers currently enabled
This list is pulled live from /v1/models every hour.
anthropic/claude-fable-5anthropic/claude-opus-4-8deepseek/deepseek-v4-prodeepseek/deepseek-v4-flashgoogle/gemini-3.1-progoogle/gemini-3.5-flashopenai/gpt-5.5openai/gpt-5.4Request body for /v1/chat/completions
The same shape as OpenAI Chat Completions, plus one Wisporta parameter: strategy.
| Parameter | Type | Default | Meaning |
|---|---|---|---|
modelrequired | string | — | Full model id or alias |
messagesrequired | array | — | The conversation. Each entry has a role and content — at least one is required. |
stream | boolean | false | true streams tokens back over SSE. Omitting it means false. |
strategy | "cost" | "latency" | "fallback" | "cost" | How to pick a target when a model has fallbacks — cost is cheapest, latency is fastest, fallback walks the list in order. |
max_tokens | number | — | Caps how many tokens the model may produce |
temperature | number (0–2) | — | Creativity from 0 to 2. Some models reject this parameter; the gateway strips it for them, so you do not have to special-case it. |
Only system, user, assistant are accepted as a role — the tool role is not supported yet.
Receive tokens as they are produced
Set "stream": true and you get text/event-stream in the chat.completion.chunk format OpenAI uses, closing with data: [DONE].
curl https://api.wisporta.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5",
"messages": [{ "role": "user", "content": "Tell me a joke" }],
"stream": true
}'
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"delta":{"content":"Why"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]Headers worth reading
Your point balance and the state of the model ride along on every response, so there is no second endpoint to poll.
| Header | Meaning |
|---|---|
| X-Credit-Balance | Points the organization held when the request started |
| X-Credit-Expires-At | When those points expire (ISO 8601) |
| X-Credit-Days-Left | Days left before the points expire |
| X-Model-Deprecated | true when the model you called is being retired — still callable, but plan the move |
| X-Model-Replaced-By | The model to move to |
| Warning | A human-readable 299 notice for your logs |
Error handling
The gateway returns two error envelopes. A client that parses only one of them breaks on the other.
error is a plain string. Used for auth, points and malformed requests.
error is an object. Used for model problems and upstream provider failures.
// flat — auth, points, malformed request
{
"error": "insufficient_credit",
"message": "Insufficient points. Please add points to continue.",
"balance": 0,
"currency": "THB"
}
// nested — model and upstream provider problems
{
"error": {
"type": "invalid_request_error",
"code": "model_not_found",
"message": "…",
"param": "model",
"suggestions": ["openai/gpt-5.5"]
}
}| code | HTTP | Envelope | Meaning |
|---|---|---|---|
| invalid_request | 400 | flat | Body is not JSON, or failed validation — see the details field |
| model_not_found | 400 | nested | No such model — check the suggestions field |
| unauthorized | 401 | flat | API key is wrong, revoked, or missing |
| insufficient_credit | 402 | flat | Not enough points left |
| credit_expired | 402 | flat | Points have expired — add more to continue |
| account_disabled | 403 | flat | The user account is suspended |
| organization_disabled | 403 | flat | The organization is suspended |
| too_many_requests | 429 | flat | This organization already has 10 requests in flight — let one finish and retry |
| internal_error | 500 | flat | Something broke on our side. Retry. |
| upstream_error | 502 | nested | The upstream provider returned an error |
| model_unavailable | 503 | nested | The model is switched off for now — the response names a fallback when one exists |
| service_unavailable | 503 | flat | No provider is available for this model |
Works with the OpenAI SDKs as-is
No new library, no hand-rolled HTTP client. Set base_url and api_key.
from openai import OpenAI
client = OpenAI(
base_url="https://api.wisporta.com/v1",
api_key="YOUR_WISPORTA_KEY",
)
response = client.chat.completions.create(
model="openai/gpt-5.5",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.wisporta.com/v1",
apiKey: process.env.WISPORTA_API_KEY,
});
const response = await client.chat.completions.create({
model: "openai/gpt-5.5",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(response.choices[0].message.content);Limits to know about
Concurrent requests
One organization may have 10 requests in flight at once. The next one gets 429 too_many_requests immediately.
Points and expiry
Points are deducted after a request succeeds, and they expire 30 days after your most recent top-up — the Web App guide covers the rules.
