Get a key

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.

  1. 01Create an account and add prepaid credit, from $5.
  2. 02Create an API key in the dashboard. It is shown once.
  3. 03Send the request below with that key.
curl
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"}'
Response
{  "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.

Header
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.

FieldTypeRequiredDescription
promptstringyesWhat to generate.
tierstringnoair, lite, premium, pro or max_pro. Omit it if you pass model.
modelstringnoPin an exact model from GET /v1/models. Never substituted.
stylestringnoStyle hint, for example photorealistic.
aspect_ratiostringnoFor example 1:1, 16:9 or 9:16.
asyncbooleannotrue returns 202 with a job id. Use it for max_pro and other slow renders.
Idempotency-KeyheadernoAny unique string up to 255 chars. A repeat returns the original job instead of billing twice.
Request body
{  "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.

FieldTypeRequiredDescription
promptstringyesWhat to generate.
tierstringnoair, lite, premium, pro or max_pro. Omit it if you pass model.
modelstringnoPin an exact model from GET /v1/models. Never substituted.
duration_snumbernoSeconds of output. The tier menu carries the allowed range.
resolutionstringno720p, 1080p or 4k. Above the tier cap it clamps down, it never errors.
aspect_ratiostringnoFor example 16:9 or 9:16.
image_urlstringnoAnimate an existing image instead of generating from text alone.
Request body
{  "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.

Response
{  "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.

FieldTypeRequiredDescription
textstringyesThe text to speak. Billed per 1,000 characters, started thousands count in full.
voice_idstringnoOmit it for the default narration voice.
modelstringnoPins an exact speech model, for example corent-eleven-multilingual-v2.
Response
{  "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.

Request body
{  "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.

FieldTypeRequiredDescription
modelstringyesA tier, corent/text-premium, or an exact model from GET /v1/models.
messagesarrayyesThe conversation, in the OpenAI shape.
max_tokensnumbernoUpper bound on the reply.
streambooleannotrue streams the reply as server-sent events.
Request body
{  // 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}
Response
{  "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.

PreferenceOptimizes forImage tierVideo tier
cheapCost firstAirAir
fastLatency firstAirAir
balancedCost, speed and quality equallyLitePremium
qualityOutput quality firstPremiumPro

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
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.

FieldTypeDescription
idstringThe request or job id.
statusstringcompleted, processing or failed.
meta.modelstringThe tier that served the request, or the exact model you pinned.
meta.cost_centsnumberThe exact charge for this request, in cents.
meta.duration_msnumberHow 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.

Response
{  "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.

StatusMeaningRetryWhat to do
400 / 422Invalid requestNoFix the highlighted field and resend.
401Invalid API keyNoCheck the header: Authorization: Bearer co_live_...
402Insufficient balanceNoAdd funds in the dashboard.
404Resource not foundNoCheck the job or batch id.
429Rate limitedYesWait the seconds given in the Retry-After header.
500Internal errorOnceRetry once. If it persists, contact support.
502 / 503Temporary upstream failureYesSafe 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.

Request body
{ "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

Response
{ "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.