ה-API למפתחים של marv.Inbox
חברו כל CRM, קופה, מערכת ERP או אפליקציה פנימית לתיבת ה-WhatsApp וה-Messenger של הצוות שלכם. יש API מסוג REST מעל OAuth2 לקריאה וכתיבה של נתונים, ולצדו webhooks חתומים שדוחפים אליכם אירועים בזמן אמת. כל סביבת עבודה יכולה ליצור לעצמה הרשאות תחת הגדרות, מפתחים. בלי תוכנית שותפים ובלי שיחת מכירה.
כתובת בסיס: https://api.marvinbox.com
מה אפשר לבנות
סנכרון אנשי קשר ושיחות
עדכנו אנשי קשר מה-CRM שלכם, אתרו אותם לפי טלפון או לפי מזהה משלכם, וקראו שיחות והיסטוריית הודעות.
שליחת הודעות וקמפיינים
שלחו תגובה או תבנית WhatsApp מאושרת לתוך שיחה, או הפעילו קמפיין יזום לרשימת אנשי קשר.
יצירת משימות ותיעוד אירועים
פתחו משימות לצוות וכתבו אירועי ציר זמן של ה-CRM, כמו הזמנה שבוצעה או חשבונית באיחור, על איש קשר.
קבלת webhooks בזמן אמת
הירשמו להודעות נכנסות, לשינויים בשיחות, לעדכוני משימות ולאירועי קמפיין. כל מסירה חתומה ב-HMAC.
כתובת בסיס וגישה
ה-API פעיל בייצור כבר היום. אין צורך בשדרוג או בחשבון מפתחים נפרד.
- כתובת בסיס
https://api.marvinbox.com- איך מקבלים הרשאות
- התחברו ל-app.marvinbox.com ופתחו הגדרות, מפתחים. צרו integration client כדי לקבל client id ו-client secret ל-API, ורשמו webhook endpoint כדי לקבל אירועים. לניהול שניהם נדרש תפקיד מנהל סביבת עבודה.
התחלה מהירה
שלושה צעדים מאפס ועד הקריאה המאומתת הראשונה.
צרו integration client
תחת הגדרות, מפתחים, Integration clients, צרו client ובחרו את ה-scopes שהוא צריך. העתיקו את ה-client id ואת ה-client secret. ה-secret מוצג פעם אחת בלבד.
המירו הרשאות לטוקן
קראו ל-endpoint של הטוקן עם ה-client id וה-secret. בתגובה תקבלו bearer token קצר מועד, בתוקף לשעה.
קראו ל-API
שלחו את הטוקן בכותרת Authorization בכל בקשה. הטוקן כבר מזהה את סביבת העבודה שלכם, אז אין כותרת tenant להגדיר.
curl -X POST https://api.marvinbox.com/external/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "marv_ic_live_...",
"client_secret": "marv_cs_..."
}'תגובה
{
"access_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "customers:write messages:write"
}curl -X POST https://api.marvinbox.com/external/v1/customers/upsert \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: <unique-key>" \
-d '{
"phone": "+972501234567",
"name": "Jane Doe",
"externalCustomerId": "crm-001"
}'אימות
האימות מבוסס על הרשאת client credentials של OAuth2. שלחו את ה-client id וה-secret ל-endpoint של הטוקן וקבלו bearer token (JWT חתום) בתוקף ל-3600 שניות.
שלחו את הטוקן הזה כ-Authorization: Bearer <token> בכל בקשה ל-external/v1. הטוקן קשור לסביבת העבודה שבבעלות ה-client, כך שטוקן של סביבה אחת לעולם לא יקרא סביבה אחרת, ואתם לא שולחים מזהה tenant.
ה-scopes נבדקים מול ה-client בזמן אמת בכל קריאה, כך שצמצום scope או החלפת secret נכנסים לתוקף מיד.
Scopes
תנו ל-client רק את ה-scopes שהוא צריך. כל endpoint למטה מציין את ה-scope הנדרש לו.
| Scope | מעניק |
|---|---|
customers:read | Look up contacts |
customers:write | Create and update contacts |
conversations:read | List and read conversations |
conversations:write | Reserved for future use |
messages:read | Read message history |
messages:write | Send messages and templates |
events:write | Ingest CRM timeline events |
tasks:read | List and read tasks |
tasks:write | Create and update tasks |
campaigns:write | Create outbound campaigns |
נקודות קצה (REST)
כל נקודות הקצה נמצאות תחת כתובת הבסיס שלמעלה. בקשות כתיבה מקבלות כותרת Idempotency-Key.
| מתודה | נקודת קצה | Scope |
|---|---|---|
| POST | /external/oauth/tokenExchange client credentials for an access token | none |
| POST | /external/v1/customers/upsertCreate or update a contact by phone or external id | customers:write |
| GET | /external/v1/customers/lookupFind a contact by phone or external id | customers:read |
| GET | /external/v1/contactsList contacts (org, chat-window flag, last message), by last activity | customers:read |
| POST | /external/v1/contacts/messagesRead a contact’s messages grouped per phone | messages:read |
| GET | /external/v1/templatesList approved WhatsApp templates (with template id) | messages:read |
| POST | /external/v1/messages/sendSend by phone: a text reply or an approved template | messages:write |
| POST | /external/v1/eventsLog a CRM timeline event (alias /interactions) | events:write |
| POST | /external/v1/outbound/campaignsCreate an outbound campaign | campaigns:write |
| POST | /external/v1/tasksCreate a task | tasks:write |
| GET | /external/v1/tasksList tasks | tasks:read |
| PATCH | /external/v1/tasks/:idUpdate a task | tasks:write |
Idempotency
שלחו כותרת Idempotency-Key בכל בקשת כתיבה. אם תנסו שוב עם אותו מפתח, marv.Inbox תחזיר את התוצאה השמורה של הקריאה הראשונה במקום לבצע את הפעולה פעמיים. השתמשו במפתח ייחודי וטרי לכל פעולה לוגית.
מגבלות קצב ורשימת IP מותרים
כל client מוגבל ל-120 בקשות לדקה כברירת מחדל. התגובות נושאות X-RateLimit-Limit ו-X-RateLimit-Remaining, ובחריגה מהמגבלה מוחזר 429. אפשר גם להגביל client לרשימת טווחי IP מותרים (CIDR) בעת היצירה.
Webhooks
Webhooks דוחפים אירועים לשרת שלכם ברגע שהם קורים, כך שאינכם צריכים לבצע polling.
רישום endpoint
תחת הגדרות, מפתחים, Webhooks, הוסיפו את כתובת המקלט שלכם ובחרו את האירועים הרצויים. העתיקו את ה-secret לחתימה שמוצג ביצירה. אפשר לרשום עד עשרה endpoints, להפעיל או לכבות כל אחד, ולסקור ניסיונות מסירה אחרונים באותו מסך.
איך נראית מסירה
כל אירוע הוא בקשת POST עם גוף JSON והכותרות הבאות:
POST /your-receiver HTTP/1.1
Content-Type: application/json
X-Marv-Event: message.created
X-Marv-Delivery: 7c9e6679-7425-40de-944b-e07fc1f90ae7
X-Marv-Timestamp: 2026-06-15T10:23:45.123Z
X-Marv-Signature: v1=3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d...תגובת 2xx מסמנת מסירה מוצלחת. marv.Inbox ממתינה עד 10 שניות לתגובה שלכם ומנסה שוב פעם אחת אחרי 5 שניות בכישלון. כתובות מקלט חייבות להיות ציבוריות. כתובות פרטיות ו-loopback נדחות.
סוגי אירועים
הירשמו לכל שילוב של האירועים האלה.
| אירוע | מתי נשלח |
|---|---|
message.created | A message was sent or received |
conversation.updated | Conversation metadata changed |
conversation.assigned | Conversation assignment changed |
conversation.closed | A conversation was closed |
conversation.reopened | A closed conversation was reopened |
אימות מסירה
כל מסירה חתומה כדי שתוכלו לסמוך שהיא הגיעה מ-marv.Inbox. החתימה מחושבת על גוף הבקשה הגולמי:
v1=HMAC-SHA256(secret, "{X-Marv-Timestamp}.{X-Marv-Delivery}.{rawBody}")חשבו אותה מחדש מול הבייטים המדויקים שקיבלתם, לפני פענוח JSON, דחו כל מסירה שבה חותם הזמן ישן ביותר מחמש דקות, בצעו דה-דופ לפי X-Marv-Delivery, והשוו בזמן קבוע.
import { createHmac, timingSafeEqual } from 'crypto';
// marv.Inbox signs every delivery:
// v1=HMAC-SHA256(secret, `${timestamp}.${deliveryId}.${rawBody}`)
// Verify against the EXACT raw request body, before JSON parsing.
export function verifyMarvWebhook(headers, rawBody, secret) {
const signature = headers['x-marv-signature']; // "v1=<hex>"
const timestamp = headers['x-marv-timestamp']; // ISO 8601
const deliveryId = headers['x-marv-delivery']; // UUID, dedupe on this
// Reject anything older than 5 minutes (replay protection).
if (Math.abs(Date.now() - Date.parse(timestamp)) > 300_000) return false;
const expected = 'v1=' + createHmac('sha256', secret)
.update(`${timestamp}.${deliveryId}.${rawBody}`)
.digest('hex');
const a = Buffer.from(signature ?? '', 'utf8');
const b = Buffer.from(expected, 'utf8');
return a.length === b.length && timingSafeEqual(a, b);
}שגיאות
שגיאות משתמשות בקודי סטטוס סטנדרטיים של HTTP עם גוף JSON שמתאר את הבעיה.
| קוד | משמעות |
|---|---|
400 | Invalid request body or a missing required field |
401 | Missing, invalid, or expired access token |
403 | Token lacks the required scope, or the caller IP is not allowlisted |
404 | Unknown workspace or resource |
409 | Conflict, for example a colliding externalCustomerId |
429 | Rate limit exceeded (see X-RateLimit-Remaining) |
שאלות נפוצות
האם צריך תוכנית שותפים או שיחת מכירה כדי להשתמש ב-API?+
לא. כל סביבת עבודה יכולה ליצור integration clients ו-webhook endpoints תחת הגדרות, מפתחים. אין תהליך הגשה וה-API אינו נעול לתוכנית גבוהה יותר.
איך מחברים CRM או מערכת תמיכה ל-marv.Inbox?+
עדכנו את אנשי הקשר שלכם עם customers/upsert, תעדו פעילות עם events, פתחו מעקבים עם tasks, ושלחו תגובות או תבניות מאושרות עם messages/send. כדי לקבל הודעות נכנסות ועדכונים במערכת שלכם, רשמו webhook endpoint והירשמו לאירועים שחשובים לכם.
איך מוודאים ש-webhook באמת הגיע מ-marv.Inbox?+
חשבו מחדש את חתימת HMAC-SHA256 על "{timestamp}.{deliveryId}.{rawBody}" עם ה-secret של ה-endpoint והשוו אותה לכותרת X-Marv-Signature בזמן קבוע. דחו מסירות שבהן X-Marv-Timestamp ישן ביותר מחמש דקות ובצעו דה-דופ לפי X-Marv-Delivery.
מה ההבדל בין integration client ל-webhook endpoint?+
integration client הוא ההרשאה שהקוד שלכם משתמש בה כדי לקרוא ל-API: יוצא, מכם אל marv.Inbox. webhook endpoint הוא כתובת ש-marv.Inbox קוראת אליה כשמשהו קורה: נכנס, מ-marv.Inbox אליכם. רוב האינטגרציות משתמשות בשניהם.
איך מסובבים או מבטלים גישה?+
סובבו את ה-secret של integration client או בטלו את ה-client לגמרי תחת הגדרות, מפתחים. סיבוב מבטל את ה-secret הישן מיד. ל-webhooks, כבו או מחקו את ה-endpoint כדי לעצור מסירות.
האם שליחת הודעות מכבדת את חלון 24 השעות של WhatsApp?+
כן. הודעת WhatsApp חופשית מותרת רק בתוך 24 שעות מההודעה האחרונה של הלקוח. מחוץ לחלון, שלחו תבנית מאושרת במקום. ה-API אוכף זאת עבורכם.
התחילו לבנות
צרו את ה-integration client וה-webhook endpoint הראשונים שלכם באפליקציה, או ספרו לנו מה אתם מחברים ונעזור לכם לאפיין.