ה-Server API מאפשר לשרת שלכם לקרוא את נתוני הזיהוי ש-TRACIO כבר אספה עבור ה-workspace שלכם: ההיסטוריה של מבקר, סשנים בודדים ומוני velocity על חלון קצר.
הוא משלים את Webhooks ולא מחליף אותם:
| Webhooks | Server API | |
|---|---|---|
| כיוון | TRACIO דוחפת אל נקודת הקצה שלכם | השרת שלכם מושך לפי דרישה |
| תזמון | בכל פעם שמתרחש זיהוי | בכל עת, לאורך חלון השמירה שלכם |
| מתאים ל־ | תגובה לאירוע | חיפוש נתונים תוך כדי החלטה, מילוי לאחור וחקירות |
שני המשטחים זמינים החל מתוכנית Pro ומעלה.
https://api.tracio.ai/v1זהו מארח שונה מנקודת הקצה של הדפדפן (edge.tracio.ai) ומלוח הבקרה (app.tracio.ai).
שלושתם נפרדים: הדפדפן מדבר עם ה-edge באמצעות המפתח הציבורי שלכם, והשרת שלכם מדבר
עם ה-Server API באמצעות המפתח הסודי שלכם.
כל בקשה נושאת את המפתח הסודי שלכם כאסימון bearer:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"ה-Server API מיועד לתקשורת שרת-לשרת בלבד. כותרות CORS אינן מוחזרות במכוון, ולכן דפדפן אינו יכול לקרוא לו — וזה מה ששומר את המפתח הסודי שלכם מחוץ לקוד צד-הלקוח. לעולם אל תשלחו את המפתח הסודי לדפדפן.
צרו אותו בלוח הבקרה תחת API Keys, ובחרו בסוג secret.
tracio_sk_ ואחריו 43 תווים, 53 בסך הכול. לוח הבקרה מציג אותו לפי
מספר התווים הראשונים שלו כדי שתוכלו להבחין בין מפתחות.החלפה מנפיקה מפתח חדש ומשאירה את הישן פעיל למשך 7 ימים, כך שתוכלו להטמיע אותו בלי זמן השבתה. פרסו את המפתח החדש, ודאו שהתעבורה עברה אליו ותנו לישן לפוג. מפתחות ציבוריים אינם ניתנים להחלפה — הם אינם סודות והם גלויים בקוד המקור של העמוד שלכם במכוון.
כל נתיב הוא GET. אין פעולות כתיבה ב-Server API: הוא קורא נתונים, והתצורה שלכם חיה
בלוח הבקרה.
| מתודה | נתיב | מחזיר |
|---|---|---|
GET | /v1/visitors/{visitorId} | היסטוריה מצרפית של מבקר אחד, בתוספת הסשן האחרון שלו |
GET | /v1/visitors/{visitorId}/sessions | רשימה מעומדת של הסשנים של אותו מבקר |
GET | /v1/visitors/{visitorId}/sessions/latest | הסשן העדכני ביותר בלבד |
GET | /v1/visitors/{visitorId}/velocity | מוני פעילות על חלון קצר |
GET | /v1/sessions/{requestId} | סשן יחיד לפי מזהה הבקשה שלו |
GET | /.well-known/webhook-keys | מפתחות ציבוריים לחתימת פלטפורמת ה-webhook (ללא אימות) |
לוכסן בסוף הנתיב מתקבל ומתעלמים ממנו. נתיב לא מוכר או מתודה שגויה מחזירים את אותה מעטפת שגיאת JSON כמו כל דבר אחר, לעולם לא עמוד HTML או טקסט פשוט.
כל קריאה תחומה בחלון זמן, שנשלט על ידי שני פרמטרי שאילתה אופציונליים:
| פרמטר | מקבל |
|---|---|
from | YYYY-MM-DD או חותמת זמן מלאה לפי RFC 3339 |
to | YYYY-MM-DD או חותמת זמן מלאה לפי RFC 3339 |
to כולל את כל אותו יום.400 invalid_request ועם ההודעה
time must be YYYY-MM-DD or RFC3339.meta, לכן בדקו את meta.from ואת meta.to במקום
להניח שהבקשה שלכם כובדה מילה במילה.curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"התגובה נושאת את ההיסטוריה המצרפית ומשבצת בתוכה את הסשן האחרון, כך שהמקרה הנפוץ דורש בקשה אחת ולא שתיים:
{ "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "firstSeenAt": "2026-05-02T10:11:12Z", "lastSeenAt": "2026-07-25T08:00:00Z", "visits": 42, "incognitoVisits": 3, "uniqueIps": 5, "uniqueCountries": 2, "browsers": ["Chrome"], "os": ["macOS"], "devices": ["desktop"], "risk": { "maxRiskScore": 63, "avgBotScore": 12.5, "botSessions": 7, "lastDecision": "real" }, "network": { "vpnSeen": false, "proxySeen": false, "torSeen": false, "datacenterSeen": true, "lastIsp": "Deutsche Telekom" }, "lastSession": { "requestId": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "accountId": "user_8842", "timestamp": "2026-07-25T08:00:00Z", "tag": "checkout", "url": "https://shop.example.com/checkout", "ip": "203.0.113.42", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36", "browser": { "name": "Chrome", "version": "126.0" }, "os": { "name": "macOS", "version": "14.5" }, "device": "desktop", "geo": { "country": "DE", "city": "Berlin", "timezone": "Europe/Berlin", "isp": "Deutsche Telekom" }, "network": { "vpn": false, "proxy": false, "tor": false, "datacenter": false, "asn": 3320 }, "bot": { "result": "human", "score": 4.5, "antidetectScore": 2.1 }, "identification": { "confidence": 0.97, "incognito": false, "matchType": "exact", "matchConfidence": 0.99 }, "decision": { "action": "real", "riskScore": 12 } }, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}| שדה | משמעות |
|---|---|
visits, incognitoVisits | סך הביקורים בחלון, וכמה מהם היו בחלון פרטי |
uniqueIps, uniqueCountries | כתובות ומדינות שונות שנצפו בחלון |
browsers, os, devices | הסביבות השונות שבהן הופיע המבקר הזה |
risk.maxRiskScore | ציון הסיכון הגבוה ביותר שנרשם בחלון, 0..100 |
risk.lastDecision | ההכרעה שנרשמה עבור הביקור האחרון |
risk.avgBotScore, risk.botSessions | ממוצע ציון הבוט ומספר סשני הבוטים — Business ומעלה |
network.*Seen | האם אי פעם נצפו עבור המבקר הזה VPN, פרוקסי, צומת יציאה של Tor או כתובת דאטה-סנטר |
network.lastIsp | ספק האינטרנט האחרון — Business ומעלה |
lastSession | אובייקט הסשן המלא של הביקור האחרון |
meta | התוכנית, תקופת השמירה שלה בימים והחלון שהוחל בפועל |
מבקר שאין לו נתונים בתוך חלון השמירה מחזיר 404 not_found עם ההודעה
visitor not found in the retention window — זו אינה שגיאה באינטגרציה שלכם, אלא סימן
שהמבקר חדש או שנתוניו כבר התיישנו.
הסשן נושא שתי הכרעות, והן עונות על שאלות שונות — האם הלקוח היה אוטומטי, ולמה הגיע מנוע הסיכון בסך הכול:
| שדה | ערכים |
|---|---|
bot.result | human, bot, uncertain |
decision.action | real, fake, suspicious |
גם bot.score וגם decision.riskScore נעים בטווח 0..100. ב-Business ומעלה,
guidance הופך אותם להמלצה לכל תרחיש על הסולם
allow ← challenge ← review ← deny — ראו
Guidance למשמעות של כל שלב.
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions?limit=100&minRiskScore=50"| פרמטר | ברירת מחדל | הערות |
|---|---|---|
limit | 50 | חסום ב-500; ערך גדול יותר נחתך ולא נדחה |
from, to | שמירת התוכנית | החלון הזמני המשותף שתואר למעלה |
cursor | — | סמן עימוד אטום מהעמוד הקודם |
botResult | — | השאירו רק סשנים עם הכרעת הבוט הזו |
minRiskScore | — | השאירו רק סשנים בציון הסיכון הזה ומעלה, 0..100 |
הסשנים חוזרים מהחדש לישן:
{ "items": [ { "requestId": "9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31", "visitorId": "X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y", "timestamp": "2026-07-25T08:00:00Z" } ], "nextCursor": "MTcyMTg5NDQwMDAwMDphYmMxMjM", "hasMore": true, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-04-26T00:00:00Z", "to": "2026-07-25T12:00:00Z" }}העימוד מבוסס סמן. אין פרמטר page ואין offset: העבירו את ה-nextCursor שקיבלתם
בחזרה כ-cursor, והמשיכו כל עוד hasMore הוא true.
async function allSessions(visitorId: string, secretKey: string) { const sessions = [] let cursor: string | undefined
do { const url = new URL(`https://api.tracio.ai/v1/visitors/${visitorId}/sessions`) url.searchParams.set("limit", "500") if (cursor) url.searchParams.set("cursor", cursor)
const res = await fetch(url, { headers: { Authorization: `Bearer ${secretKey}` } }) if (!res.ok) throw new Error(`Server API: ${res.status}`)
const page = await res.json() sessions.push(...page.items) cursor = page.nextCursor } while (cursor)
return sessions}התייחסו לסמן כאל אטום — תוכנו הוא פרט מימוש והוא עשוי להשתנות. סמן שנערך נדחה עם
400 invalid_request ועם ההודעה malformed cursor.
העדכני ביותר:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/sessions/latest"זה מחזיר אובייקט סשן חשוף — לא מערך, ולא עטוף במעטפת. מבקר שאין לו סשנים בחלון מחזיר
404 not_found עם no sessions for this visitor in the retention window.
או לפי requestId, המזהה שמופיע גם במטען ה-webhook:
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/sessions/9c1f6a2e-3b7d-4c58-a1e2-6f0d8b4a7c31?visitorId=X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y"visitorId הוא אופציונלי כאן, אבל העברתו כשאתם יודעים אותו מזרזת את החיפוש במידה
ניכרת.
ה-velocity עונה על השאלה „כמה המבקר הזה עשה לאחרונה“ — זו הצורה של credential stuffing, בדיקת כרטיסים והרשמות בכמות.
curl -H "Authorization: Bearer tracio_sk_XXXX...XXXX" \ "https://api.tracio.ai/v1/visitors/X7fh2Hg9LkMn3pQr5tBvQw3xZa9mK2pL4nR8dT6y/velocity?window=1h"window מקבל 1h, 24h או 7d וברירת המחדל שלו היא 24h. כל ערך אחר נדחה עם
400 invalid_request ועם window must be one of: 1h, 24h, 7d.
{ "window": "1h", "events": 37, "uniqueIps": 9, "uniqueCountries": 3, "uniqueAccounts": 12, "botEvents": 4, "meta": { "plan": "business", "retentionDays": 90, "from": "2026-07-25T11:00:00Z", "to": "2026-07-25T12:00:00Z" }}uniqueAccounts סופר את ערכי ה-linkedId השונים ששלחתם עבור המכשיר הזה — ראו
קישור חשבונות. botEvents הוא Business ומעלה.
שדה חסר פירושו „אין נתונים“, לעולם לא אפס. שדות ללא ערך מושמטים לחלוטין במקום
להישלח כ-0, "" או null: למבקר חדש לגמרי אין matchConfidence, ולביקור נקי אין
antidetectScore או suspectScore. החריג המכוון היחיד הוא bot.score, שנוכח תמיד גם
כשהוא אפס. קראו שדות בזהירות.
המטען תלוי בתוכנית שלכם. כל תוכנית עם גישת API מקבלת את הסשן הבסיסי — מזהים, חותמת
זמן, URL, IP, user agent, דפדפן, מערכת הפעלה, מכשיר, מיקום, רשת, בוט, זיהוי והכרעה.
Pro מוסיפה את identification.matchType, identification.matchConfidence ואת
bot.antidetectScore. Business ו-Enterprise מוסיפות את geo.isp, network.asn,
decision.suspectScore, identification.driftScore, reasons, behavior,
guidance, deviceInfo ואת שדות רמת האדם (personId, reputation,
linkedAccountsCount, linkedVisitorsCount). היעדרו של שדה Business בתוכנית Pro אינו
שגיאה.
פרטים פנימיים ברמת הסיגנל לעולם אינם מוחזרים, בשום תוכנית: שמות סיגנלים בודדים, המשקלים שלהם, הספים שמאחורי הכרעה, ערכי סיגנל גולמיים ופירוקי ציונים נשארים אצלנו. ציון שניתן להנדס לאחור לכדי הקלטים שלו חדל להיות שימושי כהגנה.
כל כישלון משתמש במעטפת אחת:
{ "error": { "code": "unauthorized", "message": "missing Authorization: Bearer <secret key>", "requestId": "8f14e45fceea167a5a36dedd" }}ה-requestId הזה אינו מזהה הביקור. שני ערכים שונים חולקים את אותו שם: בתוך מטען
סשן requestId הוא ה-UUID של הביקור, אותו אחד שה-webhook מוסר; בתוך מעטפת שגיאה הוא
מזהה מעקב באורך 24 תווים שנטבע לכל קריאת HTTP. מזהה המעקב חוזר גם בכותרת X-Request-Id
בכל תגובה, מוצלחת או לא. צרפו אותו כשאתם פונים לתמיכה — כך אנחנו מוצאים את הקריאה
המדויקת שלכם.
| HTTP | code | משמעות |
|---|---|---|
| 400 | invalid_request | פרמטר חסר או פגום |
| 401 | unauthorized | המפתח נעדר, אינו תקף, בוטל או פג |
| 402 | upgrade_required | התוכנית שלכם אינה כוללת גישת API |
| 404 | not_found | דבר לא נמצא בתוך חלון השמירה |
| 405 | method_not_allowed | הנתיב קיים, אך לא עבור המתודה הזו |
| 429 | rate_limited | חריגה מהבקשות לשנייה או מהמכסה היומית |
| 500 | internal | משהו נכשל אצלנו |
| 503 | unavailable | מאגר נתונים תומך אינו נגיש זמנית |
הבדיקות רצות בסדר קבוע — מפתח, אחר כך תוכנית, אחר כך מגבלות — כך שבקשה עם מפתח שגוי תמיד מדווחת קודם על המפתח, לעולם לא על בעיית מכסה.
שני מקרי 401 נקראים אחרת במכוון: missing Authorization: Bearer <secret key> פירושו
שהכותרת מעולם לא הגיעה, ואילו invalid or revoked API key פירושו שהיא הגיעה ולא
התאימה. 402 נושא את Data API requires the Pro plan or higher.
כל תגובה מאומתת נושאת את המצב הנוכחי שלכם:
| כותרת | משמעות |
|---|---|
X-RateLimit-Limit | המכסה היומית שלכם |
X-RateLimit-Remaining | הקריאות שנותרו היום |
X-RateLimit-Reset | זמן יוניקס של האיפוס — חצות UTC |
Retry-After | שניות להמתנה, נשלח רק יחד עם 429 |
| תוכנית | בקשות לשנייה | בקשות ליום | עומק היסטוריה |
|---|---|---|---|
| Free | אין גישת API | — | 7 ימים |
| Pro | 10 | 10,000 | 30 ימים |
| Business | 50 | 100,000 | 90 ימים |
| Enterprise | 200 | ללא מדידה | 365 ימים |