# 비동기 메시지 통계 내보내기

`exportMessagesStatistics`는 메시지 기록 및 통계를 서버의 CSV 파일로 내보냅니다. [`messages:list`](/ko/developer/api-reference/statistics-api/message-statistics-api/#messageslist)가 처리할 수 없는 대규모 또는 전체 계정 데이터를 가져올 때 사용하세요.

## messages:list 대신 내보내기를 사용해야 하는 경우

`messages:list`는 제한된 기간의 실시간, 페이지네이션된 조회를 위해 사용합니다. 결과가 `messages:list`의 딥 페이지네이션 한도(`page × per_page > 100000`)를 초과하거나, 페이지네이션된 JSON 대신 다운로드 가능한 단일 파일을 목표로 할 때 `exportMessagesStatistics`를 사용하세요. 내보내기는 결과를 하나의 응답에 보관하는 대신 디스크의 파일로 스트리밍하므로 `date_range`나 행 수에 제한이 없습니다.

## 내보내기 흐름 작동 방식

1. `messages:list`와 동일한 필터로 [`export`](#export)를 호출합니다. 응답은 파일이 생성되기 전에 즉시 `uid` 작업 식별자를 반환합니다.
2. 해당 `uid`로 [`status`](#status)를 폴링하여 `STATUS_SUCCESS`(또는 `STATUS_FAILED`)를 보고할 때까지 기다립니다.
3. 동일한 `uid`로 [`result`](#result)를 호출하여 생성된 `file`과 바로 사용할 수 있는 `file_url`을 가져옵니다.
4. 파일을 [다운로드](#download)합니다. `file_url`을 그대로 사용하거나, 비어 있는 경우 [`result`](#result)를 참조하여 `file`에서 URL을 구성하세요.

[`lastTasks`](#lasttasks)를 사용하여 애플리케이션의 최근 내보내기 작업을 조회하고, [`delete`](#delete)를 사용하여 작업을 취소하거나 보존 기간 전에 파일을 제거하세요.

## 메서드

내보내기 라이프사이클에는 5개의 메서드와 일반 다운로드 엔드포인트가 있습니다:

| 메서드 | 설명 |
|--------|--------------|
| [`exportMessagesStatistics/export`](#export) | 내보내기를 대기열에 추가하고 작업 `uid`를 반환합니다. |
| [`exportMessagesStatistics/status`](#status) | 작업 진행 상황을 확인합니다. |
| [`exportMessagesStatistics/result`](#result) | 작업이 완료되면 생성된 파일 이름을 반환합니다. |
| [`exportMessagesStatistics/lastTasks`](#lasttasks) | 애플리케이션의 최근 내보내기 작업을 나열합니다. |
| [`exportMessagesStatistics/delete`](#delete) | 보존 기간이 만료되기 전에 작업을 취소하거나 파일을 제거합니다. |
| [다운로드](#download) | 이름으로 생성된 CSV 파일을 다운로드합니다. |

### export

메시지 기록 내보내기를 대기열에 추가하고 즉시 작업 식별자를 반환합니다.

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

##### 헤더

요청에는 서버 API 토큰이 필요합니다:

| 이름 | 필수 | 설명 |
|------------------|----------|---------------------------------------------------------------------------------------------------------|
| `Authorization` | 예 | [서버 API 토큰](/ko/developer/api-reference/api-access-token/#server-api-token). 다음 형식으로 제공해야 합니다: `Authorization: Api <Server Key>`. |

##### 요청 본문 매개변수

요청 본문은 다음 필드를 허용합니다:

| 이름 | 필수 | 타입 | 설명 |
|----------------------------------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------|
| `type` | 예 | String | `"TASK_TYPE_EXPORT<wbr/>_MESSAGES_V2"`여야 합니다. |
| <code>export_messages<wbr/>_v2</code> | 예 | Object | 내보내기 매개변수, 아래에 설명되어 있습니다. |
| <code>export_messages<wbr/>_v2.application<wbr/>_code</code> | 참고 참조 | String | [Pushwoosh 애플리케이션 코드](/ko/developer/api-reference/api-identifiers/#application-code). `app_group_code`가 설정되지 않은 경우 필수입니다. |
| <code>export_messages<wbr/>_v2.app<wbr/>_group_code</code> | 참고 참조 | String | 애플리케이션 그룹 코드, 그룹의 모든 앱에 대해 내보냅니다. `application_code`가 설정되지 않은 경우 필수입니다. |
| <code>export_messages<wbr/>_v2.search</code> | 아니요 | String | 메시지 제목 및 내용에 대한 자유 텍스트 검색. |
| <code>export_messages<wbr/>_v2.filters</code> | 아니요 | Object | 메시지 필터, 아래에 설명되어 있습니다. 전체 계정 기록을 내보내려면 생략하세요. |
| <code>export_messages<wbr/>_v2.properties</code> | 아니요 | Array | CSV에 포함할 열, 아래에 설명되어 있습니다. |

`export_messages_v2.filters`는 다음을 허용합니다:

| 이름 <div style="width:150px"></div> | 타입 | 설명 |
|---------------------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------|
| `statuses` | Array | 포함할 메시지 상태. <details><summary>가능한 값</summary><ul><li><code>"MESSAGE_STATUS_CANCELED"</code></li><li><code>"MESSAGE_STATUS_CREATING"</code></li><li><code>"MESSAGE_STATUS_DONE"</code></li><li><code>"MESSAGE_STATUS_FAIL"</code></li><li><code>"MESSAGE_STATUS_PENDING"</code></li><li><code>"MESSAGE_STATUS_PROCESSING"</code></li><li><code>"MESSAGE_STATUS_WAITING"</code></li></ul></details> |
| `platforms` | Array | `messages:list`에서 사용하는 플랫폼 이름 문자열이 아닌 [플랫폼 코드](/ko/developer/api-reference/messages-api/api-prerequisites/#platforms) (숫자, 예: iOS의 경우 `1`). |
| `sent_date` | Object | 전송 날짜로 필터링된 보고 기간: `{"date_from": "YYYY-MM-DD", "date_to": "YYYY-MM-DD"}`. |
| `created_date` | Object | 메시지 생성 날짜로 필터링된 보고 기간, `sent_date`와 동일한 형식. |
| `created_via` | Array | 메시지 소스. <details><summary>가능한 값</summary><ul><li><code>"AB_TEST"</code></li><li><code>"API"</code></li><li><code>"AUTO_PUSH"</code></li><li><code>"CP"</code></li><li><code>"CSV"</code></li><li><code>"CUSTOMER_JOURNEY"</code></li><li><code>"EMAIL_API"</code></li><li><code>"EMAIL_CP"</code></li><li><code>"GEO_ZONE"</code></li><li><code>"PUSH_ON_EVENT"</code></li><li><code>"RSS"</code></li><li><code>"SYSTEM"</code></li></ul></details> |
| `segments` | Array | 메시지가 전송된 [필터 코드](/ko/developer/api-reference/api-identifiers/#segment--filter-code). |
| `campaigns` | Array | [캠페인 코드](/ko/developer/api-reference/api-identifiers/#campaign-code). `messages:list`와 달리 단일 코드가 아닌 목록을 받습니다. |
| `message_id` | String (uint64) | 따옴표로 묶인 단일 숫자 메시지 ID. `messages:list`와 달리 내보내기는 배열이 아닌 하나의 ID를 받습니다. |
| `message_code` | String | 단일 [메시지 코드](/ko/developer/api-reference/api-identifiers/#message-code). |

`export_messages_v2.properties`는 CSV에 포함될 열을 선택합니다.

<details>
<summary>가능한 값</summary>

- `"EXPORT_MESSAGE_PROPERTY_ID"`
- `"EXPORT_MESSAGE_PROPERTY_TIMESTAMP"`
- `"EXPORT_MESSAGE_PROPERTY_CONTENT"`
- `"EXPORT_MESSAGE_PROPERTY_TITLE"`
- `"EXPORT_MESSAGE_PROPERTY_CAMPAIGN_NAME"`
- `"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"`

</details>

<Aside type="caution" title="properties는 단순한 필터가 아닙니다">
`properties`에 나열되지 않은 속성은 기본 열(ID, 전송 날짜, 내용, 상태)을 포함하여 파일에 전혀 나타나지 않습니다. `properties`를 비워두면 열이 없는 CSV가 생성됩니다. 기본 세트에 추가하려는 메트릭뿐만 아니라 내보내기에 포함되어야 하는 모든 열을 나열하세요.
</Aside>

##### 요청 예시

```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: 잘못된 API 액세스 토큰">
```json
{
  "error": "account not found"
}
```
</TabItem>
</Tabs>

### status

내보내기 작업의 진행 상황을 반환합니다.

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

##### 요청 본문 매개변수

`export`에서 반환된 작업 식별자를 전달합니다:

| 이름 | 필수 | 타입 | 설명 |
|-------|----------|---------|--------------------------------------------------|
| `uid` | 예 | String (int64) | `export` 응답의 작업 식별자, 예: `"177458"`. |

##### 요청 예시

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

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

`status`는 `"STATUS_PENDING"`, `"STATUS_SUCCESS"` 또는 `"STATUS_FAILED"` 중 하나입니다. `progress`는 `0`과 `1` 사이의 분수입니다. `result`를 호출하기 전에 `status`가 `"STATUS_SUCCESS"`에 도달할 때까지 폴링하세요.

### result

작업이 완료되면 생성된 파일 이름을 반환합니다.

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

##### 요청 본문 매개변수

`export`에서 반환된 동일한 작업 식별자를 전달합니다:

| 이름 | 필수 | 타입 | 설명 |
|-------|----------|---------|--------------------------------------------------|
| `uid` | 예 | String (int64) | `export` 응답의 작업 식별자, 예: `"177458"`. |

##### 요청 예시

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

<Tabs>
<TabItem label="200: OK">
```json
{
  "export_messages_v2_result": {
    "file": "Export_Messages_v2_12345_20260813120000-a1b2c3d4.csv",
    "file_url": "https://app.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/download/Export_Messages_v2_12345_20260813120000-a1b2c3d4.csv"
  }
}
```
</TabItem>
</Tabs>

`status`가 `"STATUS_SUCCESS"`를 보고하기 전에 `result`를 호출하면 빈 결과가 반환됩니다. `file_url`은 계정의 올바른 데이터 센터에 있는 [다운로드 엔드포인트](#download)에 대한 바로 사용할 수 있는 링크입니다. `file`에서 직접 URL을 구성하는 대신 그대로 사용하세요. 계정의 데이터 센터에 기본 URL이 구성되어 있지 않으면 `file_url`은 비어 있습니다. 이 경우 계정이 기본 `app.pushwoosh.com` 데이터 센터에 있는 경우에만 `file`에서 URL을 구성하는 것으로 대체할 수 있습니다. 다른 데이터 센터나 화이트라벨 도메인에 있는 계정은 `file`만으로는 올바른 호스트를 유추할 방법이 없습니다.

### lastTasks

애플리케이션의 최근 내보내기 작업을 최신순으로 나열합니다.

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

##### 요청 본문 매개변수

모든 매개변수는 선택적 필터입니다. 토큰이 액세스할 수 있는 모든 작업을 나열하려면 모두 생략하세요:

| 이름 | 필수 | 타입 | 설명 |
|------------------|----------|---------|---------------------------------------------------------------------------------------|
| `application` | 아니요 | String | [Pushwoosh 애플리케이션 코드](/ko/developer/api-reference/api-identifiers/#application-code). 토큰이 액세스할 수 있는 모든 애플리케이션의 작업을 나열하려면 생략하세요. |
| `types` | 아니요 | Array | 특정 작업 유형으로 제한합니다. 메시지 내보내기만 보려면 <code>["TASK_TYPE_EXPORT<wbr/>_MESSAGES_V2"]</code>를 사용하세요. |
| `campaign` | 아니요 | String | [캠페인 코드](/ko/developer/api-reference/api-identifiers/#campaign-code)로 필터링합니다. |
| `message_id` | 아니요 | String (uint64) | 따옴표로 묶인 단일 숫자 메시지 ID로 필터링합니다. |
| `message_code` | 아니요 | String | 단일 [메시지 코드](/ko/developer/api-reference/api-identifiers/#message-code)로 필터링합니다. |
| `limit` | 아니요 | Integer | 반환할 최대 작업 수. |
| `timestamp_from` | 아니요 | String | 이 타임스탬프(RFC 3339) 이후에 생성된 작업만 반환합니다. |

<Aside type="note">
작업은 7일 파일 보존 기간이 지난 후 파일이 이미 삭제되었는지 여부와 관계없이 30일 동안 보관됩니다. `lastTasks`는 `result`가 더 이상 다운로드 가능한 파일로 확인되지 않는 작업을 계속 표시할 수 있습니다.
</Aside>

##### 요청 예시

```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",
        "file_url": "https://app.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/download/Export_Messages_v2_12345_20260813120000-a1b2c3d4.csv"
      }
    }
  ]
}
```
</TabItem>
</Tabs>

### delete

7일 보존 기간이 만료되기 전에 작업과 해당 파일을 삭제합니다.

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

##### 요청 본문 매개변수

`export`에서 반환된 작업 식별자를 전달합니다:

| 이름 | 필수 | 타입 | 설명 |
|-------|----------|---------|--------------------------------------------------|
| `uid` | 예 | String (int64) | `export` 응답의 작업 식별자, 예: `"177458"`. |

##### 요청 예시

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

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

<span id="download" />

### 다운로드

`result`에서 생성된 CSV 파일을 이름으로 다운로드합니다.

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

##### 헤더

다른 메서드와 동일한 방식으로 인증하거나 활성 Control Panel 세션에 의존합니다:

| 이름 | 필수 | 설명 |
|------------------|----------|-----------------------------------------------------------------------------------------------------|
| `Authorization`| 예 | [서버 API 토큰](/ko/developer/api-reference/api-access-token/#server-api-token), 다른 `exportMessagesStatistics` 메서드와 동일한 형식: `Authorization: Api <Server Key>` (`Api` 스킴은 대소문자를 구분하지 않음). `Authorization` 헤더가 없고 로그인된 Control Panel 세션이 없는 요청은 `401 Unauthorized`를 받습니다. |

`<file>`을 `result` 응답의 정확한 `file` 값으로 바꾸세요. 예:

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

<Aside type="caution">
이 URL을 수동으로 구성하는 것은 기본 `app.pushwoosh.com` 데이터 센터의 계정에서만 작동합니다. 다른 데이터 센터(`app.wavesend.ru` (OVB), `app.pushwoosh.us` (IAD))나 화이트라벨 도메인에 있는 계정은 다른 호스트가 필요하며, `file`만으로는 이를 유추할 방법이 없습니다. 대신 [`result`](#result) 또는 [`lastTasks`](#lasttasks)의 `file_url`을 사용하세요. 이 URL은 이미 계정에 맞는 올바른 호스트를 가리키고 있습니다. `file_url`이 비어 있는 경우 어떻게 해야 하는지는 [`result`](#result)를 참조하세요.
</Aside>

파일은 `properties`에서 선택한 열을 포함하는 CSV입니다. 내보내기가 완료된 후 7일 동안 사용할 수 있으며, 그 후 정리 작업이 파일을 제거하고 URL은 더 이상 확인되지 않습니다.

### 메시지 수신자 내보내기

동일한 `export`, `status`, `result`, `lastTasks`, `delete`, `download` 메서드로 하나의 메시지에 대한 개별 수신자도 내보낼 수 있습니다. `export_messages_v2` 대신 `"type": "TASK_TYPE_EXPORT_MESSAGE_RECIPIENTS"`와 `export_message_recipients` 객체를 사용하세요.

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

<Aside type="note" title="Customer Journey Holdout Split과는 다릅니다">
이 내보내기는 **메시지**가 제외한 수신자를 대상으로 합니다. Customer Journey의 [Holdout Split](/ko/product/customer-journey/journey-elements/flow-controls/holdout-split/) 지점은 다른 메커니즘입니다. 이 지점은 메시지가 전송되기 전에 *journey*의 나머지 부분에서 사용자를 제외하며, 해당 `exportJourneyPointUsers` 작업(동일한 `export`/`status`/`result` 메서드, 다른 `type`)은 전송 결과가 아닌 브랜치 멤버십을 보고합니다.
</Aside>

##### export_message_recipients 요청 필드

| 이름 <div style="width:150px"></div> | 필수 | 타입 | 설명 |
|---------------------------------------|----------|---------|-------------------------------------------------------------------------------------------------------|
| `message_id` | 참고 참조 | String (uint64) | 단일 숫자형 메시지 ID. `campaign`이 설정되지 않은 경우 필수입니다. |
| `campaign` | 참고 참조 | String | 단일 [캠페인 코드](/ko/developer/api-reference/api-identifiers/#campaign-code). `message_id`가 설정되지 않은 경우 필수입니다. 둘 다 설정하면 해당 캠페인 내에서 메시지의 행으로 범위가 좁혀집니다. |
| `application` | 예 | String | 메시지가 속한 [애플리케이션 코드](/ko/developer/api-reference/api-identifiers/#application-code). |
| `type` | 예 | String | 내보낼 수신자의 종류. `"sends"`, `"deliveries"`, `"opens"`, `"holdout"` 중 하나입니다(아래 참조). |
| `date_from` / `date_to` | 아니요 | String (date-time) | 행을 이 기간으로 제한합니다. 둘 다 생략하면 메시지의 전체 기록을 내보냅니다. |

`message_id`와 `campaign`을 모두 생략하거나 `application`을 생략하면 누락된 필드를 명시하는 오류와 함께 실패합니다. 다른 계정의 `message_id`는 내보내기가 실행되기 전에 확인되어 `NotFound: message not found`로 실패합니다. 같은 계정 내 다른 애플리케이션에 속한 `message_id` 또는 `campaign`은 거부되지 않습니다. 일치하는 행이 없으며, CSV는 헤더만 포함된 채로 다운로드됩니다.

`type`은 수신자 집합을 선택합니다:

| 값 | 반환되는 행 |
|----------------|--------------------------------------------------------------------------------------------------------------------|
| `"sends"` | 메시지가 수락된 모든 수신자. |
| `"deliveries"` | `sends` 중 제공자가 전달을 확인한 수신자. |
| `"opens"` | `sends` 중 메시지를 연 수신자. |
| `"holdout"` | 다른 메시지가 아니라 이 메시지가 제외한 수신자. 이들에게는 아무것도 전송되지 않았습니다. 계정 전체의 [컨트롤 그룹](/ko/product/audience-data-and-segmentation/control-groups/) 또는 메시지 자체의 `holdout_percentage`([Messaging API v2](/ko/developer/api-reference/messaging-api-v2/notify/) 참조) 모두 이 행을 만들 수 있습니다. |

##### 요청 예시

```json
{
  "type": "TASK_TYPE_EXPORT_MESSAGE_RECIPIENTS",
  "export_message_recipients": {
    "message_id": "22875465358",
    "application": "6D382-5ADFE",
    "type": "holdout",
    "date_from": "2026-08-01T00:00:00Z",
    "date_to": "2026-09-30T00:00:00Z"
  }
}
```

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

메시지 기록 내보내기와 동일한 방식으로 [`status`](#status)를 폴링하고 [`result`](#result)를 호출하세요. `result`는 `export_messages_v2_result` 대신 `export_message_recipients_result`를 반환합니다:

```json
{
  "export_message_recipients_result": {
    "file": "Message_22875465358_Holdout_29820-fe5d8ba468df25b7.csv",
    "file_url": "https://app.pushwoosh.com/api/v2/statistics/exportMessagesStatistics/download/Message_22875465358_Holdout_29820-fe5d8ba468df25b7.csv"
  }
}
```

`sends`, `deliveries`, `opens`는 하나의 열 집합을 공유합니다: `hwid, user_id, platform, send_timestamp, delivery_timestamp, open_timestamp, send_error, pae, send_status`. `pae`는 플랫폼이 전송을 수락했지만 이에 대해 눈에 보이는 알림을 표시하지 않은 경우 `false`이며, 이는 집계 통계에서 [`unshowable_sends`](/ko/developer/api-reference/statistics-api/message-statistics-api/)가 집계하는 것과 같은 경우입니다. `holdout`에는 더 짧은 자체 열 집합이 있습니다: `hwid, user_id, platform, holdout_timestamp`.