# Asynchronous message statistics export

`exportMessagesStatistics` exports message history and statistics to a CSV file on the server, without the row and date-range limits of [`messages:list`](/developer/api-reference/statistics-api/message-statistics-api/#messageslist). Use it to pull a full account's message history or any period that the live endpoint's 100,000-row window can't page through.

## When to use export instead of messages:list

Use `messages:list` for live, paginated lookups of a bounded period. Use `exportMessagesStatistics` when the result would exceed the deep-pagination limit of `messages:list` (`page × per_page > 100000`), or when the goal is a single downloadable file rather than paged JSON. The export has no limit on `date_range` or row count, because it streams the result to a file on disk instead of holding it in one response.

<Aside type="caution" title="Shared worker pool">
The export service runs a pool of **2 workers for the entire account base**, not per account. It fits a scheduled or on-demand full-history pull; it is not a substitute for frequent reporting, where several concurrent export requests would queue behind each other. Exported files are deleted after **7 days**; download the file before that window closes.
</Aside>

## How the export flow works

1. Call [`export`](#exportmessagesstatisticsexport) with the same filters as `messages:list`. The response returns a `uid` task identifier immediately, before the file is generated.
2. Poll [`status`](#exportmessagesstatisticsstatus) with that `uid` until it reports `STATUS_SUCCESS` (or `STATUS_FAILED`).
3. Call [`result`](#exportmessagesstatisticsresult) with the same `uid` to get the generated file name.
4. [Download](#downloading-the-exported-file) the file by name.

Use [`lastTasks`](#exportmessagesstatisticslasttasks) to look up recent export tasks for an application, and [`delete`](#exportmessagesstatisticsdelete) to cancel a task or remove its file early.

## exportMessagesStatistics/export

Queues a message history export and returns a task identifier right away.

`POST` `https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/export`

##### Headers

| Name    <div style="width:200px"></div>        | Required <div style="width:100px"></div>| Description  <div style="width:150px"></div>                                                                                        |
|----------------|----------|------------------------------------------------------------------------------------------------------|
| `Authorization`| Yes      | [Server API token](/developer/api-reference/api-access-token/#server-api-token). Must be provided in the following format: `Authorization: Api <Server Key>`.     |

##### Request body parameters

| Name <div style="width:170px"></div> | Required <div style="width:100px"></div> | Type <div style="width:100px"></div> | Description <div style="width:150px"></div> |
|--------------------------------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------|
| `type`                                | Yes      | String  | Must be `"TASK_TYPE_EXPORT_MESSAGES_V2"`.                                                                                     |
| `export_messages_v2`                  | Yes      | Object  | Export parameters, described below.                                                                                            |
| `export_messages_v2.application_code` | See note | String  | [Pushwoosh application code](/developer/api-reference/api-identifiers/#application-code). Required if `app_group_code` is not set. |
| `export_messages_v2.app_group_code`   | See note | String  | Application group code, exports across every app in the group. Required if `application_code` is not set.                     |
| `export_messages_v2.search`           | No       | String  | Free-text search over message title and content.                                                                               |
| `export_messages_v2.filters`          | No       | Object  | Message filters, described below. Omit to export the whole account history.                                                    |
| `export_messages_v2.properties`       | No       | Array   | Columns to include in the CSV, described below.                                                                                 |

`export_messages_v2.filters` accepts:

| Name <div style="width:150px"></div> | Type    | Description                                                                                                                             |
|---------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------|
| `statuses`                            | Array   | Message statuses to include. Possible values: `"MESSAGE_STATUS_CANCELED"`, `"MESSAGE_STATUS_CREATING"`, `"MESSAGE_STATUS_DONE"`, `"MESSAGE_STATUS_FAIL"`, `"MESSAGE_STATUS_PENDING"`, `"MESSAGE_STATUS_PROCESSING"`, `"MESSAGE_STATUS_WAITING"`. |
| `platforms`                           | Array   | [Platform codes](/developer/api-reference/messages-api/api-prerequisites/#platforms) (numeric, e.g. `1` for iOS), not the platform name strings used by `messages:list`. |
| `sent_date`                           | Object  | Reporting period filtered on send date: `{"date_from": "YYYY-MM-DD", "date_to": "YYYY-MM-DD"}`.                                          |
| `created_date`                        | Object  | Reporting period filtered on message creation date, same format as `sent_date`.                                                          |
| `created_via`                         | Array   | Message source. Possible values: `"AB_TEST"`, `"API"`, `"AUTO_PUSH"`, `"CP"`, `"CSV"`, `"CUSTOMER_JOURNEY"`, `"EMAIL_API"`, `"EMAIL_CP"`, `"GEO_ZONE"`, `"PUSH_ON_EVENT"`, `"RSS"`, `"SYSTEM"`. |
| `segments`                            | Array   | [Filter codes](/developer/api-reference/api-identifiers/#segment--filter-code) the message was sent to.                                 |
| `campaigns`                           | Array   | [Campaign codes](/developer/api-reference/api-identifiers/#campaign-code). Unlike `messages:list`, this takes a list, not a single code. |
| `message_id`                          | String (uint64) | A single numeric message ID, quoted. Unlike `messages:list`, export takes one ID, not an array.                                |
| `message_code`                        | String  | A single [message code](/developer/api-reference/api-identifiers/#message-code).                                                        |

`export_messages_v2.properties` selects which columns the CSV contains. Possible values: `"EXPORT_MESSAGE_PROPERTY_ID"`, `"EXPORT_MESSAGE_PROPERTY_TIMESTAMP"`, `"EXPORT_MESSAGE_PROPERTY_CONTENT"`, `"EXPORT_MESSAGE_PROPERTY_TITLE"`, `"EXPORT_MESSAGE_PROPERTY_APPLICATIONS"`, `"EXPORT_MESSAGE_PROPERTY_STATUS"`, `"EXPORT_MESSAGE_PROPERTY_PLATFORMS"`, `"EXPORT_MESSAGE_PROPERTY_SOURCE"`, `"EXPORT_MESSAGE_PROPERTY_FILTER"`, `"EXPORT_MESSAGE_PROPERTY_SUBSCRIPTION_SEGMENTS"`, `"EXPORT_MESSAGE_PROPERTY_SENT"`, `"EXPORT_MESSAGE_PROPERTY_OPENED"`, `"EXPORT_MESSAGE_PROPERTY_ERRORS"`, `"EXPORT_MESSAGE_PROPERTY_RECIPIENTS"`, `"EXPORT_MESSAGE_PROPERTY_DELIVERED"`, `"EXPORT_MESSAGE_PROPERTY_TOTAL_DELIVERED"`, `"EXPORT_MESSAGE_PROPERTY_TOTAL_OPENED"`, `"EXPORT_MESSAGE_PROPERTY_TOTAL_CLICKS"`, `"EXPORT_MESSAGE_PROPERTY_CLICKS"`, `"EXPORT_MESSAGE_PROPERTY_UNSUBSCRIBED"`.

<Aside type="caution" title="properties is not just a filter">
A property not listed in `properties` does not appear in the file at all, including the base columns (ID, send date, content, status). Leaving `properties` empty produces a CSV with no columns. List every column the export should contain, not only the metrics you want to add on top of a default set.
</Aside>

##### Example request

```json
{
  "type": "TASK_TYPE_EXPORT_MESSAGES_V2",
  "export_messages_v2": {
    "application_code": "XXXXX-XXXXX",
    "filters": {
      "created_date": {
        "date_from": "2026-01-01",
        "date_to": "2026-06-30"
      },
      "statuses": ["MESSAGE_STATUS_DONE"],
      "platforms": [1, 3]
    },
    "properties": [
      "EXPORT_MESSAGE_PROPERTY_ID",
      "EXPORT_MESSAGE_PROPERTY_TIMESTAMP",
      "EXPORT_MESSAGE_PROPERTY_STATUS",
      "EXPORT_MESSAGE_PROPERTY_PLATFORMS",
      "EXPORT_MESSAGE_PROPERTY_SENT",
      "EXPORT_MESSAGE_PROPERTY_OPENED"
    ]
  }
}
```

<Tabs>
<TabItem label="200: OK">
```json
{
  "uid": "177458"
}
```
</TabItem>
<TabItem label="401: Incorrect API access token">
```json
{
  "error": "account not found"
}
```
</TabItem>
</Tabs>

## exportMessagesStatistics/status

Returns the progress of an export task.

`POST` `https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/status`

##### Request body parameters

| Name  | Required | Type    | Description                                     |
|-------|----------|---------|--------------------------------------------------|
| `uid` | Yes      | String (int64) | Task identifier from the `export` response, e.g. `"177458"`. |

##### Example request

```json
{
  "uid": "177458"
}
```

<Tabs>
<TabItem label="200: OK">
```json
{
  "status": "STATUS_SUCCESS",
  "progress": 1
}
```
</TabItem>
</Tabs>

`status` is one of `"STATUS_PENDING"`, `"STATUS_SUCCESS"`, or `"STATUS_FAILED"`. `progress` is a fraction between `0` and `1`; poll `status` until it reaches `"STATUS_SUCCESS"` before calling `result`.

## exportMessagesStatistics/result

Returns the generated file name once the task has completed.

`POST` `https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/result`

##### Request body parameters

| Name  | Required | Type    | Description                                     |
|-------|----------|---------|--------------------------------------------------|
| `uid` | Yes      | String (int64) | Task identifier from the `export` response, e.g. `"177458"`. |

##### Example request

```json
{
  "uid": "177458"
}
```

<Tabs>
<TabItem label="200: OK">
```json
{
  "export_messages_v2_result": {
    "file": "Export_Messages_v2_12345_20260813120000-a1b2c3d4.csv"
  }
}
```
</TabItem>
</Tabs>

Calling `result` before `status` reports `"STATUS_SUCCESS"` returns an empty result. Pass the `file` value as-is to the [download endpoint](#downloading-the-exported-file).

## exportMessagesStatistics/lastTasks

Lists recent export tasks for an application, most recent first.

`POST` `https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/lastTasks`

##### Request body parameters

| Name             | Required | Type    | Description                                                                         |
|------------------|----------|---------|---------------------------------------------------------------------------------------|
| `application`    | No       | String  | [Pushwoosh application code](/developer/api-reference/api-identifiers/#application-code). Omit to list tasks across all applications the token has access to. |
| `types`          | No       | Array   | Restrict to specific task types. Use `["TASK_TYPE_EXPORT_MESSAGES_V2"]` to only see message exports. |
| `campaign`       | No       | String  | Filter by [campaign code](/developer/api-reference/api-identifiers/#campaign-code).  |
| `message_id`     | No       | String (uint64) | Filter by a single numeric message ID, quoted.                                  |
| `message_code`   | No       | String  | Filter by a single [message code](/developer/api-reference/api-identifiers/#message-code). |
| `limit`          | No       | Integer | Maximum number of tasks to return.                                                    |
| `timestamp_from` | No       | String  | Only return tasks created after this timestamp (RFC 3339).                          |

<Aside type="note">
Tasks are kept for 30 days regardless of whether their file has already been deleted after the 7-day file retention window — `lastTasks` can still show a task whose `result` no longer resolves to a downloadable file.
</Aside>

##### Example request

```json
{
  "application": "XXXXX-XXXXX",
  "types": ["TASK_TYPE_EXPORT_MESSAGES_V2"],
  "limit": 10
}
```

<Tabs>
<TabItem label="200: OK">
```json
{
  "tasks": [
    {
      "id": "177458",
      "timestamp": "2026-08-13T12:00:00Z",
      "status": "STATUS_SUCCESS",
      "requested_by_user": "user@example.com",
      "export_messages_v2": {
        "application_code": "XXXXX-XXXXX"
      },
      "export_messages_v2_result": {
        "file": "Export_Messages_v2_12345_20260813120000-a1b2c3d4.csv"
      }
    }
  ]
}
```
</TabItem>
</Tabs>

## exportMessagesStatistics/delete

Deletes a task and its file before the 7-day retention window expires.

`POST` `https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/delete`

##### Request body parameters

| Name  | Required | Type    | Description                                     |
|-------|----------|---------|--------------------------------------------------|
| `uid` | Yes      | String (int64) | Task identifier from the `export` response, e.g. `"177458"`. |

##### Example request

```json
{
  "uid": "177458"
}
```

<Tabs>
<TabItem label="200: OK">
```json
{}
```
</TabItem>
</Tabs>

## Downloading the exported file

`GET` `https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/download/<file>`

##### Headers

| Name    <div style="width:200px"></div>        | Required <div style="width:100px"></div>| Description  <div style="width:150px"></div>                                                                                        |
|----------------|----------|------------------------------------------------------------------------------------------------------|
| `Authorization`| Yes      | [Server API token](/developer/api-reference/api-access-token/#server-api-token), in the same format as the other `exportMessagesStatistics` methods: `Authorization: Api <Server Key>` (the `Api` scheme is case-insensitive). A request with no `Authorization` header and no logged-in Control Panel session gets `401 Unauthorized`.     |

Replace `<file>` with the exact `file` value from the `result` response, for example:

```
https://api.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/download/Export_Messages_v2_12345_20260813120000-a1b2c3d4.csv
```

The file is a CSV containing the columns selected in `properties`. It stays available for 7 days after the export finishes, then the cleanup job removes it and the URL stops resolving.