Base address and authentication
All endpoints live under https://ugesi.com/api/. Send your key as: Authorization: Bearer ugsk_your_key. A missing or revoked key returns 401.
MCP and ChatGPT Actions
Claude Desktop, Claude Code, Gemini CLI, Codex and Cursor: download ugesi-mcp.mjs from the MCP page and run it with your key. ChatGPT custom GPT: import the Action schema from https://ugesi.com/api/openapi/. Five operations: list models, estimate cost, generate, job status, recipe.
Estimate a job
GET /api/estimate/?model=kling-3&seconds=5&resolution=720p returns credits, a dollar estimate, the allowed durations and resolutions, and whether the model is available. POST with a JSON body works the same. No key needed, no balance touched.
Start a generation
POST /api/generate/ with a JSON body containing tool, model, prompt and any required input URLs. The response returns 202 with a job id and the credits held for the run.
Check a job
GET /api/jobs/?id=JOB_ID returns the status: queued, running, succeeded or failed. A failed job releases its credits automatically, so there is nothing to reconcile. A failed job also has a reason (blocked, empty, timeout, canceled or failed) and a hint with what to change before the next run.
Get the result
A finished job carries a signed URL to the output file. The link expires, so download rather than hotlink it into your product.
Webhooks instead of polling
Send a webhook_url with the request and we call it once the job settles. This is the recommended pattern above a few requests per minute.
Models and rates
GET /api/models/ returns every model with its slug, unit and current rate in credits. Read it at deploy time rather than hard-coding rates.
Errors
400 for a malformed body. 401 for a bad key. 402 when the balance is short. 403 when the account has no credit pack from the last 12 months. 404 for an unknown tool. 410 for a retired model. 422 for a missing or invalid input. 429 over the rate limit or with too many jobs running. 503 when a model is paused or unavailable. 502 when the provider could not start the job; the credits are refunded.
Rate limits
Sixty requests per minute per key by default. The 429 response includes Retry-After in seconds. Back off rather than retrying immediately.
Reading the rate before you spend
The models endpoint returns every model with its current credit rate and unit. Call it once at startup and cache it. Hard-coding rates is how a pipeline ends up spending three times what the author expected.
Webhooks versus polling
Video jobs take minutes. Polling works and is simpler to debug, but a webhook frees the worker while the job runs. Both are supported and both report the same final state.
Idempotency and retries
Send your own identifier with each request. If the connection drops after the job started, retry with the same identifier. That returns the original job rather than starting a second paid one.
Errors worth handling explicitly
Not enough credits returns 402 with the amount needed. A paused model returns 503 with replacements. A retired model returns 410 with the list of what to use instead. Each one is a different decision in your code.
A minimal first request
Send a model slug and a prompt to the generate endpoint with your key in the header. The response carries a job identifier. Poll the job endpoint with that identifier until the status is succeeded or failed, then read the output URL.
What the response does not include
There is no hidden charge and no post-generation billing. The credits held when the job started are charged on success or released on failure. The job record shows which happened.
Versioning and what breaks
The API has one version today, without a number in the path. Changes add fields and never remove or rename existing ones, so an integration written today keeps working. Model slugs are the part that changes, which is why the models endpoint exists.