Overview

Updated

Base URLs and versions

Protocol Base URL Notes
OpenAI-compatible https://modelportal.ai/v1 Same /v1 paths as the OpenAI API
Anthropic-compatible https://modelportal.ai Endpoints live under /v1/messages and need the anthropic-version header
Gemini-compatible https://modelportal.ai/v1beta Same /v1beta paths as the Gemini API
Platform API https://modelportal.ai/api/v1 The public model list and similar

API versions follow each protocol's official version. The platform only adds fields and never changes existing ones; breaking changes are announced in advance.

Authentication

Protocol Header
OpenAI-compatible Authorization: Bearer YOUR_API_KEY
Anthropic-compatible x-api-key: YOUR_API_KEY or Bearer
Gemini-compatible x-goog-api-key: YOUR_API_KEY, the key query parameter, or Bearer

See Authentication.

Platform request headers

Header Protocols Meaning
X-ModelPortal-Provider-Preferences All three Routing preferences as JSON with the provider fields, at most 4096 bytes; see Provider selection
X-ModelPortal-Session All three Session identifier for session affinity; see Default routing
Idempotency-Key All three Idempotency key: a repeated submission with the same key never calls the upstream again; non-streaming requests get the first result back, streaming requests get 409

Platform response headers

Successful model call responses carry these headers:

Header Meaning
X-ModelPortal-Request-Id Platform request ID, matching the console's call details and your bill
X-ModelPortal-Provider Provider identifier that served the request
X-ModelPortal-Endpoint Endpoint identifier that served the request
X-ModelPortal-Model Canonical model ID that was used
X-ModelPortal-Attempts How many endpoints the request tried

A streaming response sends its headers when the first content event arrives or when keepalives start, whichever comes first. If only keepalives have gone out, the provider, endpoint and attempt count are not settled yet; those three headers are left out and the fields in the stream are authoritative.

Extra response fields

In all three protocols the response body gains three fields; when streaming they are in the last event that carries usage:

Field Meaning
provider Provider identifier that served the request
attempts One item per attempt: provider, endpoint (endpoint identifier), status (HTTP status), cost (USD); cost is 0 for failed attempts
cost in the usage object The amount charged for this request (USD), matching your bill

The usage object is usage in OpenAI (response.usage in streaming Responses), usage in Anthropic and usageMetadata in Gemini. Every OpenAI Chat streaming chunk also carries provider. The endpoint that served the request is the one in the last attempts item.

Errors

Each protocol returns its own error format: in the OpenAI format and the platform API, code is the platform error code; the Anthropic format carries only an error type, and the Gemini format's code is the HTTP status. The full code table and the 422 exclusion reason codes are in Common errors.

Rate limits

Account requests per minute, per-key requests per minute and concurrent requests are limited; going over returns 429 rate_limited with Retry-After. Tiers are in Common errors.

Request detail and key quota

These two endpoints authenticate with your API key and accept only Authorization: Bearer YOUR_API_KEY. They are free but count toward the key's requests per minute. Amount fields end in _minor and are in units of 0.000001 USD.

GET /api/v1/requests/{request ID}

The request ID is the value of the X-ModelPortal-Request-Id response header. A key can only look up requests it made itself: requests made by another key on the same account, or by another account, return 404 call.not_found, the same as a request ID that does not exist. How far back you can look matches the call record retention period.

Field Description
request_id, started_at, model, status Request ID, start time, model ID, status
provider, offering_id Provider and endpoint identifiers that finally served the request
config_version, price_version Config version and price version of that endpoint when it served the request
error_category Error type when the request failed
duration_ms, first_byte_ms Duration and time to first token, in milliseconds
tokens Usage by dimension
cost_minor What the request cost, matching your bill
meter_flags Metering flags, for example estimated when billed on an estimate
routing_constraints Routing constraints in effect: data policy, region, quantization and other limits after merging account preferences, key preferences and request parameters; null when there were none
attempts One item per attempt: provider, offering_id, config_version, started_at, duration_ms, upstream_status (HTTP status), error_category, cost_minor

GET /api/v1/key

Returns the current key's settings and quota:

Field Description
id, name, last4, status, expires_at Key ID, name, last 4 characters, status, expiry
allowed_model_ids Model allowlist; empty means every model
daily_limit_minor, monthly_limit_minor Daily and monthly spending limits, null when not set
spent_today_minor, spent_month_minor Spent today and this month, matching the key list in the console
held_minor Amount held for requests still in flight
rate_limits Rate limit tier: account requests per minute, per-key requests per minute, concurrent requests
routing_preferences Key-level routing preferences
available_minor What this key can spend right now

available_minor counts only your cash balance and gift credit that is not limited to specific models, minus what is already held. If the key has a spending limit, it never exceeds the limit minus what was spent this period and what is held in flight.

App authorization and the management API are not open yet; they will be added here when they launch.