Skip to main content
Diff VoiceGateway’s recorded costs against a provider’s usage export.

Synopsis

voicegw reconcile reads VG’s per-request log records for a date window, parses an operator-supplied normalized provider usage file, and produces a per-model diff with absolute and percent differences. The full workflow (when to reconcile, how to interpret the diff, expected drift per modality) lives at Cost Reconciliation. The provider-side input file format is documented per provider at Reconcile File Formats.

Usage

Options

Prerequisites

  • Cost tracking enabled in voicegw.yaml (the command exits with 1 otherwise).
  • A provider usage file in VG’s canonical schema (one schema per provider; see Reconcile File Formats).

Output

Text (default)

An aligned table with one row per model. Columns: model, VG units, provider units, units delta%, VG cost, provider cost, cost delta$, cost delta%. Rows whose absolute cost diff % exceeds --threshold are tagged with a trailing * and rendered in ANSI yellow when stdout is a TTY (no color when piped or captured). Models present in only one side carry a (no vg data) or (no provider data) suffix instead. A Total row sums VG cost and provider cost across rows where both sides matched (missing-side rows are excluded so their $0 placeholders do not skew the total). When any rows are flagged, a footer line (N flagged row(s) marked with *) follows. The unit label adapts to the provider:
  • tokens for OpenAI (input + output, summed).
  • audio_s for Deepgram (seconds; VG-side minutes are converted at the boundary).
  • chars for Cartesia.

CSV

Twelve columns: model, vg_units, provider_units, units_diff_abs, units_diff_pct, vg_cost_usd, provider_cost_usd, cost_diff_abs, cost_diff_pct, matched_in_vg, matched_in_provider, flagged. The flagged column is True/False so spreadsheets can filter on it without re-deriving the threshold comparison.

JSON

A nested document matching design §2.2:
total sums only rows where both sides matched (missing-side rows excluded, mirroring the text format). flagged_count counts rows where flagged=True. Useful for piping into a monitoring or alerting tool.

Examples

Diff May 2026 OpenAI usage

JSON output for piping

The JSON output is a nested document keyed on rows, not a top-level array. Use the .rows[] selector as shown above.

Cartesia with the JSON variant of the canonical file

Exit codes

voicegw export-costs | voicegw costs

See also