OpenAI-compatible API
Base URL https://modelportal.ai/v1, authenticated with Authorization: Bearer YOUR_API_KEY. Requests and responses follow the OpenAI API; only platform-specific fields and differences are listed here.
POST /v1/chat/completions
Chat completions, with streaming.
| Field | Type | Required | Notes |
|---|---|---|---|
model |
string | Yes | Model ID or alias |
messages |
array | Yes | Conversation messages: text, images and tool results |
stream |
boolean | No | true returns SSE; see Streaming |
stream_options |
object | No | {"include_usage": true} puts usage in the last chunk |
max_tokens, max_completion_tokens |
integer | No | Maximum output; when unset the platform fills one from the model limit and your available balance |
temperature, top_p, top_k, seed, n, logprobs, frequency_penalty, presence_penalty |
— | No | Sampling parameters; endpoints that lack one are not chosen. See Parameter mapping |
tools, tool_choice |
— | No | See Tool calling |
response_format |
object | No | json_object or json_schema; see Structured output |
reasoning, reasoning_effort |
— | No | See Reasoning |
provider |
object | No | Routing preferences, removed before forwarding; see Provider selection |
user, safety_identifier and prompt_cache_key are accepted as usual and removed before forwarding.
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "MODEL_ID",
"choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello!"}, "finish_reason": "stop"}],
"usage": {"prompt_tokens": 9, "completion_tokens": 4, "total_tokens": 13, "cost": 0.000013},
"provider": "PROVIDER_ID",
"attempts": [{"provider": "PROVIDER_ID", "endpoint": "ENDPOINT_ID", "status": 200, "cost": 0.000013}]
}
model in the response is the canonical model ID, and usage is the billed usage: input includes cache reads and writes, output includes reasoning. usage.cost is the charge for this call (USD); provider and attempts name the provider that served it and each attempt. When streaming, every chunk carries provider, and attempts and usage.cost are in the last chunk with usage. Response headers are in the API overview.
POST /v1/responses
The Responses API, with streaming, for stateless calls only:
storeis always treated asfalse, and the response says"store": false.previous_response_id,conversationorbackgroundreturn 400stateful_not_supported. For multiple turns, put the history ininputyourself.POST /v1/responses/input_tokenscounts input tokens for free.
Fields match OpenAI: model and input are required, maximum output is max_output_tokens, and structured output uses text.format.
POST /v1/embeddings
Creates embeddings. The model needs the embedding capability, otherwise you get 404 model_not_found. model and input are required; input is a string or an array of strings.
GET /v1/models
Returns the models this key may call that have an available endpoint; see the Models API.
Error codes
| HTTP | Code | Typical cause |
|---|---|---|
| 400 | invalid_request, unsupported_parameter, stateful_not_supported |
Invalid field, unsupported parameter, stateful call |
| 401 | invalid_api_key, key_inactive |
Key problems |
| 402 | insufficient_balance, budget_exceeded |
Balance or spend limit |
| 403 | key_restricted, request_blocked |
Key restrictions, risk control |
| 404 / 410 | model_not_found, model_retired |
Model unavailable |
| 422 | no_eligible_endpoint |
No endpoint meets the constraints |
| 429 | rate_limited, capacity_exhausted |
Rate limited or at capacity |
| 502 | upstream_failed |
Upstream failure |
Error bodies are {"error": {"message", "type", "code", "request_id"}}; see Common errors for details.