API

JavaScript SDK 가이드

작성일 2026.03.24 | 수정일 2026.04.14

1. 설치SOLAPI CRM SDK는 CDN과 NPM 두 가지 방식으로 설치할 수 있습니다. 번들 크기는 gzip 압축 시 약 2.3KB로 매우 가볍습니다.

CDN 방식 (권장)``html

SolapiCRM.init({
trackingKey: 'tk_live_xxxxxxxxxxxxxxxx',
entityId: 'CRMRC1_contacts',
autoPageView: true
});

<h3>NPM 방식npmyarnpnpm
bash npm install @solapi/crm-browser
`
yarn add @solapi/crm-browser
pnpm add @solapi/crm-browser
import SolapiCRM from '@solapi/crm-browser';

SolapiCRM.init({
trackingKey: 'tk_live_xxxxxxxxxxxxxxxx',
entityId: 'CRMRC1_contacts',
autoPageView: true
});


2. 초기화 — init(config)SDK를 사용하려면 먼저 init() 메서드로 초기화해야 합니다.


설정 옵션`json


{
"trackingKey": {
"type": "string",
"default": "(필수)",
"description": "추적 키. 형식: tk_live_xxx 또는 tk_test_xxx"
},
"entityId": {
"type": "string",
"default": "(선택)",
"description": "기본 개체 ID"
},
"endpoint": {
"type": "string",
"default": "/api/crm/v1/track",
"description": "API 엔드포인트 URL"
},
"autoPageView": {
"type": "boolean",
"default": "false",
"description": "페이지뷰 자동 추적 활성화"
},
"batchSize": {
"type": "number",
"default": "10",
"description": "한 번에 전송할 이벤트 수"
},
"flushInterval": {
"type": "number",
"default": "10000",
"description": "이벤트 전송 주기 (밀리초)"
},
"maxQueueSize": {
"type": "number",
"default": "100",
"description": "큐에 보관할 최대 이벤트 수"
},
"debug": {
"type": "boolean",
"default": "false",
"description": "디버그 로그 활성화"
}
}

<h3>전체 설정 예시
javascript SolapiCRM.init({ // 필수: 추적 키 trackingKey: 'tk_live_abc123xyz',

// 권장: 기본 개체 ID
entityId: 'CRMRC1_contacts',

// 선택: 페이지뷰 자동 추적
autoPageView: true,

// 선택: 배치 설정
batchSize: 20,
flushInterval: 5000,
maxQueueSize: 200,

// 선택: 디버그 모드 (개발 환경에서만)
debug: process.env.NODE_ENV === 'development'
});

`프로덕션 환경에서는 debug: false로 설정하고, batchSizeflushInterval을 조정하여 네트워크 트래픽을 최적화하세요.

3. 이벤트 추적 — track(eventType, properties?, options?)사용자 행동을 추적하여 CRM 레코드에 연결합니다. 이벤트는 큐에 저장되었다가 배치로 전송됩니다.

파라미터`json

{ "eventType": { "type": "string", "description": "이벤트 타입 (예: PURCHASE, SIGNUP, CLICK)" }, "properties": { "type": "object", "description": "이벤트 속성" }, "options.category": { "type": "string", "description": "이벤트 카테고리" }, "options.label": { "type": "string", "description": "이벤트 레이블" }, "options.value": { "type": "number", "description": "이벤트 값" }, "options.recordId": { "type": "string", "description": "특정 레코드 ID" } }
<h3>기본 이벤트 추적
javascript // 단순 이벤트 SolapiCRM.track('SIGNUP');

// 버튼 클릭 이벤트
document.getElementById('cta-button').addEventListener('click', () => {
SolapiCRM.track('BUTTON_CLICK', {
buttonId: 'cta-button',
buttonText: '무료로 시작하기',
page: window.location.pathname
});
});

<h3>속성과 함께 추적
javascript // 구매 이벤트 with 상세 속성 SolapiCRM.track('PURCHASE', { productId: 'PROD_123', productName: '나이키 에어맥스', category: '신발', quantity: 1, price: 159000, currency: 'KRW', discount: 10000 }, { category: 'ecommerce', label: 'summer_sale_2026', value: 149000 });
<h3>특정 레코드에 연결
javascript SolapiCRM.track('PREMIUM_UPGRADE', { plan: 'Enterprise', billingCycle: 'annual', amount: 2400000 }, { recordId: 'CRMRC1_user_xyz123', category: 'subscription', value: 2400000 });
<h3>배치 처리 동작이벤트는 다음 조건 중 하나가 충족될 때 서버로 전송됩니다:</h3>
  • 큐 크기: batchSize에 도달하면 자동 전송 (기본값: 10개)
  • 시간 간격: flushInterval 시간이 지나면 전송 (기본값: 10초)
  • 탭 닫기: 브라우저 탭이 닫히거나 페이지를 떠날 때 visibilitychange 이벤트로 자동 전송
  • 재시도: 네트워크 오류 시 최대 3회까지 재시도 (지수 백오프)
  • 큐 오버플로: maxQueueSize를 초과하면 가장 오래된 이벤트부터 삭제
이벤트가 큐에 저장되므로 즉시 서버에 전송되지 않습니다. 실시간 처리가 필요한 경우 SolapiCRM.flush()를 호출하여 강제로 전송하세요.

<h2>4. 페이지뷰 추적 — trackPageView()### 수동 페이지뷰 추적

javascript
// 페이지가 로드될 때
SolapiCRM.trackPageView();

// React Router 예시
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function App() {
const location = useLocation();

useEffect(() => {
SolapiCRM.trackPageView();
}, [location]);

return ...;
}

<h3>자동 페이지뷰 추적 (권장)autoPageView: true로 초기화하면 SDK가 자동으로 페이지뷰를 추적합니다. SPA 프레임워크(React, Vue, Angular)에서도 별도 코드 없이 모든 라우팅이 자동 추적됩니다.</h3>
자동 감지 이벤트:
  • history.pushState: React Router, Vue Router 등의 라우팅
  • history.replaceState: URL 변경 없이 상태만 변경하는 경우
  • popstate: 브라우저 뒤로 가기/앞으로 가기
<h3>자동 수집 속성
json { "url": { "description": "전체 URL", "example": "https://example.com/products" }, "path": { "description": "경로", "example": "/products" }, "title": { "description": "페이지 제목", "example": "Products - MyShop" }, "referrer": { "description": "이전 페이지", "example": "https://google.com" } }
<h2>5. 전환 추적 — 표준 이벤트 프리셋자주 사용되는 이벤트를 표준화된 메서드로 간편하게 추적할 수 있습니다. 프리셋 메서드는 내부적으로 track()을 호출하며, 적절한 카테고리·레이블·값이 자동 설정됩니다.</h2>
<h3>일반 전환 이벤트
javascript // 회원가입 추적 (SIGN_UP) SolapiCRM.trackSignUp({ method: 'email' // 필수: 가입 방식 });

// 로그인 추적 (LOGIN)
SolapiCRM.trackLogin({
method: 'kakao' // 필수: 로그인 방식
});

// 폼 제출 추적 (FORM_SUBMIT)
SolapiCRM.trackFormSubmit({
formId: 'contact-form', // 필수: 폼 ID
formName: '문의하기' // 선택: 폼 이름 (레이블로 사용)
});

<h3>이커머스 전환 이벤트
javascript // 상품 조회 (PRODUCT_VIEW) SolapiCRM.trackProductView({ productId: 'PROD_001', // 필수 name: '프리미엄 요금제', // 필수 category: 'plans', // 선택 price: 79000, // 선택 (value로 사용) currency: 'KRW' // 선택 });

// 장바구니 추가 (CART_ADD)
SolapiCRM.trackAddToCart({
productId: 'PROD_001', // 필수
name: '프리미엄 요금제', // 필수
quantity: 1, // 선택 (기본: 1)
price: 79000 // 선택 (value = price × quantity)
});

// 결제 시작 (CHECKOUT_START)
SolapiCRM.trackCheckoutStart({
totalAmount: 79000, // 필수 (value로 사용)
itemCount: 1, // 필수
cartId: 'CART_001', // 선택
currency: 'KRW' // 선택
});

// 구매 완료 (PURCHASE)
SolapiCRM.trackPurchase({
orderId: 'ORD_001', // 필수
totalAmount: 79000, // 필수 (value로 사용)
items: [{ // 선택
productId: 'PROD_001',
name: '프리미엄 요금제',
quantity: 1,
price: 79000
}],
currency: 'KRW' // 선택
});

// 환불 (REFUND)
SolapiCRM.trackRefund({
orderId: 'ORD_001', // 필수
refundAmount: 79000 // 필수 (value로 사용)
});

<h3>퍼널 분석 예시프리셋 이벤트를 조합하여 전환 퍼널을 구성할 수 있습니다:</h3>
json { "구매 퍼널": { "description": "상품 조회부터 구매까지의 전환 경로", "flow": "PAGE_VIEW → PRODUCT_VIEW → CART_ADD → CHECKOUT_START → PURCHASE" }, "가입 퍼널": { "description": "첫 방문부터 로그인까지", "flow": "PAGE_VIEW → SIGN_UP → LOGIN" }, "폼 퍼널": { "description": "페이지 방문 후 폼 제출", "flow": "PAGE_VIEW → FORM_SUBMIT" }, "커스텀 퍼널": { "description": "프리셋 + track() 조합", "flow": "SIGN_UP → (커스텀) → (커스텀)" } }

`프리셋 메서드와 track()을 자유롭게 조합하여 사용할 수 있습니다. 대시보드의 "이벤트 퍼널" 위젯에서 전환율을 시각화할 수 있습니다.

6. 사용자 식별 — identify(recordId, traits?)로그인한 사용자를 CRM 레코드에 연결합니다. 익명 사용자의 이벤트를 알려진 레코드로 병합하는 핵심 기능입니다.

기본 사용법`javascript

// 로그인 시 — 레코드 ID만 전달 SolapiCRM.identify('CRMRC1_user_xyz123');

// 이후 이벤트는 자동으로 이 레코드에 연결됨
SolapiCRM.track('VIEW_DASHBOARD');

<h3>속성과 함께 식별
javascript SolapiCRM.identify('CRMRC1_user_xyz123', { name: '홍길동', email: 'hong@example.com', phone: '01012345678', plan: 'premium', lastLogin: new Date().toISOString() });
<h3>익명 사용자 → 알려진 사용자 전환 흐름- 첫 방문 (익명 상태): SDK가 자동으로 익명 ID를 생성합니다 (anon_1234567890abcdef)</h3>
  • 익명 이벤트 수집: 로그인 전 이벤트는 익명 ID로 추적됩니다
  • 사용자 로그인: identify()를 호출하여 레코드 ID와 연결합니다
  • 서버 측 이벤트 병합: 서버가 자동으로 익명 ID의 모든 이벤트를 알려진 레코드로 병합합니다
  • 이후 이벤트: 모든 이벤트가 알려진 레코드에 직접 연결됩니다
익명 ID는 로컬스토리지에 저장되어 브라우저를 닫아도 유지됩니다. 사용자가 로그인하지 않아도 여러 세션에 걸쳐 행동을 추적할 수 있습니다.

<h2>7. 레코드 생성 — createRecord(data)클라이언트에서 직접 새로운 CRM 레코드를 생성할 수 있습니다.</h2>
<h3>파라미터

json
{
"entityId": {
"type": "string",
"description": "개체 ID (선택, 없으면 init()의 기본값 사용)"
},
"name": {
"type": "string",
"description": "레코드 이름 (필수)"
},
"data": {
"type": "object",
"description": "레코드 속성 (선택)"
},
"tags": {
"type": "string[]",
"description": "태그 목록 (선택)"
}
}

`

// 회원가입 폼 제출 시
async function handleSignup(formData) {
try {
const record = await SolapiCRM.createRecord({
entityId: 'CRMRC1_contacts',
name: formData.name,
data: {
email: formData.email,
phone: formData.phone,
company: formData.company,
source: 'website_signup'
},
tags: ['new_user', 'trial']
});

console.log('Created record:', record.recordId);
SolapiCRM.identify(record.recordId);
} catch (error) {
console.error('Failed to create record:', error);
}
}

레코드 생성 기능을 사용하려면 추적 키에 createRecords 권한이 활성화되어 있어야 합니다.

8. 슈퍼 프로퍼티 — register() / registerOnce() / unregister()슈퍼 프로퍼티는 모든 track() 호출에 자동으로 포함되는 전역 속성입니다.

register(properties) — 전역 속성 등록`javascript

SolapiCRM.register({ plan: 'premium', region: 'ko-KR', appVersion: '2.1.0' });

// 이후 모든 track()에 자동 포함됨
SolapiCRM.track('VIEW_PAGE');
// → properties: { plan: 'premium', region: 'ko-KR', appVersion: '2.1.0' }

<h3>registerOnce(properties) — 한 번만 등록이미 존재하는 속성은 덮어쓰지 않습니다. 첫 방문 시점의 정보를 보존하는 데 유용합니다.</h3>
javascript SolapiCRM.registerOnce({ initialLandingPage: window.location.href, initialReferrer: document.referrer, firstVisit: new Date().toISOString() });
<h3>unregister(propertyName) — 속성 제거
javascript SolapiCRM.unregister('plan');
<h2>9. 프라이버시 제어GDPR, CCPA 등의 개인정보 보호 규정을 준수하기 위한 추적 거부 기능을 제공합니다.</h2>
javascript // 추적 거부 SolapiCRM.optOutTracking();

// 추적 허용 (다시 활성화)
SolapiCRM.optInTracking();

// 추적 거부 상태 확인
if (SolapiCRM.hasOptedOut()) {
console.log('사용자가 추적을 거부했습니다.');
}

`EU 지역 사용자에게는 추적 시작 전에 명시적인 동의를 받아야 합니다. 기본적으로 optOutTracking() 상태로 시작하고, 사용자가 동의한 후 optInTracking()을 호출하세요.

10. 세션 관리### reset() — 세션 초기화새로운 익명 ID를 생성하고 모든 슈퍼 프로퍼티를 초기화합니다. 로그아웃 시 사용하세요.

function handleLogout() {
  SolapiCRM.reset();
  window.location.href = '/login';
}

flush() — 이벤트 즉시 전송큐에 있는 모든 이벤트를 즉시 서버로 전송합니다.

// 구매 완료 후 즉시 전송
SolapiCRM.track('PURCHASE', { orderId: 'ORD_123', amount: 159000 });
await SolapiCRM.flush();
window.location.href = '/order-complete';

destroy() — SDK 완전 정리SDK를 완전히 정리합니다. 이벤트 전송, 타이머 정지, History API 복원, 이벤트 리스너 제거 등 모든 작업을 수행합니다.

await SolapiCRM.destroy();

11. 보안 설정### 허용 도메인 (Allowed Domains)`json

{ "example.com": { "description": "example.com만 허용" }, ".example.com": { "description": "모든 서브도메인" }, "localhost:3000": { "description": "로컬 개발 환경" }, "설정 안 함": { "description": "모든 도메인 허용" } }
<h3>권한 설정- trackEvents: 이벤트 추적 (track(), trackPageView(), identify()) 허용</h3>
  • createRecords: 레코드 생성 (createRecord()) 허용
<h3>환경별 키 분리
javascript const trackingKey = process.env.NODE_ENV === 'production' ? 'tk_live_production_key' : 'tk_test_development_key';

SolapiCRM.init({
trackingKey,
entityId: 'CRMRC1_contacts',
debug: process.env.NODE_ENV !== 'production'
});

`추적 키 (tk_live_xxx)와 SOLAPI API 키 (NCSxxx...)는 다릅니다. API 키는 절대 클라이언트 코드에 포함하면 안 됩니다.

12. 트러블슈팅`json

{ "SolapiCRM is not defined": { "cause": "CDN 스크립트 미로드", "solution": "CDN URL 확인, 스크립트 순서 확인" }, "이벤트 미수집": { "cause": "init() 미호출 또는 키 오류", "solution": "debug: true로 로그 확인" }, "401 Unauthorized": { "cause": "추적 키 무효/폐기", "solution": "키 활성 상태 확인, 새 키 생성" }, "403 Forbidden": { "cause": "도메인 미허용", "solution": "허용 도메인 목록 확인" }, "SPA 페이지뷰 미수집": { "cause": "autoPageView 비활성", "solution": "autoPageView: true 설정" }, "이벤트 중복 전송": { "cause": "init() 중복 호출", "solution": "앱에서 한 번만 호출" } }
<h3>디버그 모드 활성화
javascript SolapiCRM.init({ trackingKey: 'tk_test_xxx', entityId: 'CRMRC1_contacts', debug: true });

// 콘솔 출력 예시:
// [SolapiCRM] Initialized with trackingKey: tk_test_

// [SolapiCRM] Track event: BUTTON_CLICK
// [SolapiCRM] Flushing 1 events...
// [SolapiCRM] Events sent successfully

`

13. FAQQ: 추적 키를 클라이언트 코드에 노출해도 안전한가요? 네, 안전합니다. 추적 키는 쓰기 전용이며, 허용 도메인 검증과 권한 제한으로 보호됩니다.


Q: 여러 개체(Entity)에 이벤트를 추적할 수 있나요? 네,
init()에서 기본 개체를 설정하고, track() 호출 시 entityId 옵션으로 다른 개체를 지정할 수 있습니다.
Q: 이벤트가 실시간으로 전송되나요? 아니요, 이벤트는 배치로 전송됩니다. 실시간 전송이 필요한 경우 SolapiCRM.flush()를 호출하세요.
Q: 익명 사용자의 이벤트는 얼마나 보관되나요? 90일간 보관됩니다. 90일 내에 identify()를 호출하면 알려진 레코드로 병합됩니다.
Q: 모바일 앱에서도 사용할 수 있나요? 현재 SDK는 웹 브라우저 전용입니다. 모바일 앱에서는 REST API를 직접 호출하세요.
Q: 이벤트 이름 규칙이 있나요?** 공식 규칙은 없지만 대문자 + 언더스코어를 권장합니다. (예:
BUTTON_CLICK, VIEW_PRODUCT, ADD_TO_CART`)