---
title: "Get messages report"
description: "Returns sent, delivered, read, failed, and replied counts plus cost for\na date range, in aggregate and per WhatsApp API number. Pass\n`template_name` to scope the report to one template.\n\n`from` and `to` accept either a plain date (`YYYY-MM-DD`) for daily\nreports or a UTC timestamp (`YYYY-MM-DDTHH:MM:SSZ`) for hourly ranges.\n"
---

> Documentation Index
> Fetch the complete documentation index at: https://zacx.io/llms.txt
> Use this file to discover all available pages before exploring further.

Path: Zacx Public API › Reports

`GET /workspace/reports`

Returns sent, delivered, read, failed, and replied counts plus cost for
a date range, in aggregate and per WhatsApp API number. Pass
`template_name` to scope the report to one template.

`from` and `to` accept either a plain date (`YYYY-MM-DD`) for daily
reports or a UTC timestamp (`YYYY-MM-DDTHH:MM:SSZ`) for hourly ranges.

## Authentication

- `bearerAuth`, http, header `Authorization`

## Query parameters

- `getMessagesReport.query.from` (string, required) — Start of the range, inclusive. A date or a UTC timestamp.
- `getMessagesReport.query.to` (string, required) — End of the range, inclusive. A date or a UTC timestamp.
- `getMessagesReport.query.template_name` (string, optional) — Restrict the report to one template, by its name in your workspace.

## Code samples

### cURL

```curl
curl --request GET \
  --url 'https://api.zacx.io/v1/workspace/reports?from=string&to=string' \
  --header 'Authorization: Bearer <token>'
```

### TypeScript

```typescript
const url = 'https://api.zacx.io/v1/workspace/reports?from=string&to=string';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://api.zacx.io/v1/workspace/reports?from=string&to=string"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.text)
```

## Responses

### 200

The report.

#### Example

```json
{
  "status": "success",
  "data": {
    "reportGeneratedAt": "2026-02-01T07:37:07Z",
    "channel": "whatsapp",
    "aggregateStats": {
      "sent": 14,
      "delivered": 9,
      "read": 7,
      "failed": 5,
      "replied": 3,
      "totalCost": {
        "amount": 12.5,
        "currency": "INR"
      }
    },
    "wabaBreakdown": [
      {
        "wabaNumber": "15558047063",
        "sent": 4,
        "delivered": 0,
        "read": 0,
        "failed": 4,
        "replied": 1,
        "cost": {
          "amount": 0,
          "currency": "INR"
        }
      },
      {
        "wabaNumber": "15558047064",
        "sent": 10,
        "delivered": 9,
        "read": 7,
        "failed": 1,
        "replied": 2,
        "cost": {
          "amount": 12.5,
          "currency": "INR"
        }
      }
    ]
  }
}
```

- `getMessagesReport.response.200.status` (string, required)
- `getMessagesReport.response.200.data` (object, required)
  - `getMessagesReport.response.200.data.templateName` (string, optional) — Present only when the report was scoped with `template_name`.
  - `getMessagesReport.response.200.data.reportGeneratedAt` (string, optional)
    - format `date-time`
  - `getMessagesReport.response.200.data.channel` (string, optional)
    - example `"whatsapp"`
  - `getMessagesReport.response.200.data.aggregateStats` (object, optional)
    - `getMessagesReport.response.200.data.aggregateStats.sent` (integer, optional)
    - `getMessagesReport.response.200.data.aggregateStats.delivered` (integer, optional)
    - `getMessagesReport.response.200.data.aggregateStats.read` (integer, optional)
    - `getMessagesReport.response.200.data.aggregateStats.failed` (integer, optional)
    - `getMessagesReport.response.200.data.aggregateStats.replied` (integer, optional)
    - `getMessagesReport.response.200.data.aggregateStats.totalCost` (object, optional)
      - `getMessagesReport.response.200.data.aggregateStats.totalCost.amount` (number, required)
        - example `12.5`
      - `getMessagesReport.response.200.data.aggregateStats.totalCost.currency` (string, required)
        - example `"INR"`
  - `getMessagesReport.response.200.data.wabaBreakdown` (array<unknown>, optional) — The same counts, split per WhatsApp API number.
    - `getMessagesReport.response.200.data.wabaBreakdown.wabaNumber` (string, optional)
      - example `"15558047064"`
    - `getMessagesReport.response.200.data.wabaBreakdown.sent` (integer, optional)
    - `getMessagesReport.response.200.data.wabaBreakdown.delivered` (integer, optional)
    - `getMessagesReport.response.200.data.wabaBreakdown.read` (integer, optional)
    - `getMessagesReport.response.200.data.wabaBreakdown.failed` (integer, optional)
    - `getMessagesReport.response.200.data.wabaBreakdown.replied` (integer, optional)
    - `getMessagesReport.response.200.data.wabaBreakdown.cost` (object, optional)
      - `getMessagesReport.response.200.data.wabaBreakdown.cost.amount` (number, required)
        - example `12.5`
      - `getMessagesReport.response.200.data.wabaBreakdown.cost.currency` (string, required)
        - example `"INR"`

### 400

A required parameter is missing or invalid.

#### Example

```json
{
  "status": "error",
  "code": "VALIDATION_FAILED",
  "message": "One or more required parameters are missing",
  "errors": [
    {
      "type": "parameter",
      "field": "from",
      "message": "The from query parameter is required.",
      "input": null
    }
  ]
}
```

- `getMessagesReport.response.400.status` (string, required)
- `getMessagesReport.response.400.code` (string, required) — Stable machine-readable error code.
- `getMessagesReport.response.400.message` (string, required) — Human-readable explanation.
- `getMessagesReport.response.400.errors` (array<object>, optional) — One entry per failing parameter.
  - `getMessagesReport.response.400.errors.type` (string, optional)
    - example `"parameter"`
  - `getMessagesReport.response.400.errors.field` (string, optional)
    - example `"from"`
  - `getMessagesReport.response.400.errors.message` (string, optional)
  - `getMessagesReport.response.400.errors.input` (unknown, optional) — The value that was received, or `null` when it was missing.

### 404

No template with that name exists in the workspace.

#### Example

```json
{
  "status": "error",
  "code": "TEMPLATE_NOT_FOUND",
  "message": "The requested template name 'nonexistent_template' could not be found."
}
```

- `getMessagesReport.response.404.status` (string, required)
- `getMessagesReport.response.404.code` (string, required) — Stable machine-readable error code.
- `getMessagesReport.response.404.message` (string, required) — Human-readable explanation.


Source: https://zacx.io/api/workspace/reports/index.md
