SESSION 엔드포인트 API 레퍼런스
SDK 구현의 대안으로 서버 간(server-to-server) 연동을 사용하여 Singular의 REST API를 통해 사용자 세션을 추적하고 앱 설치, 리인게이지먼트, 리텐션 지표에 대한 어트리뷰션을 활성화하세요.
개요
서버 간(Server-to-Server) 사용 사례
SESSION 엔드포인트는 사용자가 앱을 열 때 Singular에 알려 설치 및 리인게이지먼트 어트리뷰션과 리텐션 지표를 구동합니다. Server-to-Server가 처음이신가요? S2S 기본 가이드 에서 핵심 개념과 공통 설정을 확인하세요.
지원 기능:
- 설치 어트리뷰션: 마케팅 캠페인에 대한 퍼스트 터치 어트리뷰션
- 리인게이지먼트 어트리뷰션: 복귀 사용자를 위한 멀티 터치 어트리뷰션
- 리텐션 지표: 세션 기반 인게이지먼트 추적
세션 관리
SESSION 엔드포인트는 앱 오픈 이벤트를 Singular에 알려 어트리뷰션 및 추적을 위한 사용자 세션을 초기화합니다.
세션을 전송해야 하는 시점
세션 트리거
다음과 같은 앱 라이프사이클 이벤트에 대해 SESSION 요청을 전송하세요:
- 신규 설치: 설치 후 최초 앱 실행
- 종료 상태에서의 실행: 완전히 닫힌 상태에서 앱이 열리는 경우
- 백그라운드에서 포그라운드로 전환: 타임아웃 기간(권장: 60초) 이후 앱이 포그라운드로 복귀하는 경우
세션 타임아웃 로직
짧은 앱 백그라운드 전환 동안 과도한 SESSION 요청이 발생하지 않도록 세션 타임아웃을 구현하세요.
권장 구현:
- 타임아웃 시간: 60초(1분)
- 포그라운드 < 타임아웃: 타임아웃 기간 이내에 앱이 포그라운드로 복귀하면 SESSION을 전송하지 마세요
- 포그라운드 > 타임아웃: 타임아웃 기간을 초과하여 앱이 백그라운드에 머물렀다면 SESSION을 전송하세요
- 앱 라이프사이클 추적: 앱 라이프사이클 이벤트와 타이머를 사용하여 세션 상태를 관리하세요
딥링크 지원:
딥링크, Universal Link, App Link를 통해
앱이 열리는 경우
openuri
파라미터가 채워져 있다면 타임아웃 상태와 관계없이 항상 SESSION을 전송하세요.
어트리뷰션 처리
세션 기반 어트리뷰션
Singular는 SESSION 요청을 처리하여 어트리뷰션 유형을 판별하고 적절한 워크플로우를 트리거합니다.
| 세션 유형 | Singular 처리 | 어트리뷰션 결과 |
|---|---|---|
| 첫 세션(신규 설치) | 설치 어트리뷰션 프로세스 트리거 | 설치를 마케팅 캠페인에 어트리뷰션 |
| 리인게이지먼트 조건 충족 | 리인게이지먼트 어트리뷰션 프로세스 트리거 | 사용자 복귀를 캠페인 또는 딥링크에 어트리뷰션 |
| 일반 세션 | 리텐션 추적을 위해 세션 기록 | 사용자 활동 및 인게이지먼트 지표에 반영 |
자세히 알아보기: 리인게이지먼트 어트리뷰션 FAQ
이벤트 순서 요구사항
세션과 이벤트의 타이밍은 어트리뷰션 정확도와 데이터 품질에 직접적인 영향을 미칩니다.
필수 순서 규칙:
- 이벤트에 앞선 세션: 해당 세션의 이벤트가 전송되기 전에 단일 SESSION이 먼저 수신되어야 합니다
- 실시간 이벤트 전송: 인앱 이벤트는 해당 세션 이후 실시간으로 전송되어야 합니다
- 순차 처리: 잘못된 세션 순서는 데이터 불일치와 어트리뷰션 오류를 초래합니다
API 엔드포인트 명세
SESSION 엔드포인트는 파라미터를
application/x-www-form-urlencoded
형식으로 전송하는 POST 요청을 받습니다.
엔드포인트
Base URL 및 Method
POST https://s2s.singular.net/api/v1/launch
필수 헤더:
Content-Type: application/x-www-form-urlencoded
요청 형식:
POST /api/v1/launch HTTP/1.1
Host: s2s.singular.net
Content-Type: application/x-www-form-urlencoded
param1=value1¶m2=value2
필수 파라미터
모든 SESSION 요청에는 올바른 값과 형식을 갖춘 다음 필수 파라미터가 포함되어야 합니다.
API 인증
SDK Key
| 파라미터 | 세부 정보 |
|---|---|
a
|
유형:
String
중요: Reporting API Key를 사용하지 마세요. 요청이 거부됩니다.
예시:
|
디바이스 식별자
플랫폼별 식별자
| 파라미터 | 세부 정보 |
|---|---|
idfa
|
플랫폼:
iOS
|
idfv
|
플랫폼:
iOS
|
aifa
|
플랫폼:
Android
|
asid
|
플랫폼:
Android
|
amid
|
플랫폼:
Android
|
oaid
|
플랫폼:
Android
|
andi
|
플랫폼:
Android
사용 제한: Google Play 디바이스에서는 금지됩니다—대신 AIFA와 ASID를 사용하세요. 다른 식별자를 사용할 수 없고 앱이 Google Play를 통해 배포되지 않는 경우에만 전송하세요.
예시:
|
sdid
|
플랫폼:
iOS, Android, PC, Xbox, PlayStation, Nintendo, MetaQuest, CTV
|
디바이스 파라미터
디바이스 정보
| 파라미터 | 세부 정보 |
|---|---|
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가 구현되지 않은 경우에도
예시:
|
| 파라미터 | 세부 정보 |
|---|---|
install
|
유형:
Boolean
|
install_time
|
플랫폼:
iOS, Android
이것은 디바이스 설치 시간이며 Singular의 어트리뷰션 설치
시간이 아닙니다. 어트리뷰션은 첫 세션(
iOS와 Android에서 이 값을 얻는 방법은 디바이스 데이터 조회 가이드 를 참조하세요. |
update_time
|
플랫폼:
iOS, Android
iOS와 Android에서 이 값을 얻는 방법은 디바이스 데이터 조회 가이드 를 참조하세요. |
부정행위 방지 파라미터
설치 소스 검증
| 파라미터 | 세부 정보 |
|---|---|
install_source
|
플랫폼:
Android, PC
|
install_receipt
|
플랫폼:
iOS
|
딥링크 파라미터
딥링크 지원
| 파라미터 | 세부 정보 |
|---|---|
openuri
|
플랫폼:
iOS, Android
|
ddl_enabled
|
플랫폼:
iOS, Android
|
singular_link_resolve_required
|
플랫폼:
iOS, Android
|
고급 어트리뷰션 파라미터
플랫폼 어트리뷰션 향상
| 파라미터 | 세부 정보 |
|---|---|
install_ref
Native PC (Google Play Games)
|
플랫폼:
Android (Google Play)
|
meta_ref
|
플랫폼:
Android (Google Play)
2025년 6월 18일부터: Meta Advanced Mobile Measurement (AMM) 이 Meta Install Referrer 구현의 필요성을 없앱니다. AMM이 활성화된 경우 권장하지 않습니다.
세분화된 사용자 수준 어트리뷰션 데이터를 위한 JSON URL 인코딩된
Meta Install Referrer입니다.
|
attribution_token
|
플랫폼:
iOS
|
선택 파라미터
선택 파라미터는 추적 기능을 강화하고 고급 기능을 지원합니다.
타임스탬프 파라미터
| 파라미터 | 세부 정보 |
|---|---|
utime
|
유형:
Integer
|
umilisec
|
유형:
Integer
|
네트워크 & 위치 파라미터
| 파라미터 | 세부 정보 |
|---|---|
use_ip
|
유형:
Boolean
제한사항:
예시:
|
country
|
유형:
String
|
ua
|
유형:
String
|
c
|
플랫폼:
iOS, Android
|
cn
|
플랫폼:
iOS, Android
|
커스텀 속성
| 파라미터 | 세부 정보 |
|---|---|
global_properties
|
유형:
JSON
|
앱 삭제 추적 지원
| 파라미터 | 세부 정보 |
|---|---|
apns_token
|
플랫폼:
iOS
|
fcm
|
플랫폼:
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
|
Google Ads ICM 지원 (Beta)
| 파라미터 | 세부 정보 |
|---|---|
odm_info
|
플랫폼:
iOS
|
odm_error
|
플랫폼:
iOS
|
요청 예시
샘플 코드는 여러 프로그래밍 언어에 걸친 SESSION 엔드포인트 연동을 보여줍니다.
예시 관련 주의:
코드 샘플에 모든 필수 파라미터가
포함되지 않을 수 있습니다. 프로덕션 구현 전에 전체 파라미터 목록을
검증하세요. 개발/테스트에는 고유한
i
(앱 식별자)를
사용하세요.
Python 예시
import requests
url = 'https://s2s.singular.net/api/v1/launch'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
data = {
'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',
'aifa': '8ecd7512-2864-440c-93f3-a3cabe62525b',
'asid': 'edee92a2-7b2f-45f4-a509-840f170fc6d9',
'install': 'true',
'n': 'MyCoolAppName',
'bd': 'Build/13D15',
'app_v': '1.2.3',
'openuri': 'myapp://home/page?queryparam1=value1',
'ddl_enabled': 'true',
'install_source': 'com.android.vending',
'install_time': 1510040127,
'update_time': 1510090877
}
response = requests.post(url, data=data, headers=headers)
print(response.json())
cURL 예시
curl -X POST "https://s2s.singular.net/api/v1/launch" \
-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 "aifa=8ecd7512-2864-440c-93f3-a3cabe62525b" \
--data-urlencode "asid=edee92a2-7b2f-45f4-a509-840f170fc6d9" \
--data-urlencode "install=true" \
--data-urlencode "n=MyCoolAppName" \
--data-urlencode "bd=Build/13D15" \
--data-urlencode "app_v=1.2.3" \
--data-urlencode "openuri=myapp://home/page?queryparam1=value1" \
--data-urlencode "ddl_enabled=true" \
--data-urlencode "install_source=com.android.vending" \
--data-urlencode "install_time=1510040127" \
--data-urlencode "update_time=1510090877"
HTTP 예시
POST /api/v1/launch 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&aifa=8ecd7512-2864-440c-93f3-a3cabe62525b&asid=edee92a2-7b2f-45f4-a509-840f170fc6d9&install=true&n=MyCoolAppName&bd=Build%2F13D15&app_v=1.2.3&openuri=myapp%3A%2F%2Fhome%2Fpage%3Fqueryparam1%3Dvalue1&ddl_enabled=true&install_source=com.android.vending&install_time=1510040127&update_time=1510090877
Java 예시
// Endpoint
String endpoint = "https://s2s.singular.net/api/v1/launch";
// 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("aifa", "8ecd7512-2864-440c-93f3-a3cabe62525b");
params.put("asid", "edee92a2-7b2f-45f4-a509-840f170fc6d9");
params.put("install", "true");
params.put("n", "MyCoolAppName");
params.put("bd", "Build/13D15");
params.put("app_v", "1.2.3");
params.put("openuri", "myapp://home/page?queryparam1=value1");
params.put("ddl_enabled", "true");
params.put("install_source", "com.android.vending");
params.put("install_time", "1510040127");
params.put("update_time", "1510090877");
// 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();
응답 코드 & 오류
SESSION 엔드포인트는 요청 성공 또는 실패를 나타내는 HTTP 상태 코드와 JSON 응답을 반환합니다.
전체 오류 문서: S2S 응답 코드 & 오류 처리
테스트 & 검증
실시간 데이터 검증을 위해 Singular SDK Console을 사용하여 프로덕션 배포 전에 S2S 연동을 확인하세요.
테스트 절차
엔드투엔드 검증
- 테스트 디바이스 등록: 디바이스 광고 ID를 확보하여 Singular SDK Console 에 추가하세요
- Console 로깅 활성화: 테스트 데이터를 캡처하기 위해 SDK Console에 디바이스 식별자를 추가하세요
-
개발용 App ID 사용:
테스트 데이터를 프로덕션 데이터와
분리하기 위해 앱 식별자를 개발 버전(예:
com.singular.app.dev)으로 재정의하세요 - 앱 실행: 종료 상태에서 앱을 열어 세션을 트리거하세요
- 클라이언트 데이터 검증: 앱이 필요한 모든 Singular 데이터 포인트를 서버로 전송하는지 확인하세요
-
서버 요청 확인:
서버가 모든 필수 파라미터와 함께
https://s2s.singular.net/api/v1/launch로 SESSION 요청을 전송하는지 확인하세요 - SDK Console 확인: 몇 초 이내에 SESSION 이벤트가 SDK Console에 나타나야 합니다
- 테스트 반복: 모든 앱 진입 및 포그라운드 작동 시 SESSION이 트리거되는지 검증하세요
중요 검증: EVENT 요청보다 먼저 앱 오픈/포그라운드 시 SESSION 이벤트가 발생하는지 확인하세요. 잘못된 순서는 어트리뷰션 오류를 유발합니다.
성공 지표: SESSION이 SDK Console에 나타나면 엔드투엔드 연동 테스트를 성공적으로 완료한 것입니다!
추가 리소스
테스트 문서
종합 테스트 가이드: S2S 연동 테스트 가이드