Metrics API guide
The Metrics API provides programmatic access to the same aggregated performance data visible in the Analyze dashboard. Query delivery rates, click rates, traffic counts, and other channel performance indicators across all your communication channels.
Use the Metrics API when you need to:
- Integrate performance data into your own dashboards or reporting systems
- Query metrics with custom time granulation (hour, day, week, month, quarter, year)
- Automate performance reporting across channels
- Access engagement and delivery data beyond what the dashboard exports
| Capability | Metrics API | Billing Usage API | Analyze dashboard |
|---|---|---|---|
| Data type | Performance (delivery, engagement) | Financial (costs) | Performance |
| Access | Asynchronous API | Asynchronous API | Web interface |
| Time granulation | Hour to year | Day, month | Hour to year (same constraints apply) |
| Retention | Up to 366 days per query | Current month + 2 months prior | 1 year |
| Multitenant | Application, entity | Application, entity | Application, entity |
Access and availability
To use the Metrics API, you need an API key with the metrics:manage scope. See API authorization to configure scopes on your API key.
By default, your results include data for your account only. To include related sub-accounts, set includeSubaccounts to true. If you log in as a sub-account, you see only your own account data.
Coverage
The Metrics API supports the following channels:
How it works
The Metrics API uses an asynchronous request-response pattern:
Submit a request
POST to the Metrics API endpoint with your metrics, filters, and aggregation dimensions.
Receive a request ID
The API immediately returns a request ID (HTTP 201). Processing runs asynchronously.
- Callback (only way to receive results):
callbackUrlis required in every request. Results are pushed to your endpoint when processing completes. - Polling (status only): Use the request ID to check whether processing has finished or failed. This endpoint returns
requestId,status, andfailureMessage. It does not return the result data.
For the full request and response schema, see the Metrics API reference.
Build your request
Every request must contain a callbackUrl and a request object. Inside request, both metrics and aggregateBy are required, and filterBy must specify channelCodes, sentSince, and sentUntil. All other filters are optional. For complete request and response examples, see Query aggregated traffic data.
Metrics [#metrics]
Specify one or more metric codes to calculate. Metrics are channel-specific:
- Messaging channels (SMS, MMS, WhatsApp, Viber Business Messages, RCS, and OTT channels such as Facebook Messenger, Telegram, and LINE): see Messaging metrics reference
- Email: see Email metrics reference
- Voice and Video: see Voice and Video metrics reference
Filters [#filters]
Use filters to narrow which data is included. Channel and time range are required. All other filters are optional.
| Filter | Description |
|---|---|
| Time range | sentSince and sentUntil (required, ISO 8601 UTC). See time granulation constraints. |
| Channel | channelCodes (required). Channel codes such as SMS, EMAIL, and WHATSAPP. See Channel codes for the full list. |
| Country | countryIds, a list of numeric country IDs. This differs from the Billing Usage API, which uses ISO 3166-1 alpha-2 codes. |
| Sender | Sender IDs, numbers, or domains |
| Sender type | See Sender types for all values. |
| Capabilities | Service or technology variant within a channel (for example, VIBER_BM and VIBER_BOTS). See Capabilities for all values. |
| Direction | OUTBOUND, INBOUND |
| Traffic type | Channel-specific values. See Query aggregated traffic data for the full list. These codes are not the same as the traffic type codes used by the Billing Usage API. |
| Status group | PENDING, UNDELIVERABLE, DELIVERED, EXPIRED, REJECTED |
| Error group/code | Specific error categories |
| Campaign/Communication ID | Campaign identifiers |
| Campaign reference | External reference IDs |
| Application/Entity | Multitenant identifiers |
| Account keys | Specific accounts in your hierarchy |
| includeSubaccounts | Set to true to include traffic data from sub-accounts alongside the specified accounts. Defaults to false. |
| Engagement timeframe | Filter by time elapsed between events using time buckets: timeToDeliver (delivery time), timeToAnswer (time until a call was answered), timeToClickFromSeen (click after seen), timeToClickFromDelivered (click after delivery), timeToSeenFromDelivered (seen after delivery), timeToOpenFromDelivered (open after delivery). The from bucket is inclusive and the to bucket is exclusive. |
Channel codes [#channel-codes]
Use these codes in the channelCodes filter and in results grouped by CHANNEL_CODE.
| Code | Channel |
|---|---|
SMS | SMS |
MMS | MMS |
EMAIL | |
WHATSAPP | |
RCS | RCS |
VIBER | Viber (Viber Business Messages, Viber Bots) |
VOICE_VIDEO | Voice and Video |
APPLE_MB | Apple Messages for Business |
FACEBOOK | Facebook Messenger |
TELEGRAM | Telegram |
INSTAGRAM | Instagram (Instagram Direct Messaging) |
KAKAO | Kakao (Kakao Alim Talk, Kakao Brand Message, Kakao Sangdam) |
LINE | LINE (LINE Official Account, LINE Official Notifications) |
ZALO | Zalo (Zalo Notification Services, Zalo Follower) |
For channels with multiple services (Viber, Kakao, LINE, Zalo), use the Capabilities filter to distinguish between service variants.
Aggregate by [#aggregate-by]
Use aggregateBy to group results by one or more dimensions. At least one dimension is required.
URL with non-URL metrics. For example, UNIQUE_URL_CLICK_COUNT is valid with aggregateBy: URL, but TOTAL_TRAFFIC_COUNT is not.| Group | Dimensions |
|---|---|
| Time | HOUR, DAY, WEEK_SATURDAY_START, WEEK_SUNDAY_START, WEEK_MONDAY_START, MONTH, QUARTER, YEAR |
| Account | ACCOUNT_KEY, ACCOUNT_NAME |
| Channel | CHANNEL_CODE, CHANNEL_NAME, DIRECTION, TRAFFIC_TYPE, CAPABILITY |
| Geography | COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE, NETWORK_ID, NETWORK_NAME |
| Sender | SENDER, SENDER_TYPE, SENDER_DOMAIN |
| Campaign | COMMUNICATION, CAMPAIGN_REFERENCE |
| Multitenant | APPLICATION_ID, ENTITY_ID |
| Status | STATUS_GROUP, STATUS, ERROR_GROUP, ERROR_CODE |
| Engagement | TIME_TO_DELIVER, TIME_TO_CLICK_FROM_SEEN, TIME_TO_CLICK_FROM_DELIVERED, TIME_TO_SEEN_FROM_DELIVERED, TIME_TO_OPEN_FROM_DELIVERED |
| Engagement (Voice only) | TIME_TO_ANSWER |
| Other | URL, RECIPIENT_DOMAIN |
CHANNEL_CODE is always included in results regardless of whether it is specified in aggregateBy. This ensures metric accuracy. If neither CHANNEL_CODE nor CHANNEL_NAME is specified, CHANNEL_CODE is added implicitly. If you aggregate by CHANNEL_NAME, CHANNEL_CODE is not added automatically; specify both explicitly if you need both values.Time granulation constraints [#time-granulation-constraints]
The maximum time range depends on the granulation you choose:
| Granulation | Maximum time range | Example |
|---|---|---|
HOUR | 14 days | 2024-05-01 to 2024-05-14: use HOUR |
DAY | 93 days | 2024-02-01 to 2024-05-05: use DAY |
WEEK_SATURDAY_START, WEEK_SUNDAY_START, WEEK_MONDAY_START, MONTH, QUARTER, YEAR | 366 days | 2023-06-01 to 2024-05-27: use any weekly, MONTH, QUARTER, or YEAR granulation |
Response data
Results are delivered to your callback URL as JSON. Polling returns processing status only, not the result data. The callback payload contains the following top-level fields:
| Field | Description |
|---|---|
requestId | Unique identifier for the query request |
status | Whether the request succeeded (SUCCESS) or failed |
response.requestedPeriod | The time range used in the query (sentSince and sentUntil) |
response.totalRows | Total number of data rows returned |
response.columns | Array describing each column in the results: columnName (the metric or dimension code) and columnDataType (STRING, INTEGER, NUMBER, BOOLEAN, DATE_TIME) |
response.rows | Array of data rows. Each row contains values in the same order as the columns array. N/A indicates the metric is not applicable for that channel or row combination. |
Checking the status of a request returns a smaller payload: requestId, status, and failureMessage, which explains the cause when the status is FAILED.
For the full response schema and examples, see Query aggregated traffic data.
Performance considerations
When combining time granulation with multiple grouping dimensions:
- Hourly granulation: Limit to 1 to 2 grouping dimensions. Combining hourly data with many dimensions (country + network + sender) can significantly slow processing.
- Day and month granulation: Handle multiple dimensions well for broad analysis.
- Large account hierarchies: Queries return data for the main account only by default. To include sub-accounts, set
includeSubaccounts: true. UseaccountKeysto limit results to specific accounts in your hierarchy.
Common questions
Troubleshooting
| Problem | Solution |
|---|---|
| Callback URL is not receiving results | Verify that the callback URL is publicly accessible. Check for firewall rules that may block incoming requests. Confirm the request was accepted by checking the request ID returned in the initial response. |
| 401 Unauthorized error | Verify the API key has the metrics:manage scope. See API authorization. |
| Validation error | Check that callbackUrl is present, that filterBy includes channelCodes, sentSince, and sentUntil, and that at least one metric and one aggregateBy dimension are specified. Verify the time range does not exceed the limit for your chosen granulation. |
| Cannot access the Metrics API | Verify the API key has the metrics:manage scope. If the scope is correct, the account may use a legacy setup, which is an architectural limitation that cannot be enabled on request. Contact your account manager to confirm. |
| Rate limit errors | See the Metrics API reference for rate limit details and retry guidance. |
Analyze dashboard
Explore the same performance data in the web interface with no code required.
Messaging metrics reference
Metric definitions, API syntax, and channel support matrix for messaging channels.
Email metrics reference
Email-specific delivery, engagement, and feedback metrics.
Billing Usage API
Query invoice-aligned cost data programmatically for financial reconciliation.