get-campaign-statistics-csv
curl --request GET \
--url https://api.notifly.tech/v1/projects/{projectId}/statistics.csv \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"start": "2025-06-01",
"end": "2025-06-07",
"tags": [
"exampleTag"
]
}
'import requests
url = "https://api.notifly.tech/v1/projects/{projectId}/statistics.csv"
payload = {
"start": "2025-06-01",
"end": "2025-06-07",
"tags": ["exampleTag"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.get(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({start: '2025-06-01', end: '2025-06-07', tags: ['exampleTag']})
};
fetch('https://api.notifly.tech/v1/projects/{projectId}/statistics.csv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.notifly.tech/v1/projects/{projectId}/statistics.csv",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => json_encode([
'start' => '2025-06-01',
'end' => '2025-06-07',
'tags' => [
'exampleTag'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.notifly.tech/v1/projects/{projectId}/statistics.csv"
payload := strings.NewReader("{\n \"start\": \"2025-06-01\",\n \"end\": \"2025-06-07\",\n \"tags\": [\n \"exampleTag\"\n ]\n}")
req, _ := http.NewRequest("GET", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.notifly.tech/v1/projects/{projectId}/statistics.csv")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"start\": \"2025-06-01\",\n \"end\": \"2025-06-07\",\n \"tags\": [\n \"exampleTag\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.notifly.tech/v1/projects/{projectId}/statistics.csv")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"start\": \"2025-06-01\",\n \"end\": \"2025-06-07\",\n \"tags\": [\n \"exampleTag\"\n ]\n}"
response = http.request(request)
puts response.read_body[
{
"date": "2025-06-01",
"resource_type": "campaign",
"resource_id": "xyz123",
"resource_name": "2025 여름 할인 캠페인",
"node_id": null,
"node_mane": null,
"variant_id": "xyz123",
"variant_name": "할인율 50%",
"channel": "push-notification",
"channel_sub": "image",
"brand_message_target": "M",
"tags": [
"summer",
"discount",
"mobile"
],
"message_sent": 1500,
"message_failed": 23,
"delivered": 1477,
"click": 234,
"conversion": [
{
"name": "구매완료",
"type": "전체 전환",
"count": 45
},
{
"name": "구매완료",
"type": "전환 매출",
"count": 138849
}
]
},
{
"date": "2025-06-01",
"resource_type": "user-journey",
"resource_id": "xyz123",
"resource_name": "신규 회원 온보딩",
"node_id": "abc123",
"node_mane": "회원가입 d+1 메시지",
"variant_id": "xyz123",
"variant_name": "환영 메시지",
"channel": "kakao-alimtalk",
"channel_sub": null,
"brand_message_target": null,
"tags": [],
"message_sent": 892,
"message_failed": 5,
"delivered": 887,
"click": 156,
"conversion": [
{
"name": "프로필완성",
"type": "전체 전환",
"count": 5
}
]
}
]{
"error": "InvalidRequest",
"message": "..."
}{
"error": "Unauthorized: Invalid token"
}{
"error": "Request timeout. Check the Input Parameters or try again with a shorter date range."
}{
"error": "InternalServerError",
"message": "..."
}내보내기 & 분석
메시지 통계 조회
조회 당일을 제외한 일자, 캠페인, 채널 별로 발송 성공, 실패, 도달, 클릭, 전환 수를 조회하여 CSV로 추출합니다.
GET
/
v1
/
projects
/
{projectId}
/
statistics.csv
get-campaign-statistics-csv
curl --request GET \
--url https://api.notifly.tech/v1/projects/{projectId}/statistics.csv \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"start": "2025-06-01",
"end": "2025-06-07",
"tags": [
"exampleTag"
]
}
'import requests
url = "https://api.notifly.tech/v1/projects/{projectId}/statistics.csv"
payload = {
"start": "2025-06-01",
"end": "2025-06-07",
"tags": ["exampleTag"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.get(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({start: '2025-06-01', end: '2025-06-07', tags: ['exampleTag']})
};
fetch('https://api.notifly.tech/v1/projects/{projectId}/statistics.csv', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.notifly.tech/v1/projects/{projectId}/statistics.csv",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_POSTFIELDS => json_encode([
'start' => '2025-06-01',
'end' => '2025-06-07',
'tags' => [
'exampleTag'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.notifly.tech/v1/projects/{projectId}/statistics.csv"
payload := strings.NewReader("{\n \"start\": \"2025-06-01\",\n \"end\": \"2025-06-07\",\n \"tags\": [\n \"exampleTag\"\n ]\n}")
req, _ := http.NewRequest("GET", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.notifly.tech/v1/projects/{projectId}/statistics.csv")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"start\": \"2025-06-01\",\n \"end\": \"2025-06-07\",\n \"tags\": [\n \"exampleTag\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.notifly.tech/v1/projects/{projectId}/statistics.csv")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"start\": \"2025-06-01\",\n \"end\": \"2025-06-07\",\n \"tags\": [\n \"exampleTag\"\n ]\n}"
response = http.request(request)
puts response.read_body[
{
"date": "2025-06-01",
"resource_type": "campaign",
"resource_id": "xyz123",
"resource_name": "2025 여름 할인 캠페인",
"node_id": null,
"node_mane": null,
"variant_id": "xyz123",
"variant_name": "할인율 50%",
"channel": "push-notification",
"channel_sub": "image",
"brand_message_target": "M",
"tags": [
"summer",
"discount",
"mobile"
],
"message_sent": 1500,
"message_failed": 23,
"delivered": 1477,
"click": 234,
"conversion": [
{
"name": "구매완료",
"type": "전체 전환",
"count": 45
},
{
"name": "구매완료",
"type": "전환 매출",
"count": 138849
}
]
},
{
"date": "2025-06-01",
"resource_type": "user-journey",
"resource_id": "xyz123",
"resource_name": "신규 회원 온보딩",
"node_id": "abc123",
"node_mane": "회원가입 d+1 메시지",
"variant_id": "xyz123",
"variant_name": "환영 메시지",
"channel": "kakao-alimtalk",
"channel_sub": null,
"brand_message_target": null,
"tags": [],
"message_sent": 892,
"message_failed": 5,
"delivered": 887,
"click": 156,
"conversion": [
{
"name": "프로필완성",
"type": "전체 전환",
"count": 5
}
]
}
]{
"error": "InvalidRequest",
"message": "..."
}{
"error": "Unauthorized: Invalid token"
}{
"error": "Request timeout. Check the Input Parameters or try again with a shorter date range."
}{
"error": "InternalServerError",
"message": "..."
}조회 조건전일 데이터는 매일 오전 7시(KST)에 집계가 완료됩니다. 정확한 전일 데이터 조회를 위해서는 오전 7시 이후에 API를 호출하시기를 권장합니다.
집계 표기 일자일자별 데이터는 발생 일자 기준으로 집계 및 표기됩니다. 예를 들어 7월 23일 발송한 캠페인의 클릭이 24일에 발생했다면, 23일에 발송, 24일에 클릭 이벤트가 집계됩니다.
인증
POST /authenticate로 발급받은 인증 토큰을 Bearer 형식으로 전달합니다.
경로 매개변수
프로젝트 ID
본문
application/json
응답
성공적인 통계 조회입니다
통계 데이터 날짜 (YYYY-MM-DD 형식)
리소스 타입
사용 가능한 옵션:
campaign, user-journey 메시지 내용 (채널별로 상이한 구조)
캠페인 ID (캠페인 리소스인 경우에만 존재)
캠페인 이름 (캠페인 리소스인 경우에만 존재)
Variant ID (캠페인 리소스이고, A/B 테스트인 경우에만 존재)
Variant 이름 (캠페인 리소스이고, A/B 테스트인 경우에만 존재)
캠페인 태그 목록
유저 여정 ID (유저 여정 리소스인 경우에만 존재)
유저 여정 이름 (유저 여정 리소스인 경우에만 존재)
유저 여정 노드 ID (유저 여정 리소스인 경우에만 존재)
유저 여정 노드 이름 (유저 여정 리소스인 경우에만 존재)
발송 채널 정보
발송 시도된 메시지 수
발송 실패한 메시지 수
전달 완료된 메시지 수 (채널에서 지원하지 않는 경우 null)
클릭된 메시지 수 (채널에서 지원하지 않는 경우 null)
전환 데이터 배열
Show child attributes
Show child attributes
⌘I
