스키마 레퍼런스
이벤트 스키마(allob.schema.json)에 쓸 수 있는 모든 필드예요. 스키마는 보통 에이전트가 작성하니, 이 페이지는 에이전트가 참고하거나 사람이 결과를 확인할 때 써요.
수정 순서
allob schema pull # 현재 버전을 allob.schema.json 으로 받기
# allob.schema.json 수정
allob schema push --dry-run # 검사만
allob schema push --note "add checkout_start"
allob sdk pull # 새 버전으로 SDK 다시 받기
allob sdk pull --check # 배포 전에 — SDK 가 스키마와 같은 버전인지(어긋나면 끝 코드 1)- 올릴 때마다 버전이 하나씩 올라가요. 이전 버전은
allob schema history로 봐요. - 받은 버전을 기준으로만 올릴 수 있어요. 그 사이 다른 사람이나 에이전트가 먼저 올렸다면
conflict에러가 나요. 다시allob schema pull해서 합친 뒤 올려요. - 지금 버전이 받는 이벤트나 저장하는 속성을 지우면 올리지 않고
breaking_change에러와 지워지는 목록을 보여 줘요. 이름을 바꾸거나, 이벤트를 앱과 서버 사이로 옮기거나,surface를 바꾸는 것도 지우는 것으로 봐요. 이미 설치된 앱은 예전 방식으로 계속 보내는데, allob 은 그걸 버리기 때문이에요. 정말 바꾸려면allob schema push --allow-breaking으로 올려요. 속성의column만 바꾸면 올리되 경고를 보여 줘요(그 속성의 예전 데이터와 보드에서 이어지지 않아요). - 올린 스키마는 1분 안에 이벤트 수집에 반영돼요.
allob sdk pull --check는 아무것도 쓰지 않고 로그인 없이 돌아요. 받은 SDK 의 버전이allob.schema.json과 다르거나,allob.schema.json을 고치고 아직 올리지 않았거나, SDK 폴더의 파일을 손으로 고쳤거나 지웠으면 이유를 한 줄씩 보여 주고 끝 코드 1 로 멈춰요. 배포 스크립트나 CI 에 넣어요.- 줄 끝만 바뀐 것(윈도의 CRLF)은 고친 것으로 보지 않아요. 코드 정리 도구(Prettier 같은 포매터)가 SDK 폴더를 고치면 고친 것으로 보니, SDK 폴더는 포매터 대상에서 빼 두세요.
- 스키마가 아직 만들 수 없는 대상만 있는 폴더(예:
apps.measurement가 없는데native폴더를 적어 둔 것)는 실패로 치지 않아요.allob sdk pull도 그 대상은 건너뛰기 때문이에요.
예시
일기 앱에서 "일기 쓰기 → 결제 화면 → 결제 시작 → 결제"를 측정하는 스키마예요.
{
"schemaVersion": 1,
"tracking": {
"landEvent": "ad_land",
"allowedHosts": ["diary.example.com"],
"ga4": { "measurementId": "G-XXXXXXXXXX" }
},
"enums": { "plans": ["monthly", "yearly"] },
"events": {
"entry_write": {
"label": "일기 쓰기",
"props": { "mood": { "enum": ["good", "soso", "bad"] } },
"order": ["mood"]
},
"paywall_view": {
"label": "결제 화면",
"props": { "from": { "enum": ["limit", "settings"] } },
"order": ["from"]
},
"checkout_start": {
"label": "결제 시작",
"pixel": "InitiateCheckout",
"ga": "begin_checkout",
"send": "now",
"props": { "plan": { "enum": "$plans" }, "price": { "column": "double1" } },
"order": ["plan"]
},
"purchase": {
"label": "결제(서버)",
"source": "server",
"props": { "plan": { "enum": "$plans" }, "value": { "column": "double1" } },
"order": ["plan"]
}
},
"funnels": {
"main": { "label": "쓰기 → 결제", "steps": ["entry_write", "paywall_view", "checkout_start", "purchase"] }
}
}이 스키마로 SDK 를 받으면 track.entryWrite({ mood: "good" }), track.checkoutStart({ plan: "yearly", price: 39 }) 같은 함수가 생겨요. 목록에 없는 값을 넣으면 타입 검사에서 에러가 나요.
최상위 필드
| 필드 | 설명 |
|---|---|
schemaVersion | 파일 형식 버전. 지금은 1 |
events | 이벤트 이름 → 이벤트 정의. 이름은 영문 소문자·숫자·_, 40자 이내 |
enums | 여러 이벤트가 같이 쓰는 값 목록. 속성에서 "$이름" 으로 불러요 |
funnels | 퍼널 ID → { label, steps, board }. 지표 탭은 "board": true 인 퍼널(하나만 둘 수 있어요)을, 없으면 첫 번째 퍼널을 보여 줘요 |
eventGroups | 묶음 이름 → 한 줄 설명. 이벤트의 group 필드로 묶어요 |
dimensions | 숫자를 나눠 볼 기준(요금제, 유입 캠페인 등) |
experiments | 제품 안 A/B 실험: 실험 이름 → { kind: "assignment", label, arms: [{ id, label, weight }], startedAt, endedAt }. 그룹(arm)은 기기마다 고정돼요. 아래 제품 안 A/B 참고 |
tracking | 측정 설정. 아래 tracking 필드 참고 |
apps | 앱 측정 모듈 설정 apps.measurement. 아래 apps 필드 참고 |
dimensions·experiments 는 저장하고 검사하지만, 지표 탭에는 아직 퍼널·방문 기기·리텐션·유입 경로·이벤트만 나와요.
제품 안 A/B
experiments 에 실험을 적고 SDK 를 다시 받으면, 실험마다 그룹을 돌려주는 함수가 생겨요.
const analytics = build();
const copy = analytics.experiment.pricingCopy(); // "control" | "short"- 그룹은 기기 id 로 정해져서 같은 기기는 늘 같은 그룹이에요. 서버에 묻지 않아요. 웹·앱·서버(
server.ts의assignArm(실험, sid))가 같은 기기 id 면 같은 그룹을 줘요. - 로그인한 사용자는
setUserId(사용자 id)를 부르면 기기 대신 사용자 id 로 그룹을 정해요. 그래서 같은 사람은 웹·앱·다른 기기에서도 같은 그룹이에요. 사용자 id 는 이벤트에 싣지 않고 광고·분석 도구로도 보내지 않아요. 피드백을 보낼 때만 보낸 사람으로 같이 가요. 로그인을 안 뒤, 실험 함수를 부르기 전에 불러 주세요(이 페이지·이번 실행에서 이미 정한 실험의 그룹은 바뀌지 않아요). 로그아웃하면setUserId(null)이에요. 서버는assignArm(실험, sid, 사용자 id)로 같은 그룹을 받아요. - 처음 부를 때 한 번 노출 이벤트
experiment_view(실험·그룹)를 보내요. allob 에만 보내고 광고·분석 도구로는 보내지 않아요. 앱은start()뒤에 불러 주세요. - 그룹의
label은 지표 화면에 보이는 이름이에요(없으면id).weight는 나누는 비율이에요(없으면 1).startedAt·endedAt은 실험을 시작하고 끝낸 날이에요. 지표 탭의 변경 타임라인에 그날 점으로 보이고, 결과도 이 기간으로 잘라 봐요. - 계측이 꺼진 기기(추적 거부·동의 전)도 그룹은 받지만 노출은 보내지 않아요.
setUserId없이 로그인 등으로 기기 id 를 바꾸면(adoptSid) 그 뒤로 그룹이 바뀔 수 있어요. 지표에서는 그런 기기를 처음 그룹으로만 세고, 몇 대인지 알려 줘요.- 이벤트 속성에 그룹을 싣던 방식(
dimension)도 그대로 쓸 수 있어요. - 결과는 지표 탭의 퍼널 나눠 보기에서 "실험: 이름"을 고르거나
allob metrics funnel --by exp:<실험>으로 봐요(지표 — 제품 안 A/B 결과).
이벤트 필드
| 필드 | 설명 |
|---|---|
label | 화면에 보이는 이름 |
props | 속성 이름 → 속성 정의 |
order | 값 목록 속성(enum)의 순서. 값 목록 속성이 있으면 꼭 적어야 해요 |
source | "server" 면 서버 이벤트. 웹·앱 SDK 에는 생기지 않고 server.ts 에 생겨요 |
surface | "web" 또는 "app". 기본값은 tracking.surface(없으면 web) |
send | "now" 면 모으지 않고 바로 보내요. 결제 바로 앞 단계처럼 놓치면 안 되는 이벤트에 써요 |
pixel·ga·tiktok | Meta 픽셀·GA4·TikTok 으로 보낼 때 쓸 그 도구의 이벤트 이름. 없으면 그 도구로 보내지 않아요 |
group | eventGroups 의 묶음 이름 |
endedAt | 더 이상 쓰지 않는 이벤트의 종료 날짜(YYYY-MM-DD) |
alerts | false 면 지표 이상 알림의 멈춤·계측 빠짐에서 이 이벤트를 빼요. payment_failed 같은 오류 이벤트처럼 0 이 되는 것이 좋은 소식인 이벤트에 써요 |
속성 필드
| 필드 | 설명 |
|---|---|
enum | 허용하는 값 목록(배열 또는 "$enums 이름") |
optional | 값 목록 속성을 비워도 될 때 true. order 의 맨 끝에만 둘 수 있어요 |
column | 숫자나 자유 입력 글자를 저장할 위치. 숫자는 double1, 글자는 blob8(32자)·blob9(64자) |
tools | "only" 면 광고·분석 도구로만 보내고, "never" 면 allob 에만 보내요 |
값 목록 속성은 order 순서대로 / 로 이어져 하나로 저장되고, 32자를 넘으면 잘려요. 짧은 값을 쓰세요.
tracking 필드
| 필드 | 설명 |
|---|---|
landEvent | 광고 링크로 들어온 순간에 남길 이벤트. 기본 ad_land |
surface | 이벤트의 기본 surface(web·app) |
allowedHosts | 측정할 도메인 목록. 목록 밖에서는 보내지 않아요 |
metaPixel·tiktokPixel·ga4 | 광고·분석 도구 ID({ "id": … }, GA4 는 { "measurementId": … }). 비우면 그 도구는 꺼져요 |
consent | 지역별 동의 방식. 웹사이트에 측정 넣기 참고 |
category | 값 목록 속성을 저장하는 방식: separator(기본 /), maxLength(검사할 최대 길이 — 32 를 적으면 가장 긴 조합을 미리 검사해요), unknown(값 목록 밖 값 대신 넣을 글자. 있으면 server.ts 에 known() 이 생겨요) |
session | 앱 세션 기준(백그라운드에서 얼마나 지나면 새 세션인지) |
transport | 이벤트를 모아 보내는 방식 |
apps 필드
apps.measurement 는 앱 측정 모듈(allob sdk pull 의 native 대상 — 앱에 측정 넣기)이 쓰는 값이에요. 비밀 값은 적지 않아요.
| 필드 | 설명 |
|---|---|
google | true 면 Google 애널리틱스(Firebase)를 켜요. 앱 폴더에 Firebase 설정 파일이 있어야 실제로 켜져요. 기본은 꺼짐 |
meta | Meta 앱 이벤트 { "appId": "<앱 ID 숫자>", "clientTokenEnv": "<환경 변수 이름>" }. 클라이언트 토큰은 빌드 환경 변수에만 넣고, 여기엔 그 이름만 적어요 |
att | iOS 앱 추적 허용 창 문구 { "text": { "en": "…", "ko": "…" } }. google·meta 를 켜면 en 이 꼭 있어야 해요(문구 없이 창을 띄우면 iOS 가 앱을 멈춰요) |
skAdNetwork | 광고 네트워크 ID 목록("cstr6suwn9.skadnetwork" 꼴) |
storeKitConsumables | 소모품 결제가 있으면 true(iOS 18+ 에서 결제 기록에 소모품도 남게) |
admob | AdMob 광고를 싣는 앱 { "mediation": ["applovin", …] }. Google 이 권하는 SKAdNetwork 목록과 고른 미디에이션 어댑터가 붙어요. 고를 수 있는 네트워크: applovin·unity·mintegral·pangle·liftoff·inmobi·dtexchange |
privacyManifest | iOS privacy manifest(NSPrivacyTracking·NSPrivacyTrackingDomains·NSPrivacyCollectedDataTypes·NSPrivacyAccessedAPITypes). 도구를 켰을 때만 앱에 들어가요 |
여기서 켠 업체(Google 애널리틱스·Meta·AdMob·미디에이션 네트워크)는 법 문서 사실에 바로 들어가요.
표준 이벤트
스키마에 적지 않아도 항상 쓸 수 있는 이벤트예요. 웹 SDK 에 같은 이름의 함수가 있어요.
| 이벤트 | 언제 | 웹 SDK 함수 |
|---|---|---|
ad_land | utm 이 붙은 광고 링크로 들어왔을 때(SDK 가 자동으로) | 없음 |
scroll_depth | 페이지를 25·50·75·90% 내렸을 때 | watchScrollDepth() |
lead | 연락처나 대기 명단을 남겼을 때 | lead() |
cta_click | 주요 버튼을 눌렀을 때 | ctaClick() |
signup_start·signup_complete | 가입을 시작했을 때, 마쳤을 때 | signUpStart()·signUpComplete() |
login | 로그인했을 때 | login() |
purchase | 결제했을 때. allob 기록은 서버가 남기고, 브라우저는 광고·분석 도구로만 보내요 | purchase(value, transactionId) |
버전과 호환성
- 이벤트나 속성을 추가하는 건 언제든 괜찮아요. 이미 배포된 SDK 는 새 이벤트를 보내지 않을 뿐이에요.
- 이벤트 이름을 바꾸거나 값의 뜻을 바꾸면 이전 숫자와 이어지지 않아요. 새 이름으로 추가하고, 이전 이벤트에는
endedAt을 적어 두세요. schemaVersion이 지금 CLI 보다 새로우면allob update를 하라고 알려 줘요.