---
description: API 캠페인으로 발송된 메시지 결과를 조회하는 기능을 제공합니다.
---

# API 캠페인 발송 결과 조회



## 기본 정보

### BASE URL

```
https://api-v2.effic.biz/
```

#### 데이터 조회 제한 사항

* 하루전 발송 결과를 확인 할 수 있으며, 매일 오전 4시에 데이터가 갱신됩니다.
* 발송 후처리(대체 발송, 문자 수신 결과 추적)로 인해 최대 3일까지 발송 결과가 변경됩니다.
* 발송 결과는 최대 90일 이전까지 조회할 수 있습니다.
* 조회에 대한 API rate limit 은 2 req/s 로 제한됩니다.

## 요청

### 요청 예시

* **URL**: `GET api-campaign/message`

### Header

| 항목            | 필수 여부 | 설명                        |
| ------------- | ----- | ------------------------- |
| Authorization | Yes   | `Basic` 인증 방식으로 API 키를 포함 |
| token         | No    | 다음 페이지 조회를 위한 토큰          |

\[[에픽 워크스페이스 API 키 가이드](../api)]

* 첫 번째 요청에는 `token`을 포함하지 않으며, 응답에서 `nextToken` 값을 받아 다음 페이지를 조회할 때 사용합니다.
* `token` 값이 유효하지 않으면 `BadRequestException`이 발생합니다.
* `token`은 캠페인 하루 기준 으로 데이터를 구분하는 역할을 합니다.
  1. 첫 번째 요청에는 `token` 없이 API를 호출합니다.
  2. 응답에 `nextToken` 값이 포함될 경우 이후 요청에서 `token`을 사용하여 추가 데이터를 조회합니다.
  3. 하나의 캠페인 실행 기준으로 10,000개 이상의 메시지가 존재하면 `token`이 나뉘어 제공됩니다.
  4. `token`이 더 이상 반환되지 않으면, 모든 데이터를 조회한 것입니다.

### Parameter

| 파라미터       | 타입     | 필수 여부 | 설명                         |
| ---------- | ------ | ----- | -------------------------- |
| campaignId | string | No    | 캠페인의 고유 ID                 |
| startDate  | string | Yes   | 조회 시작 날짜 (`YYYY-MM-DD` 형식) |
| endDate    | string | Yes   | 조회 종료 날짜 (`YYYY-MM-DD` 형식) |

> `startDate` 는 90일 이전까지 설정 가능합니다.
>
> `startDate` 와 `endDate` 간 간격은 7일을 초과할 수 없습니다.
>
> `campaignId` 가 없다면 워크스페이스 전체 API 캠페인 결과에 대한 검색을 실행합니다.

## 응답

***

### Body

```json
{
  "data": [
    {
      "id": "1245",
      "status": "success",
      "type": "alimtalk",
      "callerNumber": "02-1234-1234",
      "registeredAt": "2025-01-01T10:00:00Z",
      "receiverNumber": "010-1234-5678",
      "receivedAt": "2025-01-01T10:07:00Z",
      "subject": "제목입니다!",
      "content": "내용입니다!",
      "campaignName": "알림톡 자동화 켐페인",
      "campaignId": "2",
      "channelName": "effic",
      "channelId": "@effic",
      "templateCode": "SIGNUP"
    }
  ],
  "nextToken": "bdfc5bde-4532-4cc1-84fe-064660ed44be"
}
```

> 응답 데이터는 문자 메시지, 알림톡, 친구톡과 `nextToken`으로 구성됩니다.\
> 데이터가 많을 경우, `nextToken`이 포함되어 다음 페이지 요청에 사용됩니다.\
> `nextToken`이 `null`이면 더 이상 조회할 데이터가 없습니다.

#### 문자 메시지 (textMessage)

| 필드명             | 타입     | 필수 여부 | 설명                                 |
| --------------- | ------ | ----- | ---------------------------------- |
| id              | string | Yes   | 메시지의 고유 ID                         |
| status          | string | Yes   | 메시지 상태                             |
| textMessageType | string | Yes   | 문자 유형 (`sms`, `lms`, `mms`)        |
| intentType      | string | Yes   | 메시지 정보 유형 (`ad`: 광고성, `info`: 정보성) |
| callerNumber    | string | Yes   | 발신 번호                              |
| registeredAt    | string | Yes   | 발송 준비 시간                           |
| receiverNumber  | string | No    | 수신 번호                              |
| receivedAt      | string | No    | 수신 시간                              |
| subject         | string | No    | 메시지 제목                             |
| content         | string | Yes   | 메시지 내용                             |
| reason          | string | No    | 실패 사유 (해당 시)                       |
| reasonDetail    | string | No    | 상세 실패 사유                           |
| telecom         | string | No    | 통신사 정보 (`SKT`, `KT`, `LG`)         |
| campaignId      | string | Yes   | 캠페인의 고유 ID                         |
| campaignName    | string | Yes   | 캠페인 이름                             |
| tag             | string | No    | 태그이름                               |
| type            | string | Yes   | 메시지 유형 (`text_message`)            |

***

#### 알림톡 (alimtalk)

| 필드명             | 타입     | 필수 여부 | 설명                  |
| --------------- | ------ | ----- | ------------------- |
| id              | string | Yes   | 메시지의 고유 ID          |
| status          | string | Yes   | 메시지 상태              |
| receiverNumber  | string | No    | 수신 번호               |
| registeredAt    | string | Yes   | 발송 준비 시간            |
| receivedAt      | string | No    | 수신 시간               |
| subject         | string | No    | 메시지 제목              |
| content         | string | Yes   | 메시지 내용              |
| reason          | string | No    | 실패 사유 (해당 시)        |
| reasonDetail    | string | No    | 상세 실패 사유            |
| templateCode    | string | Yes   | 사용된 템플릿 코드          |
| campaignId      | string | Yes   | 캠페인의 고유 ID          |
| campaignName    | string | Yes   | 캠페인 이름              |
| channelId       | string | Yes   | 카카오 채널 식별자          |
| channelName     | string | Yes   | 카카오 채널 이름           |
| templateCode    | string | Yes   | 사용된 템플릿 코드          |
| tag             | string | No    | 태그이름                |
| type            | string | Yes   | 메시지 유형 (`alimtalk`) |
| failoverContent | string | No    | 대체 발송 내용            |
| failoverSubject | string | No    | 대체 발송 제목            |

***

#### 친구톡 (friendtalk)

| 필드명             | 타입     | 필수 여부 | 설명                    |
| --------------- | ------ | ----- | --------------------- |
| id              | string | Yes   | 메시지의 고유 ID            |
| status          | string | Yes   | 메시지 상태                |
| receiverNumber  | string | No    | 수신 번호                 |
| registeredAt    | string | Yes   | 발송 준비 시간              |
| receivedAt      | string | No    | 수신 시간                 |
| subject         | string | No    | 메시지 제목                |
| content         | string | Yes   | 메시지 내용                |
| reason          | string | No    | 실패 사유 (해당 시)          |
| reasonDetail    | string | No    | 상세 실패 사유              |
| templateCode    | string | Yes   | 사용된 템플릿 코드            |
| campaignId      | string | Yes   | 캠페인의 고유 ID            |
| campaignName    | string | Yes   | 캠페인 이름                |
| tag             | string | No    | 태그이름                  |
| type            | string | Yes   | 메시지 유형 (`friendtalk`) |
| channelId       | string | Yes   | 카카오 채널 식별자            |
| channelName     | string | Yes   | 카카오 채널 이름             |
| failoverContent | string | No    | 대체 발송 내용              |
| failoverSubject | string | No    | 대체 발송 제목              |

#### 메시지 상태 (status)

| 상태 값                 | 설명                               |
| -------------------- | -------------------------------- |
| success              | 메시지 정상 전송 완료                     |
| fail                 | 메시지 전송 실패                        |
| blocked              | 메시지 차단                           |
| filtered             | 내부 정첵에 의해 발송 필터링                 |
| processing           | 전송중 - 메시지가 발송 중인 상태              |
| confirming           | 메시지 발송 요청은 완료했으며, 수신 성공 여부를 확인 중 |
| failover\_success    | 대체 발송 성공                         |
| failover\_processing | 대체 발송 진행중                        |
| failover\_fail       | 대체 발송 실패                         |

***

#### 예시 코드 (Node.js)

```js
import axios from "axios";

async function sleep(second) {
  return new Promise((resolve) => {
    setTimeout(resolve, second * 1000);
  });
}

async function fetchMessages(baseUrl, params, authToken) {
  let nextToken = null;
  let allData = [];

  do {
    try {
      const response = await axios.get(baseUrl, {
        headers: {
          Authorization: `Basic ${authToken}`,
          token: nextToken,
        },
        params: {
          ...params,
        },
      });

      allData = allData.concat(response.data.data);
      nextToken = response.data.nextToken || null;

      if (nextToken) {
        console.log(
          `Next token received: ${nextToken}. Sleeping for 1 sec to comply with rate limit.`
        );
        await sleep(1); // 2 req/s 제한 준수를 위해 1sec 대기
      }
    } catch (error) {
      console.error("API 요청 실패:", error.message);
      break;
    }
  } while (nextToken);

  return allData;
}

const baseUrl = "https://api-v2.effic.biz/message";
const params = {
  type: "auto",
  campaignId: "1",
  startDate: "2025-03-12",
  endDate: "2025-03-12",
};
const authToken = "TDBH343tG0GDFGHBFNBFNFDSGHDS"; // Base64 인코딩된 API 키

fetchMessages(baseUrl, params, authToken)
  .then((messages) => console.log("조회된 메시지 개수:", messages.length))
  .catch((err) => console.error(err.message));
```

### 오류 응답

모든 오류 응답은 아래 형식을 따릅니다:

```json
{
  "statusCode": "422",
  "message": "수신자는 최소 1명 이상이어야 합니다.",
}
```

#### 오류 코드 목록

| 코드    | 설명                  |
| ----- | ------------------- |
| `422` | 필드 누락, UUID 형식 오류 등 |
| `404` | 존재하지 않는 캠페인 ID      |
| `400` | 유효하지 않은 시간 등        |
| `401` | 인증 실패               |
| `500` | 서버 내부 처리 중 오류 발생    |
| `429` | rate limit 초과       |
