פלטפורמת מפתחים

ה-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 כדי לקבל אירועים. לניהול שניהם נדרש תפקיד מנהל סביבת עבודה.

התחלה מהירה

שלושה צעדים מאפס ועד הקריאה המאומתת הראשונה.

  1. 1

    צרו integration client

    תחת הגדרות, מפתחים, Integration clients, צרו client ובחרו את ה-scopes שהוא צריך. העתיקו את ה-client id ואת ה-client secret. ה-secret מוצג פעם אחת בלבד.

  2. 2

    המירו הרשאות לטוקן

    קראו ל-endpoint של הטוקן עם ה-client id וה-secret. בתגובה תקבלו bearer token קצר מועד, בתוקף לשעה.

  3. 3

    קראו ל-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:readLook up contacts
customers:writeCreate and update contacts
conversations:readList and read conversations
conversations:writeReserved for future use
messages:readRead message history
messages:writeSend messages and templates
events:writeIngest CRM timeline events
tasks:readList and read tasks
tasks:writeCreate and update tasks
campaigns:writeCreate outbound campaigns

נקודות קצה (REST)

כל נקודות הקצה נמצאות תחת כתובת הבסיס שלמעלה. בקשות כתיבה מקבלות כותרת Idempotency-Key.

מתודהנקודת קצהScope
POST/external/oauth/token

Exchange client credentials for an access token

none
POST/external/v1/customers/upsert

Create or update a contact by phone or external id

customers:write
GET/external/v1/customers/lookup

Find a contact by phone or external id

customers:read
GET/external/v1/contacts

List contacts (org, chat-window flag, last message), by last activity

customers:read
POST/external/v1/contacts/messages

Read a contact’s messages grouped per phone

messages:read
GET/external/v1/templates

List approved WhatsApp templates (with template id)

messages:read
POST/external/v1/messages/send

Send by phone: a text reply or an approved template

messages:write
POST/external/v1/events

Log a CRM timeline event (alias /interactions)

events:write
POST/external/v1/outbound/campaigns

Create an outbound campaign

campaigns:write
POST/external/v1/tasks

Create a task

tasks:write
GET/external/v1/tasks

List tasks

tasks:read
PATCH/external/v1/tasks/:id

Update 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.createdA message was sent or received
conversation.updatedConversation metadata changed
conversation.assignedConversation assignment changed
conversation.closedA conversation was closed
conversation.reopenedA 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 שמתאר את הבעיה.

קודמשמעות
400Invalid request body or a missing required field
401Missing, invalid, or expired access token
403Token lacks the required scope, or the caller IP is not allowlisted
404Unknown workspace or resource
409Conflict, for example a colliding externalCustomerId
429Rate 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 הראשונים שלכם באפליקציה, או ספרו לנו מה אתם מחברים ונעזור לכם לאפיין.