Console guide

Submitting, approving, and downloading jobs from the browser, plus the organization settings around them.

The console

The console is the browser side of the service. It is where you submit and track batch inference jobs, manage API keys, manage your organization's members, and handle billing.

Everything here works on the same jobs and the same organization as the HTTP API - a job submitted from a script shows up here too, and a job submitted here can be polled with an API key. The API reference covers the API side.

Organization and members

Everyone who signs in belongs to one organization. There are three roles:

Owner
Everything an admin can do, plus: buy credits, set the billing email, rename the organization, turn auto-approve on or off, promote or demote owners, and delete the organization. The first person to sign in for a new organization becomes its owner.
Admin
Everything a member can do, plus manage people: invite teammates, set roles between member and admin, remove members and admins, and configure webhooks. An admin cannot change an owner, buy credits, manage billing, rename the organization, or set auto-approve.
Member
Submit, approve, cancel, and download jobs, and create and deactivate API keys. Cannot manage people, billing, or organization settings.

A new teammate joins as a member. An admin can promote them to admin; only an owner can make someone an owner, from the member list under Settings. Nobody can change their own role, so an organization always keeps at least one owner.

API keys

Any member can create and deactivate API keys from the Keys page. A key authenticates HTTP requests to the batch API - it is not needed to use the console, only for calling the API directly (scripts, CI, etc.).

When you create a key, the full token is shown exactly once, right after creation. Copy it then - the list only ever shows a masked preview afterwards, and there is no way to recover a lost token; create a new key instead.

Deactivating a key stops it from authenticating new requests immediately. It stays listed rather than being deleted, because jobs it already submitted are still billed and audited against it. A deactivated key cannot be reactivated.

Credits and billing

The service is prepaid. 1 credit = 1 US cent. An owner buys credits from the Settings page (opens Stripe Checkout); credits land on the balance once the payment settles, typically within seconds.

Credits are non-refundable and do not expire, except as set out in the Terms. Unused credits simply stay on the balance for future jobs.

Approving a job's cost estimate holds that amount against the balance - this is the maximum the job can ever consume. If the job finishes for less (or only part of it completes before it fails or is cancelled), you are billed only for the actual amount and the rest of the hold returns to the balance automatically.

A job that does any work costs at least 1 credit, so a very small job is quoted and billed that minimum rather than rounding down to nothing. A job that consumed nothing at all - cancelled before it started, or failed without completing a row - is not charged.

Each model also carries a minimum job price covering the cost of the GPU machine start a small job forces (mainly the model-weights download), sold at cost with no markup. It is a floor, not a fee: a job whose token estimate is below the minimum is quoted and billed the minimum instead, and nothing is ever added on top of a job that clears it. When a job's estimate sits at the minimum, the console says so next to the amount. The current minimums are listed on the pricing page.

The flip side is that batch pricing rewards volume: once a job's token price clears the minimum, the machine start is not billed anymore, so the overhead share of what you pay falls toward zero as the job grows. If you can, batch more rows into one larger job rather than submitting many small ones - the same rows cost less that way.

Balances and job costs are shown in credits, since credits are what you hold and what jobs consume. Dollars appear only where money moves: the top-up amount is entered in USD, and the form shows how many credits it buys before you pay.

Media inputs. A job whose rows carry media is priced on its model's media rates; a text-only job gets the model's text rates, which on some models are cheaper. An image is billed at a flat per-image price. An audio or video clip is billed as the input tokens its encoder turns it into, plus a small per-minute surcharge for the fetch and encode work; the minutes come from the duration_seconds you declare on the media part, or from what we infer about the clip (see the API docs). One asymmetry to know about: token charges always settle on the work actually done, but if a job is cancelled or partially completes, the per-minute surcharge is settled on the full media duration the job declared at submit.

Tax. Credit prices exclude tax. Tax is worked out from the billing address you give at Checkout and added to the payment, so the credits you receive always match the amount you entered. Wherever a reverse charge applies, a business that enters a valid tax ID at Checkout is billed with no tax added and the invoice records that - paying the tax is then your own obligation, at your local rate and under your local rules. Where we hold no tax registration, no tax is added. Your tax ID and company address are kept with your billing details and reused on later invoices.

Invoices and receipts. Every paid top-up is invoiced. The Settings page lists your purchases with a link to view each invoice or download its PDF, and Stripe emails a receipt when the payment goes through. Manage billing details on the same page opens your billing page at Stripe, where the full archive lives and where you set the company name, address and tax ID that appear on future invoices. Operator credit grants are listed too; they are not purchases, so they have no invoice. A top-up you started but never paid is listed until Stripe's payment page expires, with a link to go back and finish it; after that it is marked expired and nothing was charged.

The billing email (owner-only, set on the Settings page) is where those receipts are sent and the address printed on your invoices, plus where we send billing correspondence such as notice of changes to these terms. If it is unset, receipts go to the owner who made the purchase. It is a billing destination only - setting it does not create an account or grant anyone access.

Submitting a job

From the Jobs page, choose an input file and a model, then submit. Two input formats are accepted, detected from the file extension:

