For step-by-step examples, see the Python, JavaScript and image guides. Estimate usage with the cost calculator.
BUILD WITH JEVROUTER
Your first request.
One endpoint for the models in your project.
- Create an account and add project credits from Balance using Stripe. Any allocated trial credits can also be used.
- Create a key, choose allowed models, and save the key once.
- Choose a published model from the catalog and set your environment variable.
Python · OpenAI SDKimport os
from openai import OpenAI
client = OpenAI(
base_url="https://api.jevrouter.io/v1",
api_key=os.environ["JEVROUTER_API_KEY"],
)
response = client.chat.completions.create(
model="YOUR_PUBLISHED_MODEL_ID",
messages=[{"role": "user", "content": "Hello"}],
max_tokens=256,
)
print(response.choices[0].message.content)Base URL: https://api.jevrouter.io/v1. Send Authorization: Bearer $JEVROUTER_API_KEY. Model list: GET /v1/models.
Automatic routing
Use jev/auto after enabling an evaluated Balanced policy in Routing. Your key must allow both jev/auto and the real generation models. Jev returns task signals; your policy and cost limits select an eligible model.
Set jev.max_cost_usd to bound a request’s maximum quoted generation cost. Low confidence, timeouts, or disabled Jev data sharing use the policy’s eligible default. No eligible default produces an error. A fixed model is never silently changed to another model.
The supported contract
POST /v1/chat/completions supports text conversations, JSON and SSE responses, and the parameters listed on each model page. Streaming usage requires stream_options: { include_usage: true }.
Models that list the capability may support function tools and strict JSON schemas. Schemas use an object root, required properties, and additionalProperties: false; supported keywords are type, properties, required, additionalProperties, items, enum, description, and anyOf. Maximum depth is 8 and maximum schema nodes is 128. Tool execution is your application’s responsibility.
Chat currently accepts text input. Image generation and asynchronous video tasks use their dedicated endpoints below. Embeddings, the Responses API, BYOK and arbitrary provider options are not yet callable. Unsupported parameters return an explicit error.
Generate images
Choose an image model in Playground, or call POST /v1/images (alias: /v1/images/generations) with model, prompt and optional n. Model pages list allowed quality, resolution, aspect ratio, output format and reference-image options. Send references as input_references entries with type: "image_url" and image_url.url, using HTTPS or PNG/JPEG/WebP data URLs.
Set stream: true for long generations. The SSE connection sends keepalives, then an image_generation.completed event containing data (base64 images), model, id and usage, followed by [DONE]. Errors arrive as an SSE error event after streaming begins. This endpoint streams completion events, not partial-image previews. Buffered JSON is also available, but your network proxy may time out on long calls.
Image requests reserve a conservative amount using the provider’s image, token or megapixel pricing. jev.max_cost_usd rejects a reservation above your limit. The provider’s reported cost sets the final charge, capped by the reservation. During the beta, reference images and results may be retained in diagnostic logs for 30 days. Download Playground results before leaving.
Generate and process videos
Call POST /v1/videos with a model ID in the body and your Jevrouter bearer key. The response returns a task, not a finished video. Query GET /v1/videos/REQUEST_ID with the same key at least three seconds apart; read data.status and data.outputs. This endpoint uses Jevrouter’s video contract, not the OpenAI SDK video API.
curl --fail-with-body https://api.jevrouter.io/v1/videos \
+ -H "Authorization: Bearer $JEVROUTER_API_KEY" \
+ -H "Content-Type: application/json" \
+ -H "Idempotency-Key: my-first-wan22-video" \
+ -d @- <<'JSON'
{
"model": "wan/wan-2.2-t2v-480p-ultra-fast",
"input": {
"prompt": "A yellow sailboat on a quiet lake",
"duration": 5,
"size": "832*480"
},
"jev": {
"max_cost_usd": "0.05"
}
}
JSONEach video model publishes its input schema. Text, image and video processing jobs need different inputs. Put model-specific fields in input; source media must use accessible URLs. Set jev.max_cost_usd to limit the quoted reservation before the task is submitted.
For automatic selection, use model: "jev/auto" and an explicit task such as task: "text-to-video". Enable Auto on the project and allow Auto plus the candidate models on the key. Auto validates the task and parameters, then compares up to eight compatible candidates shortlisted by catalog price. It is not a quality ranking or an exhaustive cheapest-model guarantee.
Save the task ID and keep one Idempotency-Key per intended generation. If the submission response is lost, repeat that exact body with the same key to recover its task. If a 409 or 503 includes a task ID, query that task. Do not create a new key to recover an uncertain submission: it may create a second billed video.
Background processing continues after you disconnect. Completion notifications are handled internally; customer callbacks and cancellation are unavailable. Outputs can be media URLs or structured objects. Download promptly: result links are kept for up to seven days and may expire earlier. A task can complete before its bill settles; inspect GET /v1/requests/REQUEST_ID or project request history for the final charge.
Complete Python tutorial with persistent state and safe retries →
Errors and safe retries
Error responses include a stable code, an English message, next_action, retryable, param when one field is involved, and request_id and trace_id when available. Use the code for application logic. Follow next_action to correct the request; an unknown or partially delivered outcome must be inspected before starting another generation.
Request details include guidance and billing_outcome. noCharge means no credits were consumed; charged means settlement recorded a charge; billingPending means the final charge is not confirmed. A reservation is not a final charge. Validation failures before admission may have a correlation ID without a saved request record.
Keep the X-Jevrouter-Request-Id response header. Inspect status at GET /v1/requests/:id using the original API key, or use Requests in the console.
| 400 | Unsupported parameters or model constraints |
|---|---|
| 401 / 403 | Invalid key, permissions, or blocked project |
| 402 | Balance, budget, or request cost limit |
| 409 | Idempotency conflict or request already accepted |
| 429 | Request/token rate limit; respect Retry-After |
| 5xx | Provider or service failure; inspect request status first |
For chat and images: Send a unique Idempotency-Key for each intended generation. Reusing it never generates again or replays the response; it returns the accepted request’s status. Keys are retained for at least 24 hours. Changed bodies conflict. After a stream begins or upstream execution is uncertain, the service does not retry generation automatically.
Know what you pay
Chat: A request reserves its conservative input bound plus hard maximum output. The default output limit is 1,024 tokens unless changed in project settings. Models imported from OpenRouter settle the provider’s reported USD cost, capped by the reserved amount. If a chat cost receipt is missing, token pricing provides a fallback; image requests require a valid cost receipt. Unused credit is released.
Images and videos reserve a quote for the chosen inputs. Videos settle the confirmed generation cost, capped at the reservation, then release unused funds. Failed video generation releases the reservation without a generation charge.
USD prices are recorded with each request. Jev classification and unsuccessful upstream attempts are platform costs. Project and key budgets use UTC calendar months and count consumed plus reserved amounts. Only unspent, unreserved credits from a payment can be refunded to the original payment method.
Data and privacy
Requests are sent to the selected generation provider. Automatic routing also sends the conversation to Jev when project sharing is enabled. Disabling Jev sharing uses the configured default model. Provider retention remains subject to that provider’s policies.
During the beta, Jevrouter records complete inference request and response content in diagnostic logs for 30 days, along with request metadata, usage, route decisions, and billing records. Credentials are redacted. Explicit zero-priced :free models may use prompts and completions for provider training; paid chat routes prohibit training. The current upstream account does not allow free endpoints that publish prompts to public datasets. Playground conversations live in the current browser page and disappear on reload. API key plaintext is shown once and only a hash is stored.
If you arrive from a Google ad and allow ad measurement, we use a 30-day cookie to associate that click with your account and first successful API call. We send the click identifier, event time and a deduplication identifier to Google Ads, with no prompts, outputs or email addresses. Use Ad measurement preferences in the footer to turn off future uploads.