The formula
cost_per_requestis a flat fee added to every counted call.unitsis the quantity read atunits_path(or the size of a whole body) from the request or the response;cost_per_unitis the price of one.units_block_sizebills per started block (100for an API priced per 100 characters);units_minimumis the least number of billed units once a quantity was read. Both default to exact billing.reported_costis a USD figure the upstream itself puts in its reply, read atcost_path. An array of numbers is summed.- Token counts read at the token paths are logged, never priced.
2xx reply is not charged, but every forwarded reply counts one request against request rate limits. A call that never receives a reply counts nothing. A counted call whose mapping reads nothing still costs cost_per_request.
Set the relay pricing
- Web UI
- API
- config.json
- Open Relays, select the relay and choose Edit Relay Config.
- On the General tab, under Pricing, set Fee per Call, Price per Unit, Units Read From, Measure, Units Path and the optional Block Size and Minimum Units. The effective formula is written out underneath as you type.
- On the Advanced tab, under Usage Extraction, set Reported Cost Path, Model Path and the token paths, and the Ignore Reported Cost switch.
- Select Save General Configuration (or Save Advanced Configuration).
Mapping fields
All paths are gjson paths into a JSON body (usage.credits, DocumentMetadata.Pages, #.Text). A body is read as JSON when its content type contains json (including application/x-amz-json-1.1) or when it has no content type and parses as JSON. Negative, infinite or missing numbers read as nothing.
ignore_upstream_cost sits on the relay, not in the mapping: when on, cost_path values are dropped everywhere while your fee and unit pricing still apply.
Reading the request body
Whenunits_source is request and the measure needs a path (value or chars), the relay refuses with 400 before contacting the upstream any body it cannot measure unambiguously: a body that is not JSON, one that names a key twice in the same object (case-insensitively), or one that spells the key in a different case than units_path (text for a Text path). Whole-body measures (body_bytes, body_chars) need no such check.
The caller’s Content-Type is not consulted for request-side units, so a caller cannot label a JSON body text/plain to be billed for nothing.
Route overrides
A route’susage overrides the relay mapping field by field. An empty field inherits the relay’s value; a field set to 0 waives it on that route. A route therefore cannot switch a relay path off by leaving it blank; it can only replace it.
A route that sets only a rate is validated against the merged mapping, so it is accepted when the relay already names the units path. In the Web UI, Pricing Override on the route sheet shows the inherited value of each field as a placeholder and the merged formula underneath.
Worked examples
- Per-credit, response side
- Per-page, AWS SigV4
- Per-character, request side
- Blocks and minimum
- Whole request body
- Reported cost
Tavily reports credits spent in its reply.Response
{"usage": {"credits": 4}}:Test pricing
Test Pricing runs a sample call through a relay’s routes and mapping without contacting the upstream: which route matches, whether the call is counted, what each body yields and the resulting cost, with notes explaining every empty field.The Web UI tests the saved relay, so save your pricing edits first. To preview a mapping before saving it, call the API with
config instead of name (below).- Web UI
- API
- Open Relays, select the relay and choose Test Pricing.
- Enter the Method, Path (a query string may follow, as in
/jobs/1?stream=true), the expected Status, any Request Headers a route matches on (oneName: valueper line), the Request Body, the Response Body and its content type. - Select Run Test.
Next steps
- Virtual key access — Where the cost lands: budgets and rate limits.
- Streaming — How a stream is priced per event or by its size.
- Relay Logs — The cost breakdown on every row.