.jsonl - one full chat-completion request per line; no extra configuration needed.
.parquet - a table with a column holding each row's prompt; you name that column (the "instruction column") at submit time.

For a model that can think before answering, a thinking / reasoning checkbox appears under the model picker. It is shown only for those models, and it sets the default for every row; a JSONL row that sets thinking itself keeps its own setting. Next to it, for models that support it, a thinking budget field caps how many tokens each row may spend thinking; leave it blank and the budget is estimated the same way as the output cap, or tick the no thinking cap checkbox next to it to let thinking run uncapped.

Under Advanced you can supply a JSON response_format to constrain every answer to structured JSON (see structured output), and set max tokens per row yourself. Left alone, the cap is estimated from a sample of your input: the value every row is expected to stay under with 95% confidence, which is also the job's price basis. Setting it uses your number as the cap and price basis instead.

Audio, video, and images ride the rows themselves: on a media-capable model (the dropdown labels each model's modalities), a .jsonl row's messages may carry image, audio, and video content parts alongside text, in the same shapes the HTTP API accepts - see the input file for the exact objects and limits for the per-clip caps. A .parquet input holds plain-text prompts, so rows with media must be submitted as .jsonl. A hosted audio clip (audio_url) needs its duration_seconds declared on the part.

The file is uploaded directly from your browser to storage, then the job is created pointing at it - there is no option in the console to submit a job by giving a URL instead. The HTTP API can do both - give a URL or upload a file directly - see the API docs. Input limits are the same everywhere; see limits.

Embedding models change the form: picking one of the embedding models (see models) hides the thinking checkbox and the whole Advanced block (max tokens, response_format - none of them apply to a job that returns vectors, not text), relabels the parquet column field "Column to embed", and shows an optional "Vector dimensions" field in their place - an integer from 32 up to the model's own width, to truncate the output vector. Leave it blank for the model's full native width. See embedding jobs for the equivalent API fields.

Approving and cancelling

The Jobs page shows each job's status, its estimate, and its row counts as they fill in. The list updates itself while the page is open - a job that moves on, and the buttons that come with it, appear without a reload. Under each status is what the job is doing right now: what it is waiting on, or how many of its rows have been processed. The statuses themselves are described under job lifecycle.

Approving: a cost_ready job shows an Approve button if your balance covers the estimate, or a Top up shortcut for the shortfall if it doesn't. Any member can approve.

Cancelling: any job that hasn't reached merging yet can be cancelled by any member, from the row's Cancel button. A job that had not started work stops immediately at no charge; one with rows in flight lets them finish, bills only those, and delivers them as a partial result.

Auto-approve

When on, a job's cost estimate is approved automatically instead of waiting for someone to click Approve - it skips the manual approval step only. It does not skip the balance check: a job whose estimate exceeds the balance still stops at cost_ready and waits, exactly as it would with auto-approve off.

The Settings page shows whether auto-approve is currently on or off for your organization. An owner can turn it on or off from that page.

Webhooks

A webhook is one HTTP endpoint on your side that receives a signed event each time a job moves through its lifecycle - not only when it finishes. A registered endpoint receives every job event; there is no per-event subscription.

The full event list, the payload shape, and how to verify the signature are on the API reference page.

When a webhook is registered, the signing secret is shown exactly once, at registration time. It cannot be retrieved again afterwards - if it's lost, the endpoint has to be registered again to get a new one.

The Settings page shows whether a webhook is currently configured for your organization. An owner or admin can register or remove the endpoint URL and send a test event from that page.

Results

A job that reaches done - or one that stopped early but still delivered a partial result - offers Preview and Download on the Jobs page.

Preview opens the first rows of the result (up to 50) right in the console, so you can check the output before downloading everything.

Download opens a link straight to the result file. That link expires after a while - if it stops working, click Download again to get a fresh one. What is inside the file is described under output format.

Troubleshooting

A job is stuck at cost_ready. It is waiting for approval. Either approve it yourself (or have another member do so), or check whether auto-approve is on and your balance covers the estimate - if the balance is short, top up and it will still need approving.

A webhook isn't arriving. On the Settings page, confirm the endpoint shows as configured, then use Send test event to check delivery. Make sure the endpoint is reachable over HTTPS and isn't behind auth it doesn't expect.

An upload gets rejected. Check the file extension (only .jsonl and .parquet are accepted) and its size (1 GiB max). The error message names which check failed.

A media job fails with invalid_input. The failure reason names the problem: an inline clip or image over its per-item size cap (see limits, the message names the line), a clip longer than the model takes, a hosted audio_url without duration_seconds declared (it is assumed worst-case long and rejected as too long), or a content part your chosen model has no encoder for. The same failure covers an unsupported container: check the file extension or format field against the supported formats, make sure an inline clip's bytes really are what it says they are, and give a hosted audio or video URL either a file extension or a real Content-Type. Fix the named row, or pick a model whose modalities cover it, and resubmit.

Answers come back empty on a thinking model. The model can spend its whole output budget reasoning and leave nothing for the answer. Either turn the thinking checkbox off, set a thinking budget, or allow a larger output cap.