Skip to main content

LLM Endpoints

LLM Endpoints run pre-authored LLM, vision, image-generation and video-generation templates and return a job you poll or receive by webhook. Every endpoint declares its own named inputs; the catalog below is generated live from the API, so it always matches what is deployed — an endpoint configured in the console appears here without a docs deploy.

POST /api/v1/{prefix}/{slug}
  • Auth: Bearer key with the generate:llm scope.
  • Requires: a positive credit balance (otherwise 402).
Each endpoint carries its own path prefix

Unlike the image and voice surfaces, LLM endpoints are not all served under one fixed segment: the prefix is chosen per endpoint, so related endpoints can be grouped under a name that means something to you. The catalog below publishes each endpoint's full path — use it verbatim rather than assembling a URL from the slug.

generate:llm is on by default

Like generate:image and generate:voice, the LLM Endpoints scope is carried by every API key that was not minted with an explicit scope list — including keys you already hold. If a key returns 403 here, it was issued with a restricted scope set; ask for generate:llm to be added to it.

Holding the scope is not the whole story: each endpoint is separately either public or restricted to its own scope, so this scope reaches the public endpoints in the catalog and no others.

Request body​

Every LLM endpoint takes the same envelope. Only the contents of inputs differ, and those are what the catalog below documents per endpoint.

FieldTypeRequiredNotes
inputsobject✓The endpoint's own named inputs. Unknown keys are rejected. Values may be scalars, arrays, or nested objects, as the endpoint's schema declares.
webhook_urlstring-HTTPS URL notified when the job finishes. Falls back to your account-level webhook. The callback is signed — see Webhooks.

The language input​

Localised endpoints take a language input selecting which locale's prompt serves the request. It is optional and defaults per endpoint; the accepted values are:

en de es fr it pt-br zh-hans ja ko ru

A value outside this list is rejected with 400 before anything is charged. A locale inside the list that has no dedicated prompt yet is served the endpoint's default prompt. Language-neutral endpoints (the vision templates) publish no language input at all — the catalog below shows exactly which inputs each endpoint takes.

The model input​

Some endpoints let you choose which model serves the request. Those publish an optional model input whose schema lists the accepted OpenRouter model ids as an enum, with the endpoint's default model as its default. Omit it to run the default. A value outside the list is rejected with 400 before anything is charged. The job's model_used reports what actually ran. Endpoints that publish no model input always run their own configured model — the catalog below shows which is which.

The reasoning input​

Every text and JSON endpoint publishes an optional reasoning input that sets the reasoning effort of the request, for models that support it. The accepted values are:

off minimal low medium high xhigh

off asks the model not to reason, which also switches off models that reason by default; a model with no reasoning ignores it. A model that cannot stop reasoning (the o-series, gpt-5-mini, DeepSeek R1) is retried at minimal, and if it refuses that too it runs with its own default. The other values ask for that effort level. A model that grades effort honours every level; a model that only knows on and off treats every level as on; a model with no reasoning at all cannot serve the request, so the job fails — send off or omit the input there. The endpoint's default is whatever its operator configured, and the schema reports it as the input's default; omit the input to run with that. A value outside the list is rejected with 400 before anything is charged. Image and video endpoints publish no reasoning input.

Media inputs​

Some endpoints take one or more media inputs — an image for a vision endpoint, a video clip for a video-understanding or video-editing one, an audio clip for a transcription or audio-understanding one, a reference picture or a first frame for an image or video endpoint. Each is a media_id of media generated within the platform (see Media); the endpoint's schema marks the field with x-media-type (image, video, audio, image_video for a field that accepts either visual kind, or media for a field that accepts any kind). On a video endpoint each image input's description says whether it is a frame the clip animates from or a reference that guides it. URLs are not accepted and are rejected with 400 before anything is charged; an unknown id answers 404, a deleted or expired one 400, and an id of the wrong kind 400.

Response​

A successful call returns 202 Accepted immediately — the completion runs asynchronously:

{ "job_id": "64b7f5a6-f341-47c7-9c1e-7d13f6391cc6", "status": "queued" }

Then either poll or wait for the webhook:

GET /api/v1/{prefix}/jobs/{job_id}

(The generic GET /api/v1/jobs/{job_id} returns the same answer.)

:::danger Verify the webhook signature Every callback carries a Standard Webhooks signature. Verify it before you act on the payload. See Webhooks. :::

A completed job carries status and an outputs object: a single text field for plain-text endpoints, one typed field per property for endpoints publishing a JSON output schema, or — for image and video endpoints — one media object under image or video. A JSON schema may nest objects and hold arrays of scalars, and the outputs object has the same shape — a field published as tags.hobby arrives at outputs.tags.hobby. A media object carries the durable media_id beside a short-lived presigned url, plus kind, content_type, expires_at and model — the model that generated it, in the same id you select a model by on the endpoint (phantom/<slug> for a GPU workflow, otherwise the provider's model id) — see Media. A failed job carries error and error_code — see Jobs.

Image and video endpoints

An image endpoint answers within one worker pass. A video endpoint is a render that takes minutes: poll less often, or prefer the webhook. Both publish exactly one artifact per job, and the media object's url expires — store the media_id and pass it back into later calls.

Nested inputs​

An endpoint may group its inputs into objects. Send the tree the endpoint's schema documents:

{
"inputs": {
"availableOptions": { "gender": ["female", "male"], "minAge": 18 },
"characterInfo": { "description": "a blonde nurse" }
}
}

The GET /api/v1/{prefix}/{slug}/schema document describes the exact tree, with required at every level. An unknown nested key is rejected with its full path ("availableOptions.foo").

Example​

curl -X POST https://api.phantomrouter.ai/api/v1/{prefix}/{slug} \
-H "Authorization: Bearer $PHANTOM_KEY" \
-H "Content-Type: application/json" \
-d '{
"inputs": { "language": "de", "message": "hallo" }
}'

Each card in the catalog below carries a copyable command with that endpoint's real fields already filled in.

Errors​

StatusCodeWhen
400INVALID_REQUESTAn input failed validation, or an unknown key or locale was sent.
401UNAUTHORIZEDMissing or invalid key.
402PAYMENT_REQUIREDInsufficient credit balance.
403FORBIDDENKey lacks generate:llm.
404NOT_FOUNDNo such endpoint — or one your key cannot reach. See below.
A 404 is not always a typo

Endpoints can be restricted to keys holding an extra scope. A restricted endpoint returns exactly the same 404 as one that does not exist. If an endpoint you were told about returns 404, ask for the scope rather than assuming the slug is wrong — the catalog below lists only the endpoints open to every key holding generate:llm.

Catalog​

Every published LLM endpoint, with its exact request contract. Generated live from the API, so a change in the console appears here without a docs deploy.

Generating a client?

The same data is served as JSON at GET /api/v1/public/ai — unauthenticated, CORS-open, and ETag-cached. Each endpoint is also available on its own at GET /api/v1/public/ai/{slug}. Note that this catalogue path is fixed while the endpoints it lists are not: read each entry's path for the URL to call. The per-endpoint schema_version changes only when the contract itself changes, and matches the authenticated GET /api/v1/{prefix}/{slug}/schema.

Loading the live endpoint catalogue from /api/v1/public/ai. It is also readable directly as raw catalogue JSON — no key required.