get-user-message-history
curl --request GET \
--url https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history', 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/projects/{projectId}/users/{userId}/message-history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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/projects/{projectId}/users/{userId}/message-history")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"message_history": [
{
"id": "abc123",
"event_name": "send_success",
"channel": "push-notification",
"resource_id": "camp_001",
"sub_resource_id": "var_001",
"resource_type": "campaign",
"created_at": "2026-03-30T12:00:00.000Z",
"updated_at": "2026-03-30T12:00:00.000Z"
},
{
"id": "def456",
"event_name": "push_click",
"channel": "push-notification",
"resource_id": "camp_001",
"sub_resource_id": "var_001",
"resource_type": "campaign",
"created_at": "2026-03-30T12:05:00.000Z",
"updated_at": "2026-03-30T12:05:00.000Z"
}
],
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wMy0zMFQxMjowNTowMC4wMDBaIn0="
},
"error": null
}{
"data": null,
"error": "Invalid project ID"
}{
"data": null,
"error": "Unauthorized: Invalid Authorization Token"
}{
"data": null,
"error": "Internal Server Error: some-error-message"
}내보내기 & 분석
유저 메시지 히스토리 조회
특정 유저의 캠페인 및 유저여정 발송·수신 기록을 cursor 기반 페이지네이션으로 조회합니다.
GET
/
projects
/
{projectId}
/
users
/
{userId}
/
message-history
get-user-message-history
curl --request GET \
--url https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history', 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/projects/{projectId}/users/{userId}/message-history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
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/projects/{projectId}/users/{userId}/message-history")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.notifly.tech/projects/{projectId}/users/{userId}/message-history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"message_history": [
{
"id": "abc123",
"event_name": "send_success",
"channel": "push-notification",
"resource_id": "camp_001",
"sub_resource_id": "var_001",
"resource_type": "campaign",
"created_at": "2026-03-30T12:00:00.000Z",
"updated_at": "2026-03-30T12:00:00.000Z"
},
{
"id": "def456",
"event_name": "push_click",
"channel": "push-notification",
"resource_id": "camp_001",
"sub_resource_id": "var_001",
"resource_type": "campaign",
"created_at": "2026-03-30T12:05:00.000Z",
"updated_at": "2026-03-30T12:05:00.000Z"
}
],
"next_cursor": "eyJjcmVhdGVkX2F0IjoiMjAyNi0wMy0zMFQxMjowNTowMC4wMDBaIn0="
},
"error": null
}{
"data": null,
"error": "Invalid project ID"
}{
"data": null,
"error": "Unauthorized: Invalid Authorization Token"
}{
"data": null,
"error": "Internal Server Error: some-error-message"
}Cursor 기반 페이지네이션이 API는 cursor 기반 페이지네이션을 사용합니다. 응답의
next_cursor 값을 다음 요청의 cursor 파라미터로 전달하여 다음 페이지를 조회합니다. next_cursor가 null이면 마지막 페이지입니다.주요 이벤트명
이 외에도 채널별로 추가 이벤트가 존재할 수 있습니다.
| 이벤트명 | 설명 |
|---|---|
send_success | 발송 성공 |
send_failure | 발송 실패 |
push_click | 푸시 클릭 |
push_delivered | 푸시 도달 |
in_app_message_show | 인앱 메시지 노출 |
in_web_message_show | 인웹 메시지 노출 |
main_button_click | 메인 버튼 클릭 |
close_button_click | 닫기 버튼 클릭 |
failover_text_message_send_success | 대체 문자 발송 성공 |
failover_text_message_send_failure | 대체 문자 발송 실패 |
날짜 필터 사용 시 주의사항
start_date와 end_date를 사용할 경우, timezone 파라미터가 반드시 함께 전달되어야 합니다. 또한 start_date와 end_date는 항상 쌍으로 사용해야 합니다.인증
POST /authenticate로 발급받은 인증 토큰을 Bearer 형식으로 전달합니다.
경로 매개변수
프로젝트 ID (32자 hex string)
Pattern:
^[0-9a-f]{32}$유저의 external_user_id
Minimum string length:
1쿼리 매개변수
페이지 크기 (1~100, 기본값 20)
필수 범위:
1 <= x <= 100이전 응답의 next_cursor 값
채널 필터
사용 가능한 옵션:
push-notification, web-push-notification, email, text-message, kakao-alimtalk, kakao-friendtalk, kakao-brand-message, line, in-app-message, in-web-message, webhook 리소스 유형 (campaign 또는 user_journey)
사용 가능한 옵션:
campaign, user_journey 리소스 ID (사용 시 resource_type 필수)
조회 시작 날짜 (YYYY-MM-DD, inclusive, end_date 및 timezone과 함께 사용)
조회 종료 날짜 (YYYY-MM-DD, inclusive, start_date 및 timezone과 함께 사용)
날짜 해석 기준 timezone (IANA 형식, 예: Asia/Seoul)
