푸시 또는 풀
웹훅은 이벤트가 일어나는 대로 밀어 줍니다. Data API는 답이 필요한 순간에 물어보게 해 줍니다. 대부분의 팀은 둘 다 씁니다. 기록하고 대응하는 데는 웹훅을, 처리 흐름 안에서 확인하는 데는 Data API를 사용합니다.
웹훅 — 실시간 푸시
무언가 일어난 순간, 서명된 JSON 이벤트를 고객사 엔드포인트로 POST합니다. 방문자가 식별되었을 때, 계정 탈취가 표시되었을 때, 봇 공격이 시작되었을 때입니다. 폴링할 것도, 일정을 잡을 것도 없습니다.
적합한 용도: 모든 방문 기록, 공격 대응, 데이터 웨어하우스나 SIEM 적재.
이벤트에서 엔드포인트까지 p50 전달 지연 44~140ms.
Data API — 필요할 때 풀
서버 대 서버 전용 비공개 API입니다. 백엔드가 시크릿 키로 인증하고, 결정하는 그 순간에 당사가 방문자에 대해 알고 있는 내용을 그대로 읽어 갑니다. 보통 로그인이나 결제 핸들러 안에서 사용됩니다.
적합한 용도: 카드를 청구하기 전, 가입을 승인하기 전, 계정을 풀어 주기 전의 인라인 확인.
Pro 플랜부터 제공됩니다.
네 가지 이벤트 유형, 하나의 봉투
모든 전달은 같은 봉투로 도착하며, 이벤트 유형은 본문과 X-Tracio-Event-Type 헤더에 함께 담깁니다. 그래서 핸들러 하나로 네 가지를 모두 라우팅할 수 있습니다.
방문자 식별
핵심 이벤트입니다. 방문이 점수화되었음을 뜻하며 방문자 ID, 브라우저와 OS, 지리와 네트워크, 봇 판정과 위험 결정을 담습니다. 전달은 단계로 나뉘어, 페이지 로드 시점의 기본 이벤트에 이어 느리게 도착한 증거가 판정을 바꾸면 late 또는 정정 단계가 이어집니다. 단계 사이는 requestId로 맞춰 보시면 됩니다.
identification계정 탈취
어떤 방문에서 계정 탈취 탐지기가 발동했습니다. 알려진 계정 뒤의 디바이스가 더 이상 그 계정 주인의 디바이스처럼 보이지 않는 상태입니다. 식별 이벤트 본문 안에 숨는 대신, 계정 맥락을 붙인 독립 이벤트로 도착합니다.
account_takeover봇 공격
워크스페이스에 자동화 트래픽이 급증했습니다. 이 이벤트만은 뒤에 방문이 없습니다. 워크스페이스 수준 경보이므로 방문 관련 블록은 점수가 0으로 채워진 빈 껍데기로 도착하는 대신 본문에서 그냥 빠집니다.
attack_detected평판 변화
프로필이 평판 구간 사이를 이동했습니다. 봉투는 공격 경보와 같으며, 방문이 딸리지 않은 프로필 수준 이벤트로 새 구간과 직전 구간을 담아 옵니다.
reputation_changed전달 예시(발췌)
이것이 기본 본문입니다. Pro에서는 방문 벨로시티가, Business에서는 판정 사유 코드, 행동 신호, 가이던스, 브라우저 간 디바이스 데이터가 똑같은 형태 위에 더해집니다. 블록이 새로 생길 뿐, 기존 경로는 결코 움직이지 않습니다.
{ "version": 2, "event": "identification", "eventId": "req_8f21c4:primary", "requestId": "req_8f21c4", "phase": "primary", "visitorId": "3f9a1b2c4d5e6f70", "timestamp": "2026-07-30T12:00:00Z", "geo": { "country": "DE", "city": "Berlin", "timezone": "Europe/Berlin" }, "network": { "vpn": true, "proxy": false, "tor": false, "datacenter": false }, "bot": { "result": "human", "score": 12 }, "identification": { "confidence": 0.97, "incognito": false }, "decision": { "action": "suspicious", "riskScore": 65.9 }}모든 요청이 두 개의 서명을 싣습니다
X-Tracio-Signature는 서명 타임스탬프와 원본 요청 본문을 이어 붙인 값에 대해 웹훅 시크릿을 키로 계산한 HMAC-SHA256입니다. 보낸 쪽이 양측이 함께 가진 시크릿을 알고 있음을 증명합니다. X-Tracio-Signature-Ed25519는 플랫폼 서명으로, well-known 엔드포인트에서 가져온 공개 키로 검증하므로 고객사 쪽에 보관할 비밀이 없습니다. 타임스탬프가 서명 대상에 포함되어 있다는 점이, 과거에 캡처한 요청을 재전송해도 소용없게 만듭니다.
검증은 원본 요청 바이트에 대해 수행하세요. JSON을 다시 직렬화하면 바이트가 달라져 서명이 맞지 않습니다. 재시도는 같은 X-Tracio-Event-Id를 실어 오므로 이 값으로 중복을 제거하시면 됩니다.
모든 전달에 붙는 헤더
X-Tracio-Signature: t=1753444800,v1=5257a869e7ecebed...X-Tracio-Signature-Ed25519: t=1753444800,kid=k1,v1=0Zx0M0n8...X-Tracio-Event-Type: identificationX-Tracio-Event-Id: req_8f21c4:primaryX-Tracio-Delivery-Attempt: 1X-Tracio-Payload-Version: 2이벤트를 잃지 않도록 설계했습니다
전달은 전용 플릿에서 동작하며, 진실의 원천은 프로세스의 메모리가 아니라 큐입니다. 그것이 at-least-once 전달을 실제로 성립시킵니다. 전달 노드가 처리 도중에 죽어도 이벤트는 여전히 큐에 있고 다른 노드가 이어받습니다.
실제 장애에 맞춘 재시도
5초, 30초, 2분, 10분, 30분, 2시간, 6시간. 첫 재시도들은 1분 안에 도착하므로 서비스를 잠깐 재시작해도 잃는 것이 없습니다. 각 대기 시간은 표기값의 절반에서 표기값 사이에서 무작위로 정해지므로, 장애가 끝난 뒤 재시도가 한꺼번에 몰려오지 않습니다.
잘못 터지지 않는 자동 비활성화
웹훅이 꺼지는 것은 실패가 임계값에 도달하고 동시에 그 상태가 15분 이상 연속으로 이어졌을 때뿐입니다. 재시작 중 밀린 전달이 잠깐 몰린다고 해서 연동이 끊기지 않습니다. 410 Gone은 즉시 비활성화됩니다. 대시보드에는 사유, 응답 코드, 다시 켜기 버튼이 표시됩니다.
끊김 없는 시크릿 교체
교체 후 24시간 동안 두 시크릿이 모두 유효하고 헤더가 두 서명을 함께 실어 오므로, 둘 중 하나만 맞아도 충분합니다. 전환 시점과 경주하는 대신 이 기간 안에서 설정을 갱신하시면 됩니다. 당장 없애야 할 때는 “즉시 폐기”로 기간을 끊을 수 있습니다.
읽을 수 있는 전달 로그
응답 코드, 소요 시간, 오류 문구를 포함한 모든 시도가 대시보드에서 웹훅별로 보입니다. 그 옆에는 서명된 샘플 페이로드를 엔드포인트로 보내는 테스트 동작이 있어, 실서비스에 나가기 전에 검증 로직을 확인할 수 있습니다.
결정하는 그 순간에 물어보세요
api.tracio.ai에서 제공되는 서버 대 서버 비공개 API입니다. 백엔드가 시크릿 키로 인증하고 자기 데이터를 읽습니다. CORS 헤더는 의도적으로 전혀 보내지 않습니다. 시크릿 키는 워크스페이스 안의 모든 것에 대한 접근을 주므로 브라우저에 절대 닿아서는 안 되기 때문입니다. Pro 플랜부터 제공됩니다.
| 메서드 | 경로 | 반환값 |
|---|---|---|
| GET | /v1/visitors/{visitorId} | 방문자 요약: 최초·최종 관측, 방문 횟수, 고유 IP와 국가, 브라우저와 디바이스, 위험 이력, 그리고 최신 세션. |
| GET | /v1/visitors/{visitorId}/sessions | 커서 페이지네이션이 붙은 세션 목록. 기간, 봇 판정 결과, 최소 위험 점수로 필터링할 수 있습니다. |
| GET | /v1/visitors/{visitorId}/sessions/latest | 최신 세션을 목록 봉투 없이 단일 객체로 반환합니다. |
| GET | /v1/sessions/{requestId} | 특정 세션 하나. visitorId를 함께 넘기면 전체 이력이 아니라 방문자 인덱스를 통해 조회됩니다. |
| GET | /v1/visitors/{visitorId}/velocity | 구간(1h, 24h, 7d) 안의 활동: 몇 번의 방문이, 몇 개의 IP에서, 몇 개 국가에 걸쳐, 몇 개 계정 아래에서 일어났는지. |
결제 시점에 방문자 확인하기
전형적인 호출입니다. 결제 핸들러 안에서 카드를 승인하기 전에 실행합니다. 요청 하나에 답 하나가 돌아오고, meta 블록에는 실제로 받은 구간이 표시됩니다. 6개월을 요청했는데 플랜 보관 기간이 30일이라면 30일을 돌려주고 그 사실을 함께 알려 줍니다.
요청
# Inside your checkout handler, before you authorize the cardcurl -s -H "Authorization: Bearer $TRACIO_SECRET_KEY" \ "https://api.tracio.ai/v1/visitors/3f9a1b2c/velocity?window=24h"응답
{ "window": "24h", "events": 128, "uniqueIps": 4, "uniqueCountries": 2, "uniqueAccounts": 1, "meta": { "plan": "business", "retentionDays": 30 }}어디서나 같은 숫자
대시보드에서 65.9로 나온 방문은 Data API에서도 65.9이고 웹훅 본문에서도 65.9입니다. 서로 독립적인 두 렌더링은 어긋날 수 있습니다. 스케일 차이가 대표적인 예로, 한쪽은 0.93을 주고 다른 쪽은 93을 주는 식입니다. 그래서 패리티 테스트가 방문 하나를 만들어 두 경로로 렌더링하고 원본 JSON 위에서 공개 필드를 비교합니다. 일치는 주장이 아니라 강제됩니다.
숫자만이 아니라 조언까지
점수는 당사가 무엇을 보았는지 알려 줍니다. 가이던스는 그에 대해 무엇을 해야 하는지 알려 줍니다. 대상은 실제로 돈이 걸린 네 가지 결정이며, 버전이 관리되는 규칙으로 계산되고 그 근거가 함께 붙습니다.
결제를 받을까요?
카드를 승인하기 전에 위험도, 사기 평판, 봇 판정을 함께 저울질합니다.
가입을 받을까요?
일회용 계정이 만들어지기 전에 잡아냅니다. 여기서는 다중 계정과 평판의 비중이 가장 큽니다.
로그인을 허용할까요?
해당 방문에서 계정 탈취 탐지기가 발동했다면 자동으로 더 엄격해집니다.
전환으로 인정할까요?
진짜 추천을 자기 추천이나 보상 목적의 봇과 갈라놓습니다.
네 단어의 어휘
각 시나리오는 네 가지 답 중 하나를 받고, 그와 함께 그 답이 나온 근거, 즉 결정을 좌우한 축이 고정된 어휘에서 제시됩니다. 봇, 위험, 사기 평판, 행동, 다중 계정, 계정 탈취, 네트워크, 제휴 패턴입니다. 신호 이름도 가중치도 임계값도 보지 않은 채, 어떤 축이 조언을 움직였는지 항상 알 수 있습니다.
하나의 계산, 세 개의 경로
같은 가이던스 블록이 웹훅에 실리고, Data API에서 응답하며, 대시보드의 방문자 카드에 표시됩니다. 규칙 세트도 하나, 결과도 하나이므로 고객사 쪽에서 맞춰 볼 일이 없습니다. 전체값 대신 해당 시나리오의 조언을 읽으세요. 전체값은 네 가지 중 가장 엄격한 것을 고른 대시보드용 요약일 뿐, 결제 결정의 근거가 아닙니다. 규칙 버전이 페이로드에 함께 실리므로, 규칙 변경은 조언이 달라진 것을 보고 추측하는 일이 아니라 곧바로 알아차리는 일이 됩니다.
"guidance": { "version": 1, "overall": "review", "payment": "review", "registration": "challenge", "login": "allow", "affiliate": "allow", "basis": ["risk", "fraud_reputation"]}프런트엔드에 다섯 개의 SDK, 백엔드에 두 개의 경로
브라우저 쪽은 다섯 개의 SDK로 제공됩니다. 바닐라 JavaScript, React, Vue 3, Angular, Svelte 5입니다. 서버 사이드 SDK는 없으며 이는 의도적입니다. 백엔드는 서명된 웹훅과 Data API를 통해 순수한 HTTP로 연동합니다. 서명 검증은 당사가 공개하는 레퍼런스 벡터를 상대로 열몇 줄이면 되고, 서버 의존성 트리에서 계속 올려 줘야 할 것이 늘어나지도 않습니다.