Track expenses
The expenses command (aliases: expense, track-expenses) mirrors the
/settings/track-expenses page. It’s strictly read-only — wallet
movements are recorded by the messaging pipeline, not by this surface.
The CLI gives you every panel the page shows: summary, category
breakdown, country breakdown, trend chart, per-message log, and the same
Export CSV button.
Backed by /api/v1/app/expenses/*.
Quick start
splashify expenses # summary card
splashify expenses categories # breakdown by message category
splashify expenses countries # breakdown by destination country
splashify expenses trends # daily series (for the chart)
splashify expenses logs # per-message transactions
splashify expenses export > expenses.csv # same as page's Export CSVCommand reference
splashify expenses — summary
splashify expenses # default (alias: summary)
splashify expenses summary
splashify expenses --period 30d # narrow the window
splashify expenses --period 7d
splashify expenses --period today| Backed by | GET /api/v1/app/expenses/summary[?period=…] |
|---|
Response shape:
{
"success": true,
"summary": {
"total_deducted": 4521.50,
"total_messages": 18420,
"currency": "INR",
"period": "30d",
"categories": [/* see below */],
"countries": [/* see below */]
}
}Category breakdown
splashify expenses categories # alias: category | breakdown
splashify expenses categories --period 30d| Backed by | GET /app/expenses/categories[?period=…] |
|---|
Returns the same categories array embedded in the summary, with
category (e.g. MARKETING, UTILITY, AUTHENTICATION, SERVICE),
amount, messages, and percentage per row.
Country breakdown
splashify expenses countries # alias: top-countries
splashify expenses countries --period 30d| Backed by | GET /app/expenses/countries[?period=…] |
|---|
Per-row: country_code (ISO-2), country_name, messages, amount,
percentage — feeds the page’s country panel.
Trend chart
splashify expenses trends # daily series (alias: trend | chart)
splashify expenses trends --period 30d
splashify expenses trends --period 7d| Backed by | GET /app/expenses/trends[?period=…] |
|---|
Returns daily[] with date (ISO date), amount, messages per day.
Per-message log
splashify expenses logs # alias: log | transactions
splashify expenses logs --period all # entire history
splashify expenses logs --limit 200
splashify expenses logs --period 30d --limit 1000| Backed by | GET /app/expenses/billing-logs?period=…&limit=… |
|---|
Each row is one billing event:
{
"log_id": "uuid",
"wa_message_id": "wamid.HBg…",
"phone_number": "+919876543210",
"country_code": "IN",
"category": "MARKETING",
"amount": 0.245,
"currency": "INR",
"billed_at": "2026-05-20T14:00:00Z",
"broadcast_id": "uuid|null"
}CSV export
splashify expenses export > expenses.csv # alias: csv
splashify expenses export --period 30d > monthly.csv| Backed by | GET /app/expenses/export[?period=…] |
|---|
Streams the same CSV the page’s Export CSV button produces. Includes
a UTF-8 BOM so Excel renders the ₹ symbol correctly without manual
encoding selection.
Common workflows
”How much did MARKETING cost me last month?”
splashify expenses categories --period 30d | \
jq '.categories[] | select(.category == "MARKETING") | {amount, messages, percentage}'Daily burn-rate chart in your terminal
splashify expenses trends --period 30d | \
jq -r '.daily[] | "\(.date)\t\(.amount)"' | \
awk '{ printf "%-12s %s\n", $1, sprintf("%"int($2/10)"s", "") }' | sed 's/ /█/g'Cost per broadcast
splashify expenses logs --period 30d --limit 10000 | \
jq 'group_by(.broadcast_id // "non-broadcast") |
map({broadcast: .[0].broadcast_id, total: (map(.amount) | add), messages: length}) |
sort_by(-.total)'Reconcile against wallet history
# Sum the billing logs and compare to wallet transactions
SUM=$(splashify expenses logs --period 30d --limit 100000 | jq '[.logs[].amount] | add')
WALLET=$(splashify wallet transactions | jq '[.transactions[] | select(.type == "debit" and .reason == "message_charge") | .amount] | add')
echo "Expenses logs: $SUM"
echo "Wallet debits: $WALLET"Export and load into a spreadsheet
splashify expenses export --period 30d > may.csv
open may.csv # macOS — opens in Excel/NumbersThe BOM ensures ₹ renders. If your version of Excel still mangles it,
re-open via Data → Get Data → From Text and pick UTF-8 explicitly.
Periods
The --period flag accepts the same values across all subcommands:
| Value | Meaning |
|---|---|
today | Just today (UTC) |
7d | Last 7 days |
30d | Last 30 days (default) |
90d | Last 90 days |
all | Entire history (use sparingly — large response) |
Troubleshooting
Counts don’t match a single broadcast’s reported cost — broadcast
costs are aggregated on the broadcast row (splashify broadcast <id>).
The expenses log records each individual message; sum by broadcast_id
to reconcile.
logs is paginated — when the result count equals --limit, there
may be more. The endpoint doesn’t expose page directly; raise --limit
or shorten --period. For tens of thousands of rows, prefer export
(streams as CSV without the pagination boundary).
CSV opens with garbled ₹ in Excel — the file has a BOM but some
older Excel versions still need a manual UTF-8 selection: open Excel
first → Data → Get Data → From Text → pick expenses.csv → set encoding
to UTF-8.
See also
splashify wallet— wallet balance + raw transaction history (not the same as expense logs).splashify broadcasts— per-broadcast cost on each campaign’s detail view.splashify billing— GST profile, invoices, subscription billing (separate from per-message expenses).