Reference
Developer documentation
One key for image, video, voice and text, with the exact charge on every response.
01
Quickstart
A key, a POST, a finished image with its price attached.
- 01Create an account and add prepaid credit, from $5.
- 02Create an API key in the dashboard. It is shown once.
- 03Send the request below with that key.
curl -X POST https://api.corent.tech/v1/images/generate \ -H "Authorization: Bearer $CORENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "a fox reading a book", "tier": "air"}'{ "id": "...", "status": "completed", "images": [{ "url": "https://...", "width": 1024, "height": 1024 }], "meta": { "model": "image-air", "cost_cents": 2, "duration_ms": 1500 }}Images usually return inline with the charge. A slow render comes back as a job id to poll instead.
02
Authentication
Every request carries a bearer token from a key you created in the dashboard.
Authorization: Bearer co_live_...- Base URL
- https://api.corent.tech
- Scope
- Server-side only, never in browser code.
A key can be locked to specific models, or to tiers only, when you create it.
03
Images
POST/v1/images/generate
Generate an image. Returns inline unless you ask for a job.
| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | yes | What to generate. |
| tier | string | no | air, lite, premium, pro or max_pro. Omit it if you pass model. |
| model | string | no | Pin an exact model from GET /v1/models. Never substituted. |
| style | string | no | Style hint, for example photorealistic. |
| aspect_ratio | string | no | For example 1:1, 16:9 or 9:16. |
| async | boolean | no | true returns 202 with a job id. Use it for max_pro and other slow renders. |
| Idempotency-Key | header | no | Any unique string up to 255 chars. A repeat returns the original job instead of billing twice. |
{ "prompt": "a fox reading a book in a cozy library", // one of air, lite, premium, pro, max_pro "tier": "air", // both optional "style": "photorealistic", "aspect_ratio": "1:1", // optional; true returns 202, then poll /v1/jobs/{id} "async": false}04
Video and jobs
POST/v1/videos/generate
Returns 202 with an id. Video takes one to five minutes and bills per second of output.
| Field | Type | Required | Description |
|---|---|---|---|
| prompt | string | yes | What to generate. |
| tier | string | no | air, lite, premium, pro or max_pro. Omit it if you pass model. |
| model | string | no | Pin an exact model from GET /v1/models. Never substituted. |
| duration_s | number | no | Seconds of output. The tier menu carries the allowed range. |
| resolution | string | no | 720p, 1080p or 4k. Above the tier cap it clamps down, it never errors. |
| aspect_ratio | string | no | For example 16:9 or 9:16. |
| image_url | string | no | Animate an existing image instead of generating from text alone. |
{ "prompt": "a small sailboat crossing a calm harbor", "tier": "premium", "aspect_ratio": "16:9", "duration_s": 5, // tier-capped: clamped down, never rejected "resolution": "720p", // optional, image-to-video "image_url": "https://..."}GET/v1/jobs/{id}
Poll a job. The charge lands here when the video completes, next to the delivered pixel dimensions measured from the stored file.
Prefer GET /v1/jobs/{id}/stream, which is server-sent events, to avoid polling.
{ "id": "...", "status": "completed", "videos": [{ "url": "https://...", "width": 1920, "height": 1080, "resolution": "1080p", "duration_s": 5 }], "meta": { "model": "video-premium", "cost_cents": 162, "duration_ms": 94000 }}05
Speech
POST/v1/audio/speech
Synchronous. Returns the finished audio file and the exact charge.
| Field | Type | Required | Description |
|---|---|---|---|
| text | string | yes | The text to speak. Billed per 1,000 characters, started thousands count in full. |
| voice_id | string | no | Omit it for the default narration voice. |
| model | string | no | Pins an exact speech model, for example corent-eleven-multilingual-v2. |
{ "id": "...", "status": "completed", "audio_url": "https://...", "meta": { "model": "corent-speech-tts", "cost_cents": 14, "duration_ms": 1840 }}corent-speech-tts is a tier name, not a model. Sending it back as model returns 404. Pinnable names come from GET /v1/models.
{ "text": "Welcome to Corent. One API for image, video, and voice.", // optional "voice_id": "...", // optional; pins a speech model "model": "corent-eleven-multilingual-v2"}06
Chat completions
POST/v1/chat/completions
OpenAI-compatible. Point any OpenAI SDK at the base URL and keep your code.
| Field | Type | Required | Description |
|---|---|---|---|
| model | string | yes | A tier, corent/text-premium, or an exact model from GET /v1/models. |
| messages | array | yes | The conversation, in the OpenAI shape. |
| max_tokens | number | no | Upper bound on the reply. |
| stream | boolean | no | true streams the reply as server-sent events. |
{ // a tier, or an exact model such as "corent-gpt-5.6-sol" "model": "corent/text-premium", "messages": [{ "role": "user", "content": "Write a haiku about shipping fast." }], "max_tokens": 200, "stream": false}{ "id": "chatcmpl-...", "object": "chat.completion", "model": "corent/text-premium", "choices": [{ "message": { "content": "..." }, "finish_reason": "stop" }], "usage": { "prompt_tokens": 14, "completion_tokens": 19, "total_tokens": 33 }, "corent": { "cost_cents": 1 }}Streaming, tool calling and JSON mode pass through. Billed per token, with the charge on the corent.cost_cents extension.
07
Tiers and pinning
Name a tier and the router picks the model. Name a model and it runs exactly that.
Tiers
Five tiers: air, lite, premium, pro, max_pro. Send tier on image and video, and call a language tier as model: corent/text-premium.
Video adds resolution: pro reaches 1080p, max_pro reaches 4K. Receipts and status spell tiers out in full, as image-air or video-max_pro.
Preferences
One word instead of a tier. It resolves like this.
| Preference | Optimizes for | Image tier | Video tier |
|---|---|---|---|
| cheap | Cost first | Air | Air |
| fast | Latency first | Air | Air |
| balanced | Cost, speed and quality equally | Lite | Premium |
| quality | Output quality first | Premium | Pro |
Pinning a model
Pass model instead of tier for direct access: no routing, no substitution. If it cannot deliver, the request fails and you pay nothing.
curl -X POST https://api.corent.tech/v1/images/generate \ -H "Authorization: Bearer $CORENT_API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "a fox reading a book", "model": "corent-flux-schnell"}' // the response names the model you pinned:// "meta": { "model": "corent-flux-schnell", "cost_cents": 2, ... }Names read corent-flux-schnell. The bare name flux-schnell still resolves, so older code keeps working.
- Models
- GET /v1/models, public, no authentication.
- Tiers
- GET /v1/tiers, with per-resolution prices and live status.
- Status
- GET /v1/status, one line per tier.
08
Response and receipt
Every success says what served it and what it cost. The meta block is the receipt.
| Field | Type | Description |
|---|---|---|
| id | string | The request or job id. |
| status | string | completed, processing or failed. |
| meta.model | string | The tier that served the request, or the exact model you pinned. |
| meta.cost_cents | number | The exact charge for this request, in cents. |
| meta.duration_ms | number | How long the generation took. |
Chat completions carries the same number as corent.cost_cents. Video bills on completion, so its charge appears on GET /v1/jobs/{id}.
GET/v1/requests
Every past request with its charge, the tier that served it, how many candidates were considered and whether failover fired. Failed requests show billed: false.
{ "requests": [{ "request_id": "...", "status": "completed", "model": "image-air", "cost_cents": 2, "billed": true, "candidates_considered": 3, "failover_occurred": false, "reasoning": "Optimized for cost and speed.", "output_url": "https://..." }], "next_before": null}GET /v1/routing/explain?request_id=... answers the same question for one request.
09
Errors and retries
Nothing in this table is billed. Charging happens only after a successful result.
| Status | Meaning | Retry | What to do |
|---|---|---|---|
| 400 / 422 | Invalid request | No | Fix the highlighted field and resend. |
| 401 | Invalid API key | No | Check the header: Authorization: Bearer co_live_... |
| 402 | Insufficient balance | No | Add funds in the dashboard. |
| 404 | Resource not found | No | Check the job or batch id. |
| 429 | Rate limited | Yes | Wait the seconds given in the Retry-After header. |
| 500 | Internal error | Once | Retry once. If it persists, contact support. |
| 502 / 503 | Temporary upstream failure | Yes | Safe to retry: routing already failed over internally. |
A provider failure after internal failover is still a failure you are not charged for. Your balance is untouched.
Send an Idempotency-Key on image or video generation and a repeat returns the original job. A timed-out request can be retried blindly and can never double-bill.
10
Limits and balance
Every key carries its own ceiling, and every balance is prepaid.
Limits
Requests per minute, concurrent jobs and a daily cost cap, per key. New keys start at $10 a day, so a leaked key is bounded by default.
PUT/v1/account/api-keys/{id}/limits
Deliberately requires a dashboard login, not an API key: a leaked key must never raise its own cap.
{ "requests_per_minute": 60, "concurrent_jobs": 10, "daily_cost_cap_cents": 5000 }On 429, Retry-After gives the wait in seconds. Batches take up to 50 items and run five at a time, each billed at the normal rate.
Balance
GET/v1/account/balance
{ "balance_cents": 998 }GET /v1/account/usage returns recent jobs and total spend. POST /v1/account/deposit opens a card top-up from $5, and /deposit/crypto from $10.