Skip to content

AI Gateway Endpoints

Varity TeamCore Contributors

Every route is served from https://ai.varity.app. The full machine-readable schema is public, needs no key, and is the source for anything this page leaves out:

Terminal window
curl https://ai.varity.app/v1/openapi.json

Replace <… model id> in the examples with an id from GET /v1/models whose capabilities fit the route. For example, output_modalities containing embedding for embeddings, image for images, capabilities.speech for speech, and capabilities.transcription for transcription.

https://ai.varity.app is the canonical AI Gateway host. https://varity.app/v1 is a compatibility alias that the edge routes to the same service, so existing clients keep working; use https://ai.varity.app/v1 in new code.

The live catalog. Public, no key.

Terminal window
curl https://ai.varity.app/v1/models

The contract for this surface, including its commercial and data-handling terms. Public, no key.

All inference routes take an inference key as Authorization: Bearer … and a JSON body. Varity has no total response-time limit: without an X-Varity-Deadline-Ms header a request runs until the model finishes or the client disconnects. A provider that sends nothing for 300 seconds fails the request 504 upstream_timeout (every chat request except a web_search one, whose answer the provider returns only whole).

Terminal window
curl https://ai.varity.app/v1/chat/completions \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5-2",
"messages": [{ "role": "user", "content": "Say hello in one sentence." }]
}'

Required: model, messages. Optional fields include stream, max_completion_tokens, temperature, top_p, stop, seed, response_format, reasoning_effort, tools, tool_choice, and parallel_tool_calls. Each works only on models whose capabilities advertise it.

A message’s content can be an array of parts: text, image_url (an https URL or a base64 data: URL), and document ({ "url": …, "filename": … }), on models whose capabilities.input_modalities include image or document.

Varity-specific options go in varity_extensions:

FieldEffect
web_searchGround the answer in a live web search, on models with capabilities.web_search.
web_scrapingRead up to 5 pages linked from the latest user message.
privacy_floorTighten, never loosen, the account privacy floor for this request.

Two optional headers:

HeaderEffect
Idempotency-KeySend the same key when retrying. Reuse returns 409 duplicate_request instead of charging twice.
X-Varity-Deadline-MsOptional absolute Unix-epoch deadline in milliseconds, chosen by the caller. With it, a request still running at that instant ends 504 deadline_exceeded. A malformed or already-past value is refused 400 invalid_request before any provider effect or charge.

Streaming is covered on the overview.

Terminal window
curl https://ai.varity.app/v1/embeddings \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "<embedding model id>", "input": "The quick brown fox." }'

input is a string or an array of up to 2,048 strings. Optional: encoding_format (float or base64) and dimensions.

Terminal window
curl https://ai.varity.app/v1/images/generations \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "<image model id>", "prompt": "A red cube on a table" }'

Optional: size and n. Images come back inline as base64 in data[].b64_json with a mime_type, and Varity never stores them.

The OpenAI SDK’s images.edit upload (multipart/form-data, file fields image or image[] and optional mask) works unchanged. A JSON body with the image as base64 is also accepted:

Terminal window
curl https://ai.varity.app/v1/images/edits \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<image model id>",
"prompt": "Make the sky orange.",
"image": { "data": "<base64 bytes>", "mime_type": "image/png" }
}'

image.mime_type is one of image/png, image/jpeg, or image/webp. An optional mask takes the same { data, mime_type } shape, and size is optional.

Terminal window
curl https://ai.varity.app/v1/audio/speech \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "model": "<speech model id>", "input": "Hello from Varity.", "response_format": "mp3" }' \
--output hello.mp3

response_format must be one of the model’s capabilities.speech_formats. Optional: voice, speed, language, prompt, and stream. The response is audio bytes, not JSON.

The OpenAI SDK’s audio.transcriptions upload (multipart/form-data, file field file) works unchanged. A JSON body with the audio as base64 is also accepted:

Terminal window
curl https://ai.varity.app/v1/audio/transcriptions \
-H "Authorization: Bearer $VARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<transcription model id>",
"audio": { "data": "<base64 bytes>", "media_type": "audio/mpeg" }
}'

audio.media_type is one of audio/wav, audio/wave, audio/x-wav, audio/flac, audio/x-flac, audio/mp4, audio/m4a, audio/x-m4a, audio/aac, audio/mpeg, audio/ogg, audio/oga, or audio/webm, and the decoded audio must be under 25 MB. Optional: audio.filename, response_format (json or text), language, and timestamps.

Terminal window
curl https://ai.varity.app/v1/inference/policy \
-H "Authorization: Bearer $VARITY_API_KEY"

These routes take an inference key, so your own code can read its policy and what it has spent:

RouteReturns
GET /v1/inference/policyYour privacy floor and rate limits.
GET /v1/inference/usageRequests, tokens, and spend_usd from inference key requests for the current period, with breakdowns. Chat and Build requests are not included.
GET /v1/inference/requestsPer-request metadata. Rows for Chat and Build requests carry customer_charge and usage as null. Filters: limit (1 to 100), cursor, model, state, created_after, created_before. The two timestamps are RFC 3339; send them with fractional seconds, for example 2026-09-16T00:00:00.000Z.
GET /v1/inference/performanceLatency percentiles. window is 1h, 24h, 7d, or 30d.

Keys, billing, and the privacy setting are managed from the Developer Portal. The /v1/keys*, /v1/billing/*, and PUT /v1/inference/policy routes refuse an inference key. They are Developer Portal session operations and are not in GET /v1/openapi.json. Each is described on Billing and Keys.

Terminal window
curl https://ai.varity.app/healthz
curl https://ai.varity.app/readyz

Public, no key, outside /v1.

{ "status": "ok", "service": "varity-ai-gateway", "version": "<deployed build>", "source_commit": "<commit>" }

/readyz returns the same fields with status: "ready", plus model counts (servable, servable_by_vertical, published, minimum_servable) and a components object. version reports the deployed gateway build; re-probe for the current one rather than pinning it in your own config.

  • Compatibility: what the OpenAI surface includes and excludes, and every error code
  • Rate Limits: request budgets and body-size ceilings