Import your own data.
A vendor we have no connector for, a bill, an export from a system of your own: send the rows as JSON in the one shape every connector writes, and they land on the ledger like any other source.
The key
Create the key under Connect → OpenTelemetry; the key it shows is the organization's push key. It writes and cannot read. The read key, the one your editor uses, reads and cannot write.
curl -X POST https://app.valistry.ai/api/v1/records \
-H "Authorization: Bearer vly_ot_…" -H "Content-Type: application/json" \
-d '{"records":[{"source_record_id":"inv-0917-3","occurred_at":"2026-09-17T10:00:00Z",
"provider":"anthropic","model":"claude-sonnet-4","input_tokens":1200,"output_tokens":300,
"team":"support","workflow":"ticket-triage"}]}'The fields
- source_record_id
- Your own id for the row. Required. The same id sent again replaces the row; it never doubles.
- occurred_at
- When, as an ISO 8601 instant with its offset. Required.
- provider · model
- The vendor and the model as the vendor names it. Required. A model the rate card knows is priced from it.
- input_tokens · output_tokens · cached_tokens
- Integers. Optional, default 0.
- cost_usd
- What the row cost, in dollars, when you know it. Optional. Given, it is kept; absent, the tokens are priced.
- request_count
- Calls in the row: one for a call, more for a daily bucket. Optional, default 1.
- status · latency_ms · attempt
- ok, error or timeout; milliseconds; which attempt this was. Optional.
- trace_id
- The trace the call ran in, when you have one: the join to an outcome. Optional.
- application · workflow · team · agent
- Who and what, as your own names; a rule can match on any of them. Optional.
- workload · region
- What the runs were for, from the fixed list; the region. Optional.
- labels
- Your own labels, as key and value: cost_center, env. Lower-case keys, up to 20. A rule can match any of them. Optional.
What happens to a row
- Priced
- A row with tokens and a model we have a price for is priced at the list price, and the record says so. A row with a cost keeps it.
- Unpriced
- A row with neither is stored at $0 and marked; the reply counts them.
- Sent again
- The same id replaces the row. A retry never doubles a dollar.
- Refused
- One row in the wrong format rejects the whole batch; the reply names the row and the field. Nothing is stored.
- Up to
- 5,000 rows a call.