Skip to main content

Analytics API

Analytics endpoints exposed by the Devotel CPaaS API Base path: /api/v1 Endpoint count: 27

Messaging cost analytics with time-series and channel breakdown

GET /api/v1/analytics/costs
Aggregates the tenant’s messaging spend over the selected date range into headline totals (total messages, total spend, average cost per message, billed segments) plus a per-bucket time-series and a per-channel breakdown — each carrying its currency so multi-currency tenants render per-currency series correctly. Powers the Reports page cost summary and the Costs dashboard. Read-only; degrades to a zeroed cost summary (still 200) during a transient database blip so the continuously-polled page never flashes a 5xx.
any
Inclusive start of the reporting window (ISO-8601 date or datetime). Defaults to the last 30 days when omitted; the range may not exceed the platform lookback cap.
any
Inclusive end of the reporting window (ISO-8601 date or datetime). A single-day range (start_date === end_date) is accepted.
any
Alternative rolling lookback in whole days (bounded by the lookback cap). Mutually exclusive with an explicit start/end range.
any
Optional single-channel filter (e.g. sms, whatsapp, email).
any
Time-series bucket granularity.

Per-channel deliverability totals, trend and failure diagnostics

GET /api/v1/analytics/deliverability
Deep deliverability report for a single channel over a rolling window: outbound totals (sent, accepted, delivered, read, terminal, failed, bounced, complained, unsubscribed), the derived delivery/read/failure rates, a per-bucket time-series bucketed in the tenant’s billing timezone, and top-N failure-reason and (for SMS/voice) failure-country breakdowns. Powers the Deliverability dashboard’s per-channel tab. Results are scoped to the caller’s tenant and cached for 60s.
any
required
Channel to report on. The dashboard renders one panel per channel tab.
any
Rolling lookback window.
any
Time-series bucket size. Defaults to hour for the 24h window, day otherwise.

Top carrier rejection codes for a funnel drop-off step

GET /api/v1/analytics/funnel/{step}/drop-reasons
Root-cause drill-down for a delivery-funnel step: returns the leading carrier/provider rejection codes behind messages that dropped at the named step, each enriched with a human-readable name, an actionable description and a category from the carrier error dictionary, plus its count and share of drops. Use it to answer ‘why did messages fail to deliver at this stage?’ from the funnel chart. The sent step (sent-but-never-delivered) is populated today; the other steps are reserved and return an empty reasons array. Read-only; degrades to an empty reasons list (still 200) during a transient database blip.
any
required
Funnel stage to explain. sent returns rejection codes for messages that were sent but never delivered; other steps are reserved and return an empty list.
any
Inclusive start of the reporting window (ISO-8601 date or datetime). Defaults to the last 30 days when omitted.
any
Inclusive end of the reporting window (ISO-8601 date or datetime).
any
Alternative rolling lookback in whole days. Mutually exclusive with an explicit start/end range.
any
Optional single-channel filter (e.g. sms, whatsapp, email).
any
Maximum number of error codes to return.

List conversion goals

GET /api/v1/analytics/goals/
Returns the tenant’s configured conversion goals (paginated by limit/offset), each with its type, attribution model, lookback window, monetary value and — for pixel_fire goals — a copy-paste pixel URL hint. Every row also carries its batched all-time conversion count and revenue so the Goals table renders those columns without an N+1. Use it to populate the analytics Goals management screen.
any
Maximum number of goals to return.
any
Number of goals to skip, for pagination.

Get a conversion goal

GET /api/v1/analytics/goals/{id}
Returns a single conversion goal by id, including its type, attribution model, lookback window, monetary value and (for pixel_fire goals) the signed pixel URL hint. Returns 404 when the goal does not exist in the tenant.
any
required
Goal id.

List a goal’s recorded conversions

GET /api/v1/analytics/goals/{id}/conversions
Returns the most recent conversions recorded against a goal, each with the attributed contact, message, campaign or agent, its value and metadata. Use it to audit what drove a goal’s conversions or to export attribution detail for a specific goal.
any
required
Goal id.
any
Maximum number of conversions to return, newest first.

Get conversion stats for a goal

GET /api/v1/analytics/goals/{id}/stats
Rolls a goal’s conversions over a lookback window into headline totals (conversion count and total value) plus the top attributed messages, campaigns and agents by conversion count. Powers the goal detail page’s attribution breakdown. Use window_days to widen or narrow the reporting window.
any
required
Goal id.
any
Lookback window in days over which conversions are aggregated.

Cross-channel customer-journey path (Sankey) analytics

GET /api/v1/analytics/journey-paths
Reconstructs the ordered touchpoint sequence each customer walked across channels (chat, voice, email, WhatsApp, SMS) from the tenant’s conversations and folds it into a Sankey-ready payload: nodes (a channel occupying an ordered stage), links (stage-to-stage transitions with a journey count), stages (per-stage reached/continued/dropped/drop_off_rate), and top_paths (the most-walked full channel sequences with their share), alongside total_journeys, total_touchpoints, channels, and the echoed window/entry_channel/current_since. Query params: window (24h|7d|30d|90d, default 30d), entry_channel (keep only journeys whose first touchpoint was this channel), max_stages (2-10, default 6), min_journeys (prune links carried by fewer journeys, default 1). Restricted to owner/admin/developer/viewer; read-only, rate-limited, 60s cached.

Aggregate message delivery metrics with time-series

GET /api/v1/analytics/messages
Returns headline messaging KPIs for the selected date range — total sent, delivered, failed and read, the derived delivery and read rates, and the average delivery time — plus a per-bucket (hour/day/week/month) time-series for charting. Powers the Reports page and the insights delivery-trend graph; filter by channel, status or campaign_id, and pass phone_number_id to scope the WhatsApp Quality tile to a single sending number. Read-only; degrades to zeroed totals and an empty time_series (still 200) during a transient database blip so the continuously-polled page never flashes a 5xx.
any
Inclusive start of the reporting window (ISO-8601 date or datetime). Defaults to the last 30 days when omitted; the range may not exceed the platform lookback cap.
any
Inclusive end of the reporting window (ISO-8601 date or datetime). A single-day range (start_date === end_date) is accepted.
any
Alternative rolling lookback in whole days (bounded by the lookback cap). Mutually exclusive with an explicit start/end range.
any
Optional single-channel filter (e.g. sms, whatsapp, email, rcs, viber, telegram).
any
Optional message-status filter (e.g. delivered, failed).
any
Optional filter to a single campaign’s messages.
any
Time-series bucket granularity.
any
Optional WhatsApp multi-WABA scope — narrows the time-series to outbound rows stamped with this sending phone_number_id.

Message volume and delivery by channel

GET /api/v1/analytics/messages/by-channel
Aggregates the tenant’s messaging traffic over the selected date range into a per-channel breakdown — for each channel (sms, whatsapp, email, rcs, viber, telegram, voice) the total messages sent, delivered and failed plus the resulting delivery rate. Powers the Messages hub per-channel slice and the WhatsApp Analytics KPI cards; pass phone_number_id to scope the counts to a single WhatsApp sending number. Read-only, rate-limited, 60s cached; degrades to an empty channels array (still 200) during a transient database blip so the always-on widget never flashes a 5xx.
any
Inclusive start of the reporting window (ISO-8601 date, e.g. 2026-07-01). Defaults to the tenant’s standard lookback when omitted; the range may not exceed the platform lookback cap.
any
Inclusive end of the reporting window (ISO-8601 date). A single-day range (start_date === end_date) is accepted.
any
Alternative rolling lookback in whole days (bounded by the lookback cap). Mutually exclusive with an explicit start/end range.
any
Optional WhatsApp multi-WABA scope — narrows the breakdown to outbound rows stamped with this sending phone_number_id. Ignored by org-wide callers.

Message volume and delivery by destination country

GET /api/v1/analytics/messages/by-country
Breaks the tenant’s messaging traffic for the selected date range down by destination country, returning total sent, delivered and failed plus the delivery rate per country so operators can spot a country where delivery is degrading. Optionally filter to a single channel. Read-only; degrades to an empty countries array (still 200) during a transient database blip so the continuously-polled insights widget never surfaces a 5xx.
any
Inclusive start of the reporting window (ISO-8601 date, e.g. 2026-07-01). Defaults to the tenant’s standard lookback when omitted; the range may not exceed the platform lookback cap.
any
Inclusive end of the reporting window (ISO-8601 date). A single-day range (start_date === end_date) is accepted.
any
Alternative rolling lookback in whole days (bounded by the lookback cap). Mutually exclusive with an explicit start/end range.
any
Optional single-channel filter (e.g. sms, whatsapp, email).

Failed-message breakdown by error code

GET /api/v1/analytics/messages/errors
Returns the leading provider/carrier error codes behind failed messages over the selected date range, each with its occurrence count, alongside the total failed volume — the drill-down operators use to see which rejection reason dominates. Optionally filter to a single channel. Read-only; degrades to an empty breakdown (still 200) during a transient database blip instead of a blind 5xx.
any
Inclusive start of the reporting window (ISO-8601 date, e.g. 2026-07-01). Defaults to the tenant’s standard lookback when omitted; the range may not exceed the platform lookback cap.
any
Inclusive end of the reporting window (ISO-8601 date). A single-day range (start_date === end_date) is accepted.
any
Alternative rolling lookback in whole days (bounded by the lookback cap). Mutually exclusive with an explicit start/end range.
any
Optional single-channel filter (e.g. sms, whatsapp, email).

Carrier, country and error-code delivery histograms

GET /api/v1/analytics/messaging-insights
Twilio-Messaging-Insights-style diagnostics for a single messaging channel over a rolling window: per-carrier and per-destination-country delivery/failure rates, the dominant provider error codes with taxonomy-resolved names and actionable descriptions, and a roll-up of those errors by category (carrier filtering, content, opt-out, network). Use it to answer ‘which carrier is filtering me?’ or ‘which country is degrading?’. Narrow to one dimension with the carrier, country or errorCode filters.
any
Messaging channel to analyse. Restricted to channels that carry MCCMNC + error_code.
any
Rolling lookback window.
any
Filter to a single carrier/provider by name.
any
Filter to a single ISO-3166-1 alpha-2 country code.
any
Filter to a single raw provider error_code.

Per-MNO delivery truth with silent-drop detection

GET /api/v1/analytics/per-mno-delivery
Delivery breakdown by mobile network operator (MCCMNC) for SMS or voice over a rolling window, including delivered/failed counts, delivery and engagement rates, an inferred-dropped estimate, and a silent-drop suspicion flag for MNOs whose delivery rate falls below the threshold on a sufficient sample — the signal that a carrier is accepting then silently dropping traffic. Override the defaults (drop_rate < 92, 4h silent window, 50-message minimum sample) with dropRateThreshold, silentWindowHours and minSampleSize for niche traffic profiles such as alerting or 2FA-only.
any
required
Channel to analyse. Restricted to channels with first-class MNO data.
any
Rolling lookback window.
any
Delivery-rate floor (percent). MNOs below this may be flagged. Defaults to 92.
any
Silent-drop detection window in hours. Defaults to 4.
any
Minimum terminal-message sample before an MNO can be flagged. Defaults to 50.

List scheduled analytics reports

GET /api/v1/analytics/scheduled-reports
Returns the organization’s saved recurring analytics reports (messaging volume, deliverability, top contacts, spend, or a custom saved query), keyset-paginated. Each item carries its cadence, recipients, filters, enabled flag, timezone and the last/next send timestamps. Pass cursor (the nextCursor from the previous page) and limit to page through; total is the real count across all pages.
any
Opaque nextCursor returned by the previous page; a missing or malformed cursor degrades to the first page.
any
Page size, bounded to 1–200.

Conversation sentiment roll-up analytics

GET /api/v1/analytics/sentiment
Portfolio-level conversation-sentiment roll-up over a rolling window: an overall net-sentiment index plus trend buckets and breakdowns by channel, assigned agent, detected language and resolution state — so a CX team can monitor experience across all threads at once rather than one at a time and catch a ‘great in English, failing in another locale’ gap. Optionally narrow every breakdown with a single channel or language filter.
any
Rolling lookback window.
any
Optional single-channel filter (e.g. chat, voice, email, whatsapp).
any
Optional detected-conversation-language filter (ISO 639-1, e.g. en, es); ‘unknown’ selects messages with no detected language.

Telegram bot delivery KPIs

GET /api/v1/analytics/telegram
Telegram-specific messaging KPIs over the selected date range — bot-blocked rate (users who blocked the bot), the group-versus-DM volume split by chat type, the custom-emoji-button rate, and a daily trend — because Telegram’s delivery semantics differ from SMS/WhatsApp and the generic time-series does not capture them. Read-only; degrades to zeroed totals (still 200) during a transient database blip.
any
Inclusive start of the reporting window (ISO-8601 date, e.g. 2026-07-01). Defaults to the tenant’s standard lookback when omitted; the range may not exceed the platform lookback cap.
any
Inclusive end of the reporting window (ISO-8601 date). A single-day range (start_date === end_date) is accepted.
any
Alternative rolling lookback in whole days (bounded by the lookback cap). Mutually exclusive with an explicit start/end range.

Record a conversion via the tracking pixel

GET /g/{goalId}/{contactId}.gif
Public 1×1 transparent GIF conversion pixel. Embed the signed URL on a third-party thank-you or confirmation page; when the browser loads the image, Orbit records a conversion for the given goal and contact. The request is HMAC-signed (sig) and bound to goalId, contactId and the tenant schema, so a third party can neither forge a conversion nor replay a signature into a different tenant’s goal. The endpoint always returns the GIF with a 200 — even when the signature is missing or invalid — so the host page never shows a broken image.
string
required
The goal the conversion is credited to.
string
required
The contact the conversion is attributed to.
string
required
HMAC-SHA256 signature binding goalId, contactId and the tenant schema. Minted by Orbit when the pixel URL is generated.
string
required
The tenant schema the goal belongs to; verified against the signature so a swapped value cannot cross-tenant-write.

Record an email open via the tracking pixel

GET /p/{sig}.gif
Public 1×1 transparent GIF open-tracking pixel embedded in outbound HTML emails. When the recipient’s mail client loads the image, Orbit verifies the HMAC signature (sig) — which binds the message id, tenant, and send timestamp — and records an email-open engagement event. The endpoint always returns the GIF with a 200, even when the signature is missing or invalid, so a mail client never shows a broken image.
string
required
HMAC-SHA256 signature binding the message id, tenant, and send timestamp. Minted by Orbit when the email is rendered.

Create a conversion goal

POST /api/v1/analytics/goals/
Creates a conversion goal for the tenant. Choose a type (pixel_fire, webhook_hit, manual, tag_added, custom_event), an attribution model and a lookback window; pixel_fire goals return a signed pixel URL hint you can embed on a thank-you page. Requires the owner, admin or developer role. Returns the created goal (201).

Record a conversion for a goal

POST /api/v1/analytics/goals/{id}/record
Records one or more conversions against a goal — the manual/server-to-server counterpart to the tracking pixel. Attach a contact_id, an optional value_cents override and free-form metadata. Server-to-server callers may authenticate the contact by sending an Authorization: HMAC &lt;contactId&gt;:&lt;sig&gt; header (sig = HMAC-SHA256 of goalId:contactId with the tenant API secret); an unsigned external contact_id is never accepted. Returns the recorded conversion rows (201).
any
required
Goal id.

Create a scheduled analytics report

POST /api/v1/analytics/scheduled-reports
Schedules a recurring analytics report emailed to one or more recipients on a daily, weekly or monthly cadence. Choose a report type (messaging_volume, deliverability, top_contacts, spend or custom), 1–50 unique recipient emails, optional filters (a custom report’s filters.dataset selects the messages or queue_performance dataset), an enabled flag, and an IANA timezone the cadence anchors to. Requires an owner, admin or developer role; returns the created report with its computed next_send_at.
any
1–50 unique recipient emails, as an array or a comma-separated string.

Send a scheduled report immediately

POST /api/v1/analytics/scheduled-reports/{id}/send-now
Queues an out-of-cadence run of an existing scheduled report so its next delivery fires now, without changing its recurring schedule. The API marks the row due and the webhook-worker picks it up on its next tick (keeping the send/retry path out of the API replica); poll the report’s last_sent_at for progress. The report must belong to the caller’s organization.
string
required
Scheduled-report id to send now.

Update a conversion goal

PATCH /api/v1/analytics/goals/{id}
Partially updates a conversion goal — send only the fields you want to change (at least one is required). Useful for renaming a goal, adjusting its value, changing the attribution model, or enabling/disabling it. Requires the owner, admin or developer role. Returns the updated goal, or 404 when it does not exist.
any
required
Goal id.

Update a scheduled analytics report

PATCH /api/v1/analytics/scheduled-reports/{id}
Updates one or more fields of an existing scheduled report — its name, type, frequency, recipients, filters, enabled flag or timezone. At least one field must be provided; the cadence’s next_send_at is recomputed when the frequency or timezone changes. Requires an owner, admin or developer role and that the report belongs to the caller’s organization.
string
required
Scheduled-report id to update.
any

Delete a conversion goal

DELETE /api/v1/analytics/goals/{id}
Permanently deletes a conversion goal by id. Existing recorded conversions are unaffected by the delete. Requires the owner, admin or developer role. Returns 404 when the goal does not exist in the tenant.
any
required
Goal id.

Delete a scheduled analytics report

DELETE /api/v1/analytics/scheduled-reports/{id}
Permanently removes a scheduled report so it stops being emailed. The report must belong to the caller’s organization and the delete is audit-logged. Returns the deleted id. Requires an owner, admin or developer role.
string
required
Scheduled-report id to delete.