Analytics Dashboard
Understanding the analytics dashboard for ChinqIT Verify
The analytics dashboard, opened from Analytics in the sidebar, gives you a time-ranged view of your messaging activity and spend. Both the admin dashboard (/admin/analytics) and the client dashboard (/client/analytics) use the same interface, scoped to the appropriate data: admins see platform-wide figures, clients see only their own API-key traffic.
Time range selector
Three preset ranges are available: 7 days, 30 days, and 90 days. Selecting a range reloads all charts and stat cards. Buckets are daily for 7- and 30-day ranges, and weekly for 90 days.
Stat cards
Four cards appear at the top of the dashboard.
| Card | What it shows |
|---|---|
| Money spent | Total spend (negative wallet transactions) in the selected period. The card subtitle shows the total credits (top-ups) received in the same period. |
| Messages | Total messages submitted in the period, across all channels (OTP, SMS, WhatsApp). |
| Success rate | Percentage of messages that were successfully submitted, calculated on the system-fault denominator: successes / (successes + system-caused failures). Recipient-side failures (unreachable number, etc.) do not count against this rate. |
| OTP verified % | Percentage of OTP messages that were subsequently verified by the recipient. Shows a dash when no OTP was sent in the period. |
Internal SMS alerts (low-balance and header-expiration notices sent by the gateway) are ordinary SMS messages owned by the ChinqIT client key: they count as SMS usage and spend, attributed to the ChinqIT client in admin views.
Money over time
An area+line chart shows daily (or weekly) spend and top-ups. The spend figure is the real cost of messages sent, net of refunds — it is sourced from each message's recorded cost, not from wallet ledger debits. The top-ups figure comes from positive ledger entries (credits added to the balance). Hovering a data point shows the exact amounts for that day or week.
The client card label is Money spent; the admin card label is Revenue (billed). In the admin view, both the revenue and top-up figures aggregate across all clients on the platform.
Messages by category
A horizontal stacked-bar breakdown shows, for each channel (otp, sms, whatsapp), how many messages were delivered versus failed. The total message count for each channel appears on the right. Only channels with at least one message in the period are listed.
Message flow
A Sankey diagram visualises how messages move through the system. Flows go from left to right in two stages: channel (OTP / SMS / WhatsApp) → outcome (delivered / pending / failed / rejected). The width of each band is proportional to message volume; hover a band to see its count. Why messages failed is shown in the failure category split below, not as a third stage.
Failure category split
When there are failed messages, a color-coded split bar and legend show why messages failed, broken into five categories:
| Category | Meaning | Color |
|---|---|---|
| System | A platform or gateway error caused the failure — the message never reached the carrier. These failures reduce your success rate. | Red |
| Recipient | The destination number was unreachable, rejected the message, or is invalid. The fault is on the recipient side, not the platform. | Amber |
| Account | The failure was caused by an account-level problem — for example, insufficient balance or an inactive API key. | Blue |
| Content | The message was rejected because of its content — for example, a blocked sender header or a message body that violated carrier rules. | Purple |
| Unknown | The failure could not be classified into one of the above categories. | Gray |
Each category shows its share as a percentage and an absolute count. Recipient failures carry the note "Not your fault — numbers were wrong or unreachable.", and system failures "Refunded automatically."
Export
Export downloads the period as a CSV (analytics-7d.csv, analytics-30d.csv or analytics-90d.csv), one row per day or week with delivered, failed, pending, spend and top-ups. A notification confirms the file name.
API endpoint
The dashboard calls one internal Next.js API route:
GET /api/analytics/summary?range=7|30|90Authentication is session-based (standard dashboard login). The range parameter accepts 7, 30, or 90; any other value defaults to 30. The response shape:
{
"range": { "days": 30, "from": "...", "to": "...", "bucket": "day" },
"cards": {
"messages": 1240,
"successRate": 97,
"moneySpent": 62.40,
"moneyToppedUp": 100.00,
"otpVerifiedRate": 84
},
"money": [
{ "date": "2026-05-30", "spend": 2.10, "topup": 0 }
],
"volume": [
{ "date": "2026-05-30", "delivered": 40, "failed": 1, "pending": 0 }
],
"otp": [
{ "date": "2026-05-30", "sent": 30, "verified": 25 }
],
"byCategory": [
{ "category": "otp", "total": 900, "delivered": 880, "failed": 20 },
{ "category": "sms", "total": 340, "delivered": 330, "failed": 10 }
],
"failures": {
"total": 30,
"byCategory": [
{ "category": "system", "count": 5, "pct": 17 },
{ "category": "recipient", "count": 25, "pct": 83 }
]
}
}volume and otp are dense: one entry per day (or week) in the range, zero-filled. otp counts the OTPs sent and verified in each bucket; the client home draws its OTPs verified trend from it.
The old /api/analytics/verify/* endpoints (latency percentiles, by-country, by-operator, by-line-type, per-message drilldown) have been removed. Use GET /api/analytics/summary for all analytics needs.