연락처 SDK 연동 가이드
웹/앱 SDK의 identify()로 회원 정보·수신동의·커스텀 속성·행동 데이터를 주소록(연락처)에 수집합니다.
연락처 데이터 구성
하나의 연락처는 세 층으로 이루어지며, 각각 다른 API 호출로 채워집니다.
| 층 | 담기는 정보 | 채우는 방법 | 세그먼트 조건 |
|---|---|---|---|
| 기본 정보 | 이름·전화·이메일·앱푸시 식별자·수신동의 | POST /identify, /opt-in |
이름/이메일/전화/수신동의 |
| 커스텀 속성 | 등급·생일·포인트 등 내 서비스 고유 항목 | /identify의 customFields |
custom.* |
| 행동 데이터 | 로그인·구매·커스텀 이벤트의 최초/마지막 시각·횟수·누적액 | /session/event, /session/funnel/track |
activity.* |
externalUserId로 식별됩니다.
같은 externalUserId로 다시 호출하면 새 레코드가 아니라 기존 연락처가 갱신됩니다.
인증 & 베이스 URL
연락처 API는 /api/v1/cross-platform/** 경로를 사용하며,
모든 요청에 두 개의 헤더가 반드시 필요합니다.
| 헤더 | 필수 | 설명 |
|---|---|---|
| X-App-ID | 필수 | 연동할 앱의 ID (숫자) |
| X-Mobile-App-API-Key | 필수 | 해당 앱의 API Key |
| Content-Type | 필수 | application/json |
X-App-ID와 X-Mobile-App-API-Key는
둘 다 있어야 하며 서로 매칭되는 쌍이어야 합니다. 하나라도 없거나 쌍이 일치하지 않으면
401을 반환합니다. API Key는 서버 측에만 보관하고 브라우저·앱 클라이언트에 노출하지 마세요.
베이스 URL은 https://fplink.net/api/v1/cross-platform 입니다.
사용자 수집 엔드포인트
SDK는 아래 세 엔드포인트로 회원 정보와 수신동의를 주소록에 upsert합니다.
POST /api/v1/cross-platform/identify
로그인·회원가입·프로필 변경 시 호출합니다. externalUserId 기준으로
없으면 새로 만들고(INSERT), 있으면 전달한 필드만 갱신합니다(보내지 않은 필드는 기존 값 유지).
요청 본문
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| externalUserId | String | 필수 | 내 서비스의 회원 ID (최대 200자) |
| name | String | 이름 (최대 100자) | |
| phone | String | 전화번호 — 서버에서 AES-256 암호화 저장 (최대 50자) | |
| String | 이메일 — 서버에서 AES-256 암호화 저장 (최대 200자) | ||
| pushIdentify | String | 앱푸시 식별자 (핑거푸시 토큰, 최대 200자) | |
| smsOptIn | Boolean | SMS 수신동의 | |
| emailOptIn | Boolean | 이메일 수신동의 | |
| pushOptIn | Boolean | 앱푸시 수신동의 | |
| smsAdOptIn | Boolean | SMS 광고 수신동의 | |
| emailAdOptIn | Boolean | 이메일 광고 수신동의 | |
| pushAdOptIn | Boolean | 앱푸시 광고 수신동의 | |
| nightAdOptIn | Boolean | 야간 광고 수신동의 | |
| alimtalkAdOptIn | Boolean | 알림톡 광고 수신동의 | |
| whatsappOptIn | Boolean | WhatsApp 수신동의 | |
| customFields | Object | 등급·생일 등 임의 속성 — 키 단위 병합, 세그먼트 custom.* 소스 |
요청 예시
curl -X POST https://fplink.net/api/v1/cross-platform/identify \
-H "X-App-ID: 12345" \
-H "X-Mobile-App-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"externalUserId": "u1001",
"name": "홍길동",
"phone": "01012345678",
"email": "gildong@example.com",
"smsOptIn": true,
"emailAdOptIn": true,
"customFields": { "grade": "gold", "birthday": "1990-07-26", "point": 15000 }
}'
응답
{
"success": true,
"action": "created", // "created" | "updated" | "reactivated"
"externalUserId": "u1001"
}
- created — 신규 연락처 생성
- updated — 기존 연락처 갱신
- reactivated — 탈퇴했던 연락처가 재가입으로 되살아남
YYYY-MM-DD
(또는 YYYY-MM-DDTHH:mm:ss) 형식으로 보내야 날짜 조건에서 인식됩니다.
자세한 내용은 세그먼트 가이드를 참고하세요.
- 커스텀 필드 키는 연락처당 기본 50개까지(조직별 조정 가능), 키 이름은 최대 50자입니다.
- 값은 텍스트로 저장됩니다. 숫자·불리언을 보내도 문자열로 저장·반환됩니다(예:
15000→"15000"). 값 길이는 기본 2000자까지(조직별 조정 가능)입니다. - 상한을 넘는 키는 무시되고, 길이를 초과한 값은 잘려서 저장됩니다. 오류로 반환되지 않습니다.
- 가입일 주의:
createdAt은 연락처가 이 플랫폼에 처음 생성된 시각(유입일)입니다. 실시간 SDK 가입이면 실제 가입일과 같지만, 기존 회원 가져오기·지연 식별이면 다릅니다. 고객사 서비스 기준 실제 가입일로 세그먼트하려면signup_date(YYYY-MM-DD)를 커스텀 필드로 명시해 보내세요 — createdAt이 표현하지 못하는 과거 사실이라 중복이 아닙니다. - 반복·금액 행동(구매 등)은
activity.purchase.first/last/count/sum으로 서버가 자동 집계합니다. 마지막 구매 "일"만 커스텀 필드로 추가로 저장하는 중복은 피하세요. 커스텀 필드는 등급·관심사·유입 전 과거 사실처럼 서비스가 정하는 속성에 쓰는 것을 권장합니다.
POST /api/v1/cross-platform/opt-in
마이페이지 등에서 수신동의만 단독으로 변경할 때 호출합니다.
identify()를 먼저 호출하지 않은 사용자는 404를 반환합니다.
요청 본문
externalUserId(필수) + identify와 동일한 수신동의 필드들
(smsOptIn, emailOptIn,
pushOptIn, smsAdOptIn,
emailAdOptIn, pushAdOptIn,
nightAdOptIn, alimtalkAdOptIn,
whatsappOptIn). 전달한 항목만 갱신됩니다.
curl -X POST https://fplink.net/api/v1/cross-platform/opt-in \
-H "X-App-ID: 12345" \
-H "X-Mobile-App-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{ "externalUserId": "u1001", "smsOptIn": false, "emailAdOptIn": true }'
POST /api/v1/cross-platform/withdraw
탈퇴 시 호출합니다. 연락처를 비활성화하고 이름·전화번호·이메일·앱푸시 식별자·커스텀 속성을 즉시 공백 처리하며 수신동의를 모두 해제합니다. 행동 기록도 함께 삭제됩니다.
요청 본문
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| externalUserId | String | 필수 | 탈퇴할 회원 ID |
{
"success": true,
"externalUserId": "u1001",
"withdrawnCount": 1 // 공백 처리된 연락처 수
}
externalUserId로
다시 identify()를 호출하면 재가입(reactivated)으로
처리되며 정보를 다시 보내야 합니다. 발송 이력·누적 통계는 보존됩니다.
관리자가 콘솔에서 차단한 연락처는 재가입해도 되살아나지 않습니다.
대상이 없으면 404를 반환합니다(이미 탈퇴했거나 등록된 적 없는 사용자).
행동 데이터(activity) 수집
로그인·구매·커스텀 이벤트 같은 행동은 세션 API로 기록됩니다. 서버는 세션에 연결된
externalUserId로 연락처를 찾아, 이벤트를 해당 연락처의
activity(최초 시각·마지막 시각·발생 횟수·누적 금액)로 집계합니다.
이 값들이 세그먼트의 activity.* 조건 소스가 됩니다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| POST | /session/event | 커스텀 이벤트 기록 — eventType이 metric 이름이 됨 |
| POST | /session/funnel/track | 퍼널 이벤트 추적 — 로그인·구매·앱설치·앱실행 등 표준 전환 |
/session/event 요청 필드
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| sessionId | String | 필수 | 세션 ID |
| eventType | String | 필수 | 이벤트명 — activity metric 이름으로 사용 (예: wishlist_add) |
| eventData | Object | 이벤트 추가 데이터 | |
| clientTimestamp | String | ISO 8601 UTC | |
| clientTimezone | String | 예: Asia/Seoul |
- 커스텀 이벤트 metric은 조직당 기본 50개까지 생성됩니다. 상한에 도달하면 기존 metric은 계속 누적되지만 새 metric은 만들어지지 않습니다. metric 이름은 최대 50자입니다.
login·purchase·app_open·app_install은 서버 표준 metric으로, 퍼널 추적(/session/funnel/track)에서 자동 기록되며 커스텀 상한과 무관합니다.- 구매 금액 누적(LTV)은 조직 기준통화와 일치할 때만 합산됩니다(다른 통화는 발생 횟수만 기록).
세그먼트 연계
이 API로 수집한 데이터는 콘솔의 세그먼트 조건으로 즉시 활용됩니다.
커스텀 속성은 custom.키로, 행동 데이터는
activity.metric.first|last|count|sum 형태로 참조됩니다.
조건에 맞는 대상자는 매일 자동으로 다시 계산되어 캠페인·자동화 발송 대상으로 쓰입니다.
조건 문법과 활용 예시는 세그먼트 사용자 속성 가이드를 참고하세요.
오류 응답
| 상태 코드 | 상황 | 비고 |
|---|---|---|
| 400 | X-App-ID가 숫자가 아님, 또는 요청 본문 검증 실패 | externalUserId 누락 등 |
| 401 | 인증 헤더 누락 또는 App ID / API Key 쌍 불일치 | 두 헤더 모두 필요 |
| 403 | 필요한 애드온 미구독 | 세션/퍼널 API의 애드온 요구사항 |
| 404 | 대상 연락처 없음 | /opt-in·/withdraw에서 identify 선행 안 됨 |
// 401 — 헤더 누락
{ "error": "X-App-ID 헤더는 필수입니다." }
// 404 — opt-in 선행 identify 없음
{ "success": false, "message": "등록되지 않은 사용자입니다. identify()를 먼저 호출하세요." }