EVENT 엔드포인트 API 레퍼런스
SDK 구현의 대안으로, 서버 간 연동을 통해 Singular의 REST API를 사용하여 인앱 이벤트와 수익을 추적하고 어트리뷰션 분석 및 캠페인 최적화에 활용합니다.
개요
서버 간(S2S) 사용 사례
EVENT 엔드포인트는 어트리뷰션 분석과 캠페인 최적화를 위해 인앱 이벤트와 수익을 추적합니다. 서버 간 연동이 처음이신가요? 핵심 개념과 공통 설정은 S2S 기본 가이드 를 참조하세요.
지원 기능:
- 이벤트 어트리뷰션: 사용자 행동을 마케팅 캠페인과 연결합니다
- 수익 추적: 인앱 구매와 거래를 측정하고 어트리뷰션합니다
- 커스텀 이벤트: 가입부터 레벨 완료까지 모든 사용자 상호작용을 추적합니다
- 이벤트 프로퍼티: 더 깊이 있는 분석을 위해 이벤트에 컨텍스트 데이터를 첨부합니다
하이브리드 사용 사례: 하이브리드 연동에서는 Singular SDK가 필수이며 세션 추적을 관리하므로 SESSION 엔드포인트는 사용하지 않습니다. 서버는 SDK가 제공한 Singular Device ID(SDID)를 사용하여 EVENT V2 엔드포인트로 이벤트를 전송합니다.
필수 요구사항
사전 요구사항:
- 이벤트보다 세션이 먼저: 이벤트를 추적하기 전에 SESSION이 먼저 설정되어야 합니다
- 순차적 순서: 세션 순서가 올바르지 않으면 데이터 불일치와 어트리뷰션 오류가 발생합니다
이벤트 추적 가이드라인
명명 규칙과 데이터 구조에 대한 Singular의 모범 사례에 따라 이벤트 추적을 구현하세요.
이벤트 정의
이벤트 정의하기
S2S 연동을 구현하기 전에, 조직에서 캠페인 성과 분석을 위해 추적하려는 이벤트의 전체 목록을 정의하세요.
이벤트 기획 가이드: 인앱 이벤트 정의하기
이벤트 명명의 영향: Singular로 전달되는 이벤트 이름은 리포트, 익스포트, 포스트백에 이벤트가 표시되는 방식을 그대로 결정합니다.
표준 이벤트 명명
모범 사례:
- 표준 이벤트: 파트너 연동 매핑을 간소화하려면 Singular의 표준 이벤트 명명 규칙 을 사용하세요
- 영어 사용: 서드파티 파트너 및 분석 솔루션과의 호환성을 위해 이벤트 이름은 영어로 전달하세요
- 표준 속성: 이벤트 프로퍼티에는 표준 이벤트 속성 이름 을 사용하세요
문자 제한
길이 제한:
- 이벤트 이름: 최대 32 ASCII 문자(비 ASCII 문자의 경우 UTF-8 변환 시 32바이트)
- 이벤트 속성: 속성 키와 값당 최대 500 ASCII 문자
엔드포인트 선택
EVENT 엔드포인트에는 두 가지 버전이 있습니다. 아래 아코디언에서 각 버전의 엔드포인트 URL과 필수 디바이스 식별자를 확인하세요. 그 밖의 모든 파라미터는 공통이며 아래 필수 파라미터 및 선택 파라미터 에 한 번씩만 문서화되어 있습니다.
2026년 7월 15일부터 V2 필수. 2026년 7월 15일 이후에 생성된 계정은 Event Endpoint V2(SDID 기반)를 사용해야 하며, 신규 계정에서는 V1을 사용할 수 없습니다. 이미 V1으로 연동된 기존 고객은 영향을 받지 않습니다. V2로 마이그레이션하려면 Singular 고객 성공 매니저에게 문의하세요.
Singular SDK가 Singular Device ID(SDID)로 세션을 추적하고 서버가 동일한 SDID를 사용하여 이벤트를 전송하는 하이브리드 연동에는 V2를 사용하세요. V2는 플랫폼별 디바이스 식별자를 사용하지 않습니다.
POST https://s2s.singular.net/api/v2/evt
필수 식별자:
| 파라미터 | 세부 정보 |
|---|---|
sdid
|
플랫폼:
iOS, Android, Web, PC, Xbox, PlayStation, Nintendo, MetaQuest, CTV
|
순수 서버 사이드 연동, 또는 Singular SDK가 SDID를 사용하지 않고 플랫폼별 디바이스 식별자(IDFA, IDFV, AIFA, ASID 등)에 의존하는 하이브리드 연동에는 V1을 사용하세요.
POST https://s2s.singular.net/api/v1/evt
필수 식별자(최소 1개):
| 파라미터 | 세부 정보 |
|---|---|
idfa
|
플랫폼:
iOS
|
idfv
|
플랫폼:
iOS
|
aifa
|
플랫폼:
Android
|
asid
|
플랫폼:
Android
|
amid
|
플랫폼:
Android
|
oaid
|
플랫폼:
Android
|
andi
|
플랫폼:
Android
사용 제한: Google Play 디바이스에서는 사용이 금지되며, 대신 AIFA와 ASID를 사용하세요. 다른 식별자를 전혀 사용할 수 없고 앱이 Google Play를 통해 배포되지 않는 경우에만 전송하세요.
예시:
|
필수 파라미터
모든 EVENT 요청에는 디바이스 식별자 외에 다음 필수 파라미터가 포함되어야 합니다.
파라미터 형식:
모든 파라미터는 POST 메서드를 사용하여 요청 본문에
application/x-www-form-urlencoded
데이터로 전송해야 합니다. 요청에는
Content-Type: application/x-www-form-urlencoded
헤더가 포함되어야 합니다. 파라미터를 JSON 요청 본문으로 전송하지 마세요.
API 인증
| 파라미터 | 세부 정보 |
|---|---|
a
|
유형:
String
중요: Reporting API Key를 사용하지 마세요. 요청이 거부됩니다.
예시:
|
디바이스 파라미터
| 파라미터 | 세부 정보 |
|---|---|
p
|
유형:
String
|
ip
|
유형:
String
|
ve
|
유형:
String
|
ma
|
플랫폼:
iOS, Android
|
mo
|
플랫폼:
iOS, Android
|
lc
|
플랫폼:
iOS, Android
|
bd
|
플랫폼:
iOS, Android
|
애플리케이션 파라미터
| 파라미터 | 세부 정보 |
|---|---|
i
|
유형:
String
|
app_v
|
유형:
String
|
att_authorization_status
|
플랫폼:
iOS
항상 필수:
ATT를 구현하지 않은 경우에도
예시:
|
이벤트 파라미터
| 파라미터 | 세부 정보 |
|---|---|
n
|
유형:
String
|
선택 파라미터
선택 파라미터는 추가 컨텍스트와 기능으로 이벤트 추적을 보강합니다.
타임스탬프 파라미터
| 파라미터 | 세부 정보 |
|---|---|
utime
|
유형:
Integer
|
umilisec
|
유형:
Integer
|
이벤트 속성
파트너 Conversion API 지원:
Singular의 Conversion API 연동을 통해 이러한 이벤트를 광고 네트워크 파트너에게 전달하려면, 표준 선택 이벤트 속성(다음과 같은 해시된 퍼스트 파티 데이터)을 포함하세요:
eventId
및
ehash
). 자세한 내용은
Conversion API 연동을 위한 표준 이벤트 속성
를 참조하세요.
| 파라미터 | 세부 정보 |
|---|---|
e
|
유형:
JSON
|
global_properties
|
유형:
JSON
|
네트워크 파라미터
| 파라미터 | 세부 정보 |
|---|---|
use_ip
|
유형:
Boolean
제한 사항:
예시:
|
country
|
유형:
String
|
ua
|
유형:
String
|
c
|
플랫폼:
iOS, Android
|
cn
|
플랫폼:
iOS, Android
|
데이터 프라이버시
| 파라미터 | 세부 정보 |
|---|---|
data_sharing_options
|
유형:
JSON
|
dnt
|
플랫폼:
iOS, Android
|
dntoff
|
플랫폼:
iOS, Android
|
크로스 디바이스 지원
| 파라미터 | 세부 정보 |
|---|---|
custom_user_id
|
유형:
String
PII 금지: 개인 식별 정보를 전달하지 마세요. 원본 이메일 주소, 전화번호, 이름이 아닌 해시 처리되었거나 익명화된 내부 식별자를 사용하세요.
예시:
|
SKAdNetwork 지원
| 파라미터 | 세부 정보 |
|---|---|
skan_conversion_value
|
플랫폼:
iOS
|
skan_first_call_timestamp
|
플랫폼:
iOS
|
skan_last_call_timestamp
|
플랫폼:
iOS
|
수익 추적
적절한 검증과 통화 처리를 통해 인앱 구매와 수익 이벤트를 추적하세요.
필수 수익 파라미터
기본 수익 추적
직접 수익 검증을 수행하는 경우 수익 이벤트 추적에 필요한 최소 파라미터입니다.
모범 사례: Singular로 이벤트 요청을 보내기 전에 서버 측에서 App Store와 수익 이벤트를 검증하세요. 직접 검증을 수행하는 경우 이 파라미터들만 필요합니다.
| 파라미터 | 세부 정보 |
|---|---|
is_revenue_event
|
유형:
Boolean
|
amt
|
유형:
Number
|
cur
|
유형:
String
|
참고:
amt
파라미터를 전송하면
is_revenue_event
값과 관계없이 해당 이벤트가 수익 이벤트로 처리되며, 여기에는
is_revenue_event=false
도 포함됩니다. 이벤트를 수익 이벤트로 처리하지 않으려면
amt
파라미터를 생략하세요. 금액이 없는 수익 이벤트를 표시하려면 다음을 전송하세요:
is_revenue_event=true
.
수익 검증 파라미터
Singular 검증 수익
Singular가 App Store와 서버 측 수익 검증을 수행하도록 하는 선택 파라미터입니다.
검증 요구사항:
- App Store와의 수익 검증을 Singular에 의존하는 경우 필수입니다
- 구매 영수증과 서명 값의 구문이 올바른지 확인하세요
-
형식이 올바르지 않으면 Singular가 수익을 차단하고
__iapinvalid__이벤트를 생성합니다
| 파라미터 | 세부 정보 |
|---|---|
purchase_receipt
|
플랫폼:
iOS, Android
|
receipt_signature
|
플랫폼:
Android
|
purchase_product_id
|
유형:
String
|
purchase_transaction_id
|
유형:
String
|
광고 수익 추적
고정된 이벤트 이름과 광고 수익화 속성을 담은 표준 EVENT를 전송하여 미디에이션 플랫폼(예: AdMob, AppLovin MAX, ironSource)의 노출 단위 광고 수익화 수익을 추적합니다. 광고 수익은 위에 문서화된 것과 동일한 EVENT 엔드포인트를 사용합니다.
미디에이션 플랫폼 데이터: 필요한 광고 수익 속성은 미디에이션 플랫폼 SDK에서 직접 수집하세요. 각 미디에이션 플랫폼이 제공하는 속성은 광고 수익 SDK 가이드 를 참조하세요.
광고 수익화 수익
표준 필수 파라미터(인증, 디바이스, 애플리케이션) 외에, 광고 수익 이벤트에는 다음이 필요합니다.
| 파라미터 | 세부 정보 |
|---|---|
n
|
유형:
String
|
is_admon_revenue
|
유형:
Boolean
|
is_revenue_event
|
유형:
Boolean
|
amt
|
유형:
Number
|
cur
|
유형:
String
|
e
|
유형:
JSON
선택 속성:
JSON 구조:
URL 인코딩 예시:
참고: 값이 없는 속성은 생략하세요. |
요청 예시
샘플 코드는 여러 프로그래밍 언어에서의 EVENT 엔드포인트 연동을 보여줍니다.
예시 관련 고지:
코드 샘플에는 필요한 모든 파라미터가 포함되어 있지 않을 수 있습니다. 프로덕션에 구현하기 전에 전체 파라미터 목록을 확인하세요. 개발/테스트에는 고유한
i
(앱 식별자)를 사용하세요.
Python 예시
import requests
url = 'https://s2s.singular.net/api/v1/evt'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
params = {
'a': 'sdk_key_here',
'p': 'Android',
'i': 'com.singular.app',
'ip': '10.1.2.3',
've': '9.2',
'ma': 'samsung',
'mo': 'SM-G935F',
'lc': 'en_US',
'bd': 'Build/13D15',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'asid': 'edee92a2-7b2f-45f4-a509-840f170fc6d9',
'n': 'sng_add_to_cart'
}
response = requests.post(url, data=params, headers=headers)
print(response.json())
cURL 예시
curl -X POST "https://s2s.singular.net/api/v1/evt" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "a=sdk_key_here" \
--data-urlencode "p=Android" \
--data-urlencode "i=com.singular.app" \
--data-urlencode "ip=10.1.2.3" \
--data-urlencode "ve=9.2" \
--data-urlencode "ma=samsung" \
--data-urlencode "mo=SM-G935F" \
--data-urlencode "lc=en_US" \
--data-urlencode "bd=Build/13D15" \
--data-urlencode "aifa=8ecd7512-2864-440c-93f3-a3cabe62525b" \
--data-urlencode "asid=edee92a2-7b2f-45f4-a509-840f170fc6d9" \
--data-urlencode "n=sng_add_to_cart"
HTTP 예시
POST /api/v1/evt HTTP/1.1
Host: s2s.singular.net
Content-Type: application/x-www-form-urlencoded
Accept: application/json
a=sdk_key_here&p=Android&i=com.singular.app&ip=10.1.2.3&ve=9.2&ma=samsung&mo=SM-G935F&lc=en_US&bd=Build%2F13D15&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&asid=edee92a2-7b2f-45f4-a509-840f170fc6d9&n=sng_add_to_cart
Java 예시
// Endpoint
String endpoint = "https://s2s.singular.net/api/v1/evt";
// Parameters
Map<String, String> params = new HashMap<>();
params.put("a", "sdk_key_here");
params.put("p", "Android");
params.put("i", "com.singular.app");
params.put("ip", "10.1.2.3");
params.put("ve", "9.2");
params.put("ma", "samsung");
params.put("mo", "SM-G935F");
params.put("lc", "en_US");
params.put("bd", "Build/13D15");
params.put("aifa", "8ecd7512-2864-440c-93f3-a3cabe62525b");
params.put("asid", "edee92a2-7b2f-45f4-a509-840f170fc6d9");
params.put("n", "sng_add_to_cart");
// Build form-urlencoded body
StringBuilder form = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (form.length() > 0) form.append('&');
form.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append('=')
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
byte[] body = form.toString().getBytes(StandardCharsets.UTF_8);
// Create connection
URL url = new URL(endpoint);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Accept", "application/json");
// Write body
try (OutputStream os = conn.getOutputStream()) {
os.write(body);
}
// Get response
int responseCode = conn.getResponseCode();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("HTTP Status Code: " + responseCode);
System.out.println("Response: " + response.toString());
conn.disconnect();
응답 코드 및 오류
EVENT 엔드포인트는 요청의 성공 또는 실패를 나타내는 HTTP 상태 코드와 JSON 응답을 반환합니다.
전체 오류 문서: S2S 응답 코드 및 오류 처리
테스트 및 검증
프로덕션 배포 전에 Singular SDK Console을 사용하여 실시간 데이터 검증으로 S2S 이벤트 연동을 확인하세요.
테스트 절차
엔드 투 엔드 검증
- 테스트 디바이스 등록: 디바이스 광고 ID를 확인하여 다음에 추가하세요: Singular SDK Console
- 콘솔 로깅 활성화: 테스트 데이터를 수집하려면 SDK Console에 디바이스 식별자를 추가하세요
-
개발용 App ID 사용:
테스트 데이터와 프로덕션 데이터를 분리하려면 앱 식별자를 개발 버전(예:
com.singular.app.dev)으로 재정의하세요 - 빌드 및 실행: 종료된 상태에서 앱을 빌드하거나 실행하세요
- 클라이언트 데이터 검증: 앱이 필요한 모든 Singular 데이터 포인트를 서버로 전송하는지 확인하세요
-
세션 확인:
서버가 필요한 모든 파라미터와 함께 SESSION 요청을 다음으로 전송하는지 확인하세요:
https://s2s.singular.net/api/v1/launch - SDK Console 확인(세션): 몇 초 이내에 SESSION 이벤트가 SDK Console에 표시되어야 합니다
이벤트 테스트
- 이벤트 트리거: 앱에서 이벤트를 트리거하세요
- 이벤트 데이터 검증: 필요한 모든 Singular 데이터 포인트와 함께 이벤트가 서버로 전송되었는지 확인하세요
-
서버 요청 확인:
서버가 필요한 모든 파라미터와 함께 EVENT 요청을 엔드포인트(V2
https://s2s.singular.net/api/v2/evt또는 V1https://s2s.singular.net/api/v1/evt)로 전송하는지 확인하세요. - SDK Console 확인(이벤트): 몇 초 이내에 EVENT가 SDK Console에 표시되어야 합니다
- 테스트 반복: 전송된 모든 이벤트가 예상 값을 갖는지 검증하세요
필수 확인 사항:
- EVENT를 수신하기 전에 앱 실행/포그라운드 전환 시 SESSION 이벤트가 발생하는지 확인하세요
- EVENT의 필수 데이터 포인트가 SESSION의 데이터 포인트와 일치하는지 확인하세요
성공 지표: SDK Console에 이벤트가 표시되면 엔드 투 엔드 이벤트 연동 테스트를 성공적으로 완료한 것입니다!
추가 리소스
테스트 문서
종합 테스트 가이드: S2S 연동 테스트 가이드