Users API
יצירה, עדכון וניהול פרופילי משתמשים בצורה תכנותית.
כל נקודות הקצה בעמוד זה יחסיות לכתובת הבסיס: https://api-eu1.joryio.com - ראו סקירת API.
אימות
כל הבקשות דורשות אימות עם מפתח API:
Authorization: Bearer jry_live_your_api_key_here
Content-Type: application/json
Create or Update User
יצירת משתמש חדש או עדכון מאפייני משתמש קיים.
נקודת הקצה מקבלת שתי צורות גוף: אובייקט משתמש בודד (המתועד כאן - מחזיר את המשתמש המלא עם סיכומי קליטה מפורטים) או מערך JSON חשוף של אובייקטי משתמש לפעולות באצווה (מחזיר סיכום מצרפי) - ראו Bulk Operations (array body).
Endpoint
POST /users
גוף בקשה
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
externalId | string | אחד מ־externalId / email | המזהה הייחודי שלכם למשתמש (עד 255 תווים) - מפתח היצירה-או-עדכון |
email | string | אחד מ־externalId / email | כתובת אימייל |
userId | string | לא | המזהה הפנימי של Joryio (24-hex, מהתגובות של ה-API) - עדכון בלבד, לעולם לא יוצר (ראו הערה למטה). לא ניתן לשלוח יחד עם externalId |
phone | string | לא | מספר טלפון (עד 20 תווים) |
attributes | object | לא | מאפייני משתמש מותאמים (מוגבל: עד 200 מפתחות, 50KB, עומק קינון 5) |
subscriptions | array | לא | חברויות ברשימות מנויים שמוחלות באותה קריאה (עד 100). ראו Inline subscriptions |
events | array | לא | אירועים שנקלטים באותה קריאה (עד 25). ראו Inline events |
userId הוא המזהה הפנימי של Joryio - עדכון בלבדuserId ו־externalId אינם כינויים זה לזה. userId הוא ה־id הפנימי בן 24 תווי hex שרק Joryio יוצרת (מוחזר כ־id / userId בתגובות): שליחתו מעדכנת בדיוק את אותו משתמש, או מחזירה 404 אם הוא לא קיים - היא לעולם לא יוצרת משתמש ולעולם לא מתאימה לפי externalId. ערך userId שאינו 24-hex נדחה עם 400, ושליחת userId ו־externalId יחד באותו גוף נדחית עם 400. ליצירה או עדכון של משתמש לפי המזהה שלכם - בכל צורה שהיא - השתמשו ב־externalId.
Inline subscriptions
קליטה בקריאה אחת: במקום קריאה נפרדת ל־POST /subscriptions/contacts/:userId/lists/:listId לכל רשימה, אפשר להעביר את החברויות ישירות. כל פריט:
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
listId | string | כן | מזהה רשימת המנויים |
channel | string | לא | email, sms, whatsapp, push או viber. ברירת מחדל: email |
status | string | לא | subscribed (ברירת מחדל) או unsubscribed |
רשומות ההסכמה נכתבות דרך אותו מסלול מבוקר של נקודת הקצה העצמאית לרישום, עם מקור api. שתי התחייבויות:
- הסרת הסכמה (opt-out) מפורשת קיימת לאותה רשימה/ערוץ לעולם אינה מוחזרת בשקט - הפריט מדולג ומדווח. צירוף מחדש של איש קשר שהסיר הסכמה מחייב קריאה מפורשת ל־
POST /subscriptions/contacts/:userId/lists/:listId. - כשלים בכל פריט (למשל
listIdלא מוכר) מדווחים בסיכום התגובה ולעולם אינם מבטלים את עדכון הפרופיל.
Inline events
כל פריט נקלט דרך צינור האירועים הסטנדרטי - טריגרים של מסעות, סגמנטים ואנליטיקה מופעלים בדיוק כמו ב־POST /events/track:
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
name | string | כן | שם האירוע (עד 255 תווים). עדיף שמות קנוניים כמו Order Completed |
properties | object | לא | מאפייני האירוע (אותן מגבלות כמו בנקודת הקצה track: מספר מפתחות, 50KB, עומק קינון מוגבל) |
timestamp | string או number | לא | מחרוזת ISO 8601 או epoch במילישניות. ברירת מחדל: עכשיו |
דוגמת בקשה
curl -X POST https://api-eu1.joryio.com/users \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"externalId": "user_123",
"email": "john.doe@example.com",
"phone": "+1234567890",
"attributes": {
"firstName": "John",
"lastName": "Doe",
"plan": "premium",
"signupDate": "2024-01-15T10:30:00Z",
"customField": "value"
},
"subscriptions": [
{ "listId": "3f9d2c1e-7a54-4b2e-9c1d-8e6f5a4b3c2d", "channel": "email" },
{ "listId": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "channel": "sms" }
],
"events": [
{
"name": "Order Completed",
"properties": { "orderId": "ord_789", "total": 129.90, "currency": "USD" },
"timestamp": "2024-01-15T10:29:45Z"
},
{ "name": "Product Viewed", "properties": { "productId": "sku_42" } }
]
}'
תגובה
אובייקט המשתמש מוחזר ישירות (בלי מעטפת). id / userId הם המזהה הפנימי של Joryio; ה־externalId ששלחתם מוחזר כפי שהוא:
{
"id": "665f1e2a9b3c4d5e6f7a8b9c",
"userId": "665f1e2a9b3c4d5e6f7a8b9c",
"externalId": "user_123",
"email": "john.doe@example.com",
"phone": "+1234567890",
"attributes": {
"firstName": "John",
"lastName": "Doe",
"plan": "premium",
"signupDate": "2024-01-15T10:30:00Z"
},
"segments": [],
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"subscriptions": { "applied": 2, "skipped": [] },
"events": { "accepted": 2, "rejected": [] }
}
שדות הסיכום subscriptions ו־events מופיעים רק כאשר הקלטים המתאימים סופקו. מנויים שדולגו הם אובייקטים של { listId, channel, reason }; אירועים שנדחו הם { name, reason }.
הערות
- אם המשתמש קיים, המאפיינים מתמזגים (מאפיינים קיימים שלא בבקשה נשמרים)
- הגדרת מאפיין כ־
nullשומרתnullכערך שלו - היא אינה מוחקת את המפתח - אימייל וטלפון מאונדקסים אוטומטית לסגמנטציה
subscriptions/eventsמוחלים אחרי עדכון הפרופיל; כשלים בכל פריט מדווחים בשדות הסיכום ולעולם אינם מכשילים את הקריאה או מבטלים את המשתמש
Get User by ID
שליפת פרופיל המשתמש ומאפייניו. קיימים שני מסלולי חיפוש:
GET /users/by-user-id/:userId- חיפוש לפי המזהה שלכם (ה־externalIdשאיתו יצרתם את המשתמש). זה המסלול המומלץ לאינטגרציות.GET /users/:userId- חיפוש לפי המזהה הפנימי של Joryio (ה־idבן 24 תווי hex שמוחזר בתגובות).
Endpoint
GET /users/by-user-id/:userId
פרמטרי נתיב
| פרמטר | סוג | תיאור |
|---|---|---|
userId | string | המזהה החיצוני שלכם (externalId) |
דוגמת בקשה
curl -X GET https://api-eu1.joryio.com/users/by-user-id/user_123 \
-H "Authorization: Bearer jry_live_your_api_key"
תגובה
{
"id": "665f1e2a9b3c4d5e6f7a8b9c",
"userId": "665f1e2a9b3c4d5e6f7a8b9c",
"externalId": "user_123",
"email": "john.doe@example.com",
"phone": "+1234567890",
"attributes": {
"firstName": "John",
"lastName": "Doe",
"plan": "premium",
"lifetimeValue": 1250.50
},
"segments": [],
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T14:20:00.000Z"
}
List Users
רשימת כל המשתמשים עם עימוד. התוצאות ממוינות לפי עדכון אחרון - אין תחביר סינון לפי מאפיינים או מיון בנקודת קצה זו (השתמשו בסגמנטים לחיתוך לפי מאפיינים, או ב־GET /users/search?query=... לחיפוש לפי שם/אימייל/טלפון/מזהה).
Endpoint
GET /users
פרמטרי שאילתה
| פרמטר | סוג | ברירת מחדל | תיאור |
|---|---|---|---|
limit | number | 50 | תוצאות לעמוד (לכל היותר 200) |
offset | number | 0 | מספר משתמשים לדילוג |
דוגמת בקשה
curl -X GET "https://api-eu1.joryio.com/users?limit=50&offset=0" \
-H "Authorization: Bearer jry_live_your_api_key"
תגובה
{
"data": [
{
"id": "665f1e2a9b3c4d5e6f7a8b9c",
"userId": "665f1e2a9b3c4d5e6f7a8b9c",
"externalId": "user_123",
"email": "user1@example.com",
"attributes": {
"plan": "premium"
}
},
{
"id": "665f1e2a9b3c4d5e6f7a8b9d",
"userId": "665f1e2a9b3c4d5e6f7a8b9d",
"externalId": "user_456",
"email": "user2@example.com",
"attributes": {
"plan": "premium"
}
}
],
"pagination": {
"total": 156,
"limit": 50,
"offset": 0,
"hasMore": true
}
}
Update User
עדכון אימייל, טלפון או מאפיינים של משתמש בלי להחליף את הפרופיל כולו. המאפיינים מתמזגים לפי מפתח. משתמשים ב־PUT (אין נתיב PATCH):
PUT /users/by-user-id/:userId- עדכון לפי המזהה שלכם.PUT /users/:userId- עדכון לפי המזהה הפנימי של Joryio.
Endpoint
PUT /users/by-user-id/:userId
גוף בקשה
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
email | string | לא | כתובת אימייל חדשה |
phone | string | לא | מספר טלפון חדש |
attributes | object | לא | מאפיינים למיזוג (עדכון לפי מפתח) |
דוגמת בקשה
curl -X PUT https://api-eu1.joryio.com/users/by-user-id/user_123 \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"attributes": {
"plan": "enterprise",
"mrr": 499
}
}'
תגובה
אובייקט המשתמש המעודכן מוחזר ישירות:
{
"id": "665f1e2a9b3c4d5e6f7a8b9c",
"userId": "665f1e2a9b3c4d5e6f7a8b9c",
"externalId": "user_123",
"attributes": {
"firstName": "John",
"plan": "enterprise",
"mrr": 499,
"signupDate": "2024-01-15T10:30:00Z"
},
"updatedAt": "2024-01-20T15:30:00.000Z"
}
Delete User
מחיקת משתמש. המשתמש מועבר לסל מיחזור (מאורכב עם רישום ביקורת) וניתן לשחזר אותו - הוא אינו נמחק לצמיתות.
Endpoint
DELETE /users/:userId
פרמטר הנתיב הוא המזהה הפנימי של Joryio. דורש את ההרשאה users:delete. אפשר להעביר ?reason= אופציונלי כדי לתעד את הסיבה ברישום הביקורת של המחיקה.
דוגמת בקשה
curl -X DELETE "https://api-eu1.joryio.com/users/665f1e2a9b3c4d5e6f7a8b9c?reason=duplicate" \
-H "Authorization: Bearer jry_live_your_api_key"
תגובה
204 No Content - גוף התגובה ריק.
הערות
- המשתמש מועבר לסל מיחזור וניתן לשחזר אותו - ראו List Deleted Users. כל מחיקה נרשמת עם רישום ביקורת של מי / מתי / איך / למה. (השחזור מתבצע כרגע דרך endpoint פנימי - פנו לתמיכה כדי לשחזר איש קשר שנמחק.)
- המשתמש מוסר מהסגמנטים וקמפיינים פעילים מפסיקים לכוון אליו מיידית.
- היסטוריית האירועים נשמרת, כך שמשתמש משוחזר שומר על ההיסטוריה המלאה שלו.
- כדי למחוק לצמיתות משתמש וכל הנתונים שלו (הזכות למחיקה לפי GDPR), השתמשו בזרימת מחיקת הנתונים (DSR) במקום זאת - היא בלתי הפיכה ומהווה פעולה שונה.
List Deleted Users
רשימת סל המיחזור - משתמשים שנמחקו, יחד עם רישום הביקורת של המחיקה (מי, מתי, איך, למה).
Endpoint
GET /users/deleted
דורש את ההרשאה users:read.
פרמטרי שאילתה
| פרמטר | סוג | ברירת מחדל | תיאור |
|---|---|---|---|
query | string | - | אופציונלי. התאמה לפי תחילית email/externalId, טלפון או מזהה המשתמש המקורי |
limit | number | 50 | תוצאות לכל היותר (לכל היותר 200) |
offset | number | 0 | מספר תוצאות לדילוג |
דוגמת בקשה
curl "https://api-eu1.joryio.com/users/deleted?limit=50" \
-H "Authorization: Bearer jry_live_your_api_key"
תגובה
{
"total": 1,
"items": [
{
"originalId": "665f1e2a9b3c4d5e6f7a8b9c",
"email": "sarah@example.com",
"phone": "+15551234567",
"externalId": "usr_1001",
"deletedAt": "2026-08-09T03:00:30.000Z",
"deletedBy": "you@example.com",
"deletedVia": "api",
"deletedReason": "duplicate",
"restoredAt": null
}
]
}
Bulk Operations (array body)
אין נקודת קצה נפרדת לפעולות באצווה: POST /users מקבל או אובייקט משתמש בודד או מערך JSON חשוף של אובייקטי משתמש (בלי אובייקט עוטף). צורת המערך יוצרת או מעדכנת עד 1000 משתמשים בבקשה אחת.
Endpoint
POST /users
Content-Type: application/json
[ { ...user }, { ...user } ]
גוף בקשה
מערך JSON (עד 1000 איברים). כל איבר באותו פורמט כמו הצורה של אובייקט בודד, כולל השדות האופציונליים subscriptions ו־events. המגבלות חלות על כל איבר: עד 100 מנויים ועד 25 אירועים לכל איבר (כך שבקשת 1000 איברים נושאת לכל היותר 25 אירועים לאיבר - המכסה אינה מוכפלת על ידי האצווה).
כל איבר עובר תיקוף מלא. איבר לא תקין מדווח ב־failed לפי האינדקס שלו במערך - לעולם אינו מתקבל בשקט - ושאר האיברים התקינים עדיין מעובדים.
דוגמת בקשה
curl -X POST https://api-eu1.joryio.com/users \
-H "Authorization: Bearer jry_live_your_api_key" \
-H "Content-Type: application/json" \
-d '[
{
"externalId": "user_001",
"email": "user1@example.com",
"attributes": { "firstName": "John", "plan": "free" },
"subscriptions": [
{ "listId": "3f9d2c1e-7a54-4b2e-9c1d-8e6f5a4b3c2d", "channel": "email" }
],
"events": [
{ "name": "Order Completed", "properties": { "orderId": "ord_789", "total": 129.90 } }
]
},
{
"externalId": "user_002",
"email": "user2@example.com",
"attributes": { "firstName": "Jane", "plan": "premium" }
}
]'
תגובה
בשונה מצורת האובייקט (שמחזירה את המשתמש המלא עם סיכומי קליטה מפורטים), צורת המערך מחזירה סיכום מצרפי:
{
"processed": 2,
"created": 1,
"updated": 1,
"failed": [],
"subscriptions": { "applied": 1, "skipped": 0 },
"events": { "accepted": 1, "rejected": 0 }
}
תגובה עם כשלים
{
"processed": 2,
"created": 1,
"updated": 1,
"failed": [
{
"index": 2,
"userId": "user_003",
"reason": "property hacker should not exist"
}
],
"subscriptions": { "applied": 0, "skipped": 0 },
"events": { "accepted": 0, "rejected": 0 }
}
מגבלות
- לכל היותר 1000 משתמשים בבקשה
- כל איבר עובר את אותו תיקוף כמו צורת האובייקט הבודד (כולל
subscriptions/eventsהמקוננים) - מכסות לכל איבר: 100 מנויים, 25 אירועים
- מכסות לכלל הבקשה: לכל היותר 500 אירועים ו־1000 חברויות ברשימות מנויים, במצטבר על פני כל המערך - מעבר לכך, שלחו אירועים אל
POST /events/track(גוף מערך) וחברויות ברשימות אל נקודת הקצהbulk-membersלרשימות מנויים - העיבוד מתבצע במקביל בקבוצות של 10 לביצועים מיטביים
- כשל חלקי מותר - איברים תקינים מעובדים גם אם חלק נכשלו, ו־
failedמפרט כל כשל לפי אינדקס במערך - תוצאות הקליטה (
subscriptions/events) מסוכמות כספירות; השתמשו בצורת האובייקט הבודד כשנדרשות סיבות מפורטות לכל פריט
צורת המערך מיועדת לאצוות תכנותיות מצד השרת שלכם. עבור קבצים והגירות מלאות, אל תבנו לולאות אצווה ידניות - השתמשו ב-Bulk Import בלוח הבקרה (CSV/JSON עם מיפוי עמודות, מניעת כפילויות, כללי הסכמה ודוח שגיאות) או בסנכרון מחסן נתונים לטעינות חוזרות.
User Events
Get User's Events
שליפת כל האירועים עבור משתמש ספציפי.
Endpoint
GET /users/:userId/events
פרמטר הנתיב הוא המזהה הפנימי של Joryio.
פרמטרי שאילתה
| פרמטר | סוג | ברירת מחדל | תיאור |
|---|---|---|---|
limit | number | 50 | מספר אירועים להחזרה (לכל היותר 1000) |
offset | number | 0 | היסט לעימוד |
startDate | string | - | סינון אירועים אחרי תאריך זה (ISO 8601) |
endDate | string | - | סינון אירועים לפני תאריך זה (ISO 8601) |
eventName | string | - | סינון לפי שם אירוע |
groupBySession | boolean | false | החזרה גם של האירועים מקובצים לפי הפעלה |
דוגמת בקשה
curl -X GET "https://api-eu1.joryio.com/users/665f1e2a9b3c4d5e6f7a8b9c/events?limit=20" \
-H "Authorization: Bearer jry_live_your_api_key"
תגובה
שדות האירוע ב־snake_case (הם מגיעים ממחסן האנליטיקה):
{
"data": [
{
"event_id": "9b2f6c1e-4a8d-4f0b-9c3d-2e1f5a6b7c8d",
"event_name": "Order Completed",
"properties": {
"orderId": "order_456",
"total": 99.99
},
"timestamp": "2024-01-20 14:30:00"
},
{
"event_id": "1c3e5a7b-9d2f-4b6c-8e0a-3f5d7b9c1e2a",
"event_name": "Page Viewed",
"properties": {
"page": "/pricing"
},
"timestamp": "2024-01-20 14:25:00"
}
],
"total": 156,
"limit": 20,
"offset": 0
}
מאפיינים נפוצים
שדות ומאפיינים מיוחדים
email ו־phone הם שדות פרופיל ברמה העליונה (לא מאפיינים) - שלחו אותם ברמה העליונה של גוף הבקשה.
למאפיינים הבאים יש משמעות מיוחדת ב־Joryio:
| מאפיין | סוג | תיאור |
|---|---|---|
firstName | string | שם פרטי (משמש בחיפוש ובתצוגה) |
lastName | string | שם משפחה (משמש בחיפוש ובתצוגה) |
language | string | שפה מועדפת (מוגדרת אוטומטית על ידי ה־SDKs כשזמינה) |
timezone | string | אזור זמן בפורמט IANA (מפעיל שעות שקט ומשלוח מסעות לפי זמן מקומי) |
country | string | קוד מדינה (מאונדקס לסגמנטציה) |
מאפיינים מותאמים
אפשר להוסיף מספר בלתי מוגבל של מאפיינים מותאמים:
{
"attributes": {
"plan": "premium",
"mrr": 99,
"signupSource": "google_ads",
"lifetimeValue": 1250.50,
"tags": ["vip", "early-adopter"],
"preferences": {
"emailNotifications": true,
"smsNotifications": false
}
}
}
סוגי נתונים נתמכים
- String:
"premium" - Number:
99.99 - Boolean:
true/false - Date:
"2024-01-15T10:30:00Z"(ISO 8601) - Array:
["tag1", "tag2"] - Object:
{ "nested": "value" }
תגובות שגיאה
כל השגיאות משתמשות בגוף השגיאה הסטנדרטי - ראו סקירת API: תגובת שגיאה.
400 Bad Request
{
"statusCode": 400,
"message": "Cannot create or update a user without a valid identifier (externalId or email to create; userId only updates an existing user)",
"timestamp": "2026-01-15T10:30:00.000Z",
"path": "/users"
}
401 Unauthorized
{
"statusCode": 401,
"message": "Invalid or expired API key",
"timestamp": "2026-01-15T10:30:00.000Z",
"path": "/users"
}
404 Not Found
{
"statusCode": 404,
"message": "User with userId 'user_123' not found",
"timestamp": "2026-01-15T10:30:00.000Z",
"path": "/users/by-user-id/user_123"
}
שיטות עבודה מומלצות
1. ניסיון חוזר בטוח - POST /users הוא Upsert
POST /users ממופתח לפי ה־userId שלכם - ניסיון חוזר של אותה בקשה מעדכן את אותו פרופיל במקום ליצור כפילות. אין כותרת Idempotency-Key; פשוט שלחו את הבקשה שוב כפי שהיא בעת כשל רשת:
curl -X POST https://api-eu1.joryio.com/users \
-H "Authorization: Bearer jry_live_your_api_key" \
-d '{...}'
2. שמות מאפיינים
השתמשו בשמות עקביים ותיאוריים:
טוב:
{
"signupDate": "2024-01-15",
"lifetimeValue": 1250.50,
"plan": "premium"
}
לא טוב:
{
"sd": "2024-01-15",
"ltv": 1250.50,
"p": "premium"
}
3. פורמט מספר טלפון
תמיד השתמשו בפורמט E.164:
טוב: "+1234567890"
לא טוב: "(123) 456-7890", "123-456-7890"
מגבלות קצב
ל־Users API אין כיום מגבלות קצב קבועות לכל נקודת קצה - ראו סקירת API: מגבלות קצב להתנהגות ברמת הפלטפורמה ולטיפול בתגובות 429.