AI pricing
Enrichment is metered separately from the endpoint. A call costs the endpoint's normal price plus one extra charge per enrichment step that judged something. The extra credits are in metadata.extra_credits and in each step's extra_credits, and metadata.credits_charged already includes them.
How a step is charged#
- Reserved. Before judging, the most the step could cost for the rows it is allowed to judge is reserved, the way a paid data route is. If your balance or the key's credit limit cannot cover it, nothing is judged (see below).
- Settled to actual. After judging, the charge becomes what the step actually used, and the difference is returned. You pay for what was judged, not for the reservation.
- Recorded per step. Labels, relevance and themes are separate lines, so
extra_creditson each block tells you what that step cost.
What is free#
- Cached judgments. A text judged for the same preset (or the same relevance query) in the last 30 days is reused at no charge. A text judged for
sentimentandquestionis a free hit for either one alone later. - Skipped rows. Rows with no text, non-text, or under 3 characters are never sent to the provider.
- Unjudged rows. A row that could not be judged is not charged;
extra_creditsreflects only what was judged. - Repeats. Identical texts within one call are judged once. The same call again is a data cache hit plus judgment cache hits, so it is free.
- Idempotent replays. A repeat with the same
Idempotency-Keyreturns the stored body, labels included, at 0 credits. - Refusals. A request refused for an unknown preset (
INVALID_LABEL) or an enrichment parameter on an endpoint that does not accept it is rejected before any charge. With enrichment not enabled andstrict=true, the call is refused before the data is fetched, so it is free too.
Refunds#
- With
strict=true(the default), a step that ends with nothing judged is an error, and its reservation is refunded in full. - A partial result charges only the rows that were judged.
- If your balance or your key's limit cannot cover the reservation, the call answers
INSUFFICIENT_CREDITSorKEY_BUDGET_EXCEEDEDnaming the step. No enrichment charge is made. The endpoint's own charge stands and its data is cached, so retrying once you have topped up is a free cache hit for the data.
What moves the charge#
Output dominates: the charge grows with the number of rows judged and with the number of fields you ask for. Fewer presets are cheaper, so name only the ones you need with label= rather than taking the defaults.
Measured examples#
Recorded on the dev API with the pre-release test provider (synthetic usage, real arithmetic):
| Call | Judged | Extra credits | Per row |
|---|---|---|---|
| Hacker News story comments, the 4 comment presets | 32 rows | 60.225 | 1.88 |
Search results, label=sentiment | 10 rows | 9.134 | 0.91 |
Search results, relevance | 10 rows | 4.969 | 0.50 |
themes (12 themes named in one call) | 26 rows | 7.822 | n/a |
Repeating the first call was 0 extra credits: a data cache hit and every judgment cached. A real provider will have its own figures; these pages will be updated with measured ones before enrichment leaves preview.
Limits#
| Limit | Value |
|---|---|
| Rows judged per request | 200. The rest stay null with reason: request_cap and status: partial. |
| Judged rows per account per UTC day | 5,000. Past it, nothing more is judged that day (reason: account_cap). |
| Service-wide daily allowance | A shared daily ceiling across all accounts (reason: global_cap). |
| Text per row | Clipped to 2,000 characters before judging; under 3 characters is skipped. |
| Judgment cache | 30 days. |
When a limit stops a call that would judge nothing, strict=true answers AI_BUDGET_EXCEEDED (429) with a Retry-After in seconds until the next UTC day, and strict=false returns the rows unjudged with no charge. A limit that stops only part of a call gives a partial result, never an error.
Streams#
On a stream, the platform frames go out before the judgments, so their credits_charged excludes enrichment. The enrich frames follow, and done carries extra_credits and the full credits_charged. A failure after the platforms settled (402, 429 or 503) arrives as a single error frame, then done.
See also#
Labels, Relevance, Themes, Credits & pricing and Errors.