
שליחת תבניות וואטסאפ ללקוחות שלכם, הורדת קבצים מהטבלאות שלכם, וקבלת Webhook חתום בכל פעם שמשהו משתנה בעסק. אימות באמצעות מפתח API שיוצרים בהגדרות העסק.
כל בקשות ה-API נשלחות לכתובת ה-Gateway:
https://crimbo-gateway-833321703837.me-west1.run.appכל בקשה חייבת לכלול את מפתח ה-API שלכם בכותרת X-API-Key. המפתחות מונפקים מעמוד הגדרות העסק ומוגבלים לעסק שלכם.
X-API-Key: crm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxאין לכם מפתח? פתחו הגדרות עסק ← גישת API. ערך המפתח בפורמט טקסט מופיע פעם אחת בלבד ביצירה - העתיקו אותו אז, או בטלו וצרו חדש.
לכל מפתח יש הרשאה אחת או יותר שקובעות מה מותר לו לעשות. ההרשאות נבחרות ביצירת המפתח ולא ניתן לשנות אותן אחר כך - כדי לשנות מה אינטגרציה רשאית לעשות, צרו מפתח חדש ובטלו את הישן.
| הרשאה | תיאור |
|---|---|
messages:send | שליחת הודעות וואטסאפ: /send-template ו-/send-action. מפתח שנוצר בלי לבחור הרשאה מקבל את זו. |
collections:read | הורדת קבצים שנשמרו בטבלאות שלכם. לא יכול לשלוח שום דבר, ולכן זה המפתח הבטוח לתת למערכת שמקבלת Webhooks. |
client_tags:read | קבלת רשימת התגיות שלכם וקריאת התגיות של כל לקוח. קריאה בלבד. |
client_tags:write | הוספה, החלפה והסרה של תגיות אצל הלקוחות שלכם. מפתח עם הרשאה זו יכול לשנות את חלוקת הלקוחות שלכם לקבוצות, ולכן תנו אותה רק למערכות שאתם סומכים עליהן. |
קריאה ל-endpoint שהמפתח שלכם לא מורשה אליו מחזירה 403:
{
"error": "This API key does not have the \"collections:read\" scope. Issue a key with that scope in Settings.",
"code": "API_KEY_SCOPE_MISSING",
"required_scope": "collections:read"
}כל מפתח API יכול לבצע עד 600 בקשות בדקה, בחלון זמן נע. בנוסף, בקשות מכתובת IP אחת מוגבלות ל-1,200 בדקה בסך הכול, בכל המפתחות יחד.
חריגה מחזירה 429. המתינו כמה שניות ונסו שוב, והאריכו את ההמתנה אם ה-429 חוזר.
HTTP/1.1 429 Too Many Requests
{
"error": "Too many requests",
"message": "Please slow down and try again shortly."
}POST/api/public/v1/send-template
שולח תבנית וואטסאפ מאושרת של Meta למספר טלפון. אם אין לקוח עם המספר הזה בעסק שלכם, ייווצר אוטומטית - שלחו client.name / client.email אופציונליים כדי לאכלס את הפרטים.
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
template_name | string | כן | שם תבנית מאושרת של Meta (תלוי-רישיות). |
language | string | כן | שפת התבנית כפי שרשומה ב-Meta (לדוגמה "he", "en_US"). |
phone_number | string | כן | מספר טלפון של הנמען. פורמט E.164 ("+972…") עדיף; מספרים ישראליים מקומיים מנורמלים אוטומטית. |
parameters | string[] | לא | ערכים מסודרים עבור {{1}}, {{2}}, … בגוף התבנית. הסדר חשוב. |
header_media | { type, url, filename? } | לא | חובה כשבתבנית יש כותרת של תמונה, וידאו או מסמך; אחרת יש להשמיט. type הוא "image", "video" או "document" וחייב להתאים לכותרת התבנית. url חייב להיות קישור https ציבורי: וואטסאפ מורידה ממנו את הקובץ. filename אופציונלי ורלוונטי למסמכים בלבד. |
button_parameters | { index, value, type? }[] | לא | חובה כשהקישור של כפתור מסתיים ב-{{1}}; אחרת נדרש רק כדי לקבוע payload של כפתור תשובה מהירה. index הוא מיקום הכפתור בתבנית, החל מ-0. עבור קישור, value הוא רק החלק שמחליף את {{1}}: וואטסאפ מוסיפה אותו לסוף הקישור שהתבנית מגדירה. type הוא "url" (ברירת המחדל), או "quick_reply" כדי לקבוע את ה-payload שתקבלו כשהלקוח לוחץ על הכפתור. |
client.name | string | לא | שם תצוגה המשמש ביצירת לקוח אוטומטית. מתעלם אם כבר קיים לקוח עם הטלפון הזה. |
client.email | string | לא | אימייל המשמש ביצירת לקוח אוטומטית. מתעלם אם כבר קיים לקוח עם הטלפון הזה. |
curl -X POST https://crimbo-gateway-833321703837.me-west1.run.app/api/public/v1/send-template \
-H "X-API-Key: $CRIMBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_name": "appointment_reminder",
"language": "he",
"phone_number": "+972501234567",
"parameters": ["John", "10:00"],
"client": { "name": "John Doe" }
}'וואטסאפ דוחה תבנית כזו בשגיאה 132012 אלא אם השליחה מציינת את הקובץ. שלחו header_media עם קישור https ציבורי; ה-type חייב להתאים לכותרת התבנית. תשובת 200 מעידה רק שוואטסאפ קיבלה את הבקשה: קישור שאי אפשר להשתמש בו (לא נגיש, גדול מדי, או וידאו שאינו mp4 עם וידאו H.264 ואודיו AAC) ייכשל מאוחר יותר, כשגיאה 131053 ב-webhook של סטטוס המשלוח.
curl -X POST https://crimbo-gateway-833321703837.me-west1.run.app/api/public/v1/send-template \
-H "X-API-Key: $CRIMBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_name": "product_launch",
"language": "en_US",
"phone_number": "+972501234567",
"header_media": { "type": "video", "url": "https://example.com/launch.mp4" }
}'אם הקישור של כפתור בתבנית מסתיים ב-{{1}} (למשל https://example.com/invoices/{{1}}), שלחו button_parameters עם ה-index של הכפתור ורק החלק שמחליף את {{1}}. שלחו "abc123" ולא את הכתובת המלאה: וואטסאפ מוסיפה את הערך שלכם לסוף הקישור שהתבנית מגדירה, והקישור שמתקבל לא נבדק. מעברי שורה, טאבים ורווחים חוזרים בערך הופכים לרווח יחיד.
curl -X POST https://crimbo-gateway-833321703837.me-west1.run.app/api/public/v1/send-template \
-H "X-API-Key: $CRIMBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_name": "invoice_ready",
"language": "en_US",
"phone_number": "+972501234567",
"parameters": ["John"],
"button_parameters": [{ "index": 0, "value": "abc123" }]
}'{
"success": true,
"message_id": "wamid.HBgLOTcyNTAxMjM0NTY3FQIAERgSMjA4Q0...",
"client_id": 1234,
"client_created": false
}message_id הוא ה-WAMID של Meta עבור התבנית שנשלחה. client_created מציין אם הקריאה יצרה רשומת לקוח חדשה.
POST/api/public/v1/send-action
השתמשו בזה במקום ב-/send-template כשהמערכת שלכם כבר שולחת מבנים משלה. אתם ממשיכים לשלוח את שמות הפעולות ושמות השדות שלכם - מקוננים איך שתרצו - ואנחנו מתרגמים אותם לתבנית שמטא מצפה לה. אותו מפתח API, אותה שליחה, אותה תשובה.
זה עובד על בסיס הגדרה חד-פעמית: השותף שלכם מגדיר בעמוד השותף אילו תבנית כל פעולה שולחת ואיזה שדה שלכם ממלא כל משתנה בתבנית. ההגדרה הזו תקפה לכל העסקים שהוא מנהל, כך שחיבור עסק נוסף לא דורש שינוי מצדכם.
| שדה | סוג | חובה | תיאור |
|---|---|---|---|
actionType | string | כן | שם הפעולה שהשותף שלכם הגדיר. ההתאמה אינה תלוית-רישיות. |
recipient | string | כן | מספר טלפון של הנמען. פורמט E.164 ("+972…") עדיף; מספרים ישראליים מקומיים מנורמלים אוטומטית. phone_number נתמך כשם נרדף. |
language | string | לא | שפת התבנית. נופל בחזרה לשפה שהוגדרה לפעולה, וחובה כשלפעולה אין שפה. |
…any other field | string | number | boolean | לא | כל השאר שלכם. קננו איך שהמערכת שלכם כבר עושה - ההגדרה מצביעה על כל ערך לפי נתיב, לדוגמה customer.customerName או extraFields.invoiceUrl. |
שדות כמו business.businessName או customer.customerName הם ערכים בלבד. הם ממלאים משתנים בהודעה; הם לא קובעים איזה עסק שולח או איזה לקוח מקבל. מפתח ה-API מזהה את השולח ו-recipient מזהה את הלקוח.
curl -X POST https://crimbo-gateway-833321703837.me-west1.run.app/api/public/v1/send-action \
-H "X-API-Key: $CRIMBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"actionType": "OPTIMUS_UPDATE_EVENT_TIME",
"recipient": "0501234567",
"language": "he",
"customer": {
"customerName": "יוסי כהן"
},
"appointment": {
"eventDate": "15/06/26",
"eventStartTime": "10:00"
},
"business": {
"businessName": "מספרת דנה",
"businessPhone": "031234567"
}
}'פעולה אחרת צריכה שדות אחרים, ושום דבר בבקשה לא משתנה מלבד הגוף. ערך כמו קישור לחשבונית יכול למלא משתנה בהודעה או את החלק הדינמי בקישור של כפתור, לפי האופן שבו הפעולה הוגדרה.
דבר אחד שחשוב לדעת אם ערך מזין קישור של כפתור: וואטסאפ מוסיפה אותו לסוף הקישור שהתבנית כבר מגדירה, כך שתבנית שמקשרת ל-https://example.com/{{1}} צריכה רק את המזהה. אתם יכולים להמשיך לשלוח כתובות מלאות אם זה מה שיש לכם - השותף שלכם מגדיר איזו התחלה להסיר, וקישור שמצביע למקום לא צפוי נדחה במקום להישלח שבור.
{
"actionType": "OPTIMUS_INCOMING_INVOICE_NO_BUTTON",
"recipient": "0501234567",
"language": "he",
"business": {
"businessName": "מספרת דנה",
"businessPhone": "031234567"
},
"extraFields": {
"invoiceUrl": "https://example.com/invoices/abc123"
}
}{
"success": true,
"message_id": "wamid.HBgLOTcyNTAxMjM0NTY3FQIAERgSMjA4Q0...",
"client_id": 1234,
"client_created": false
}שדה ממופה שחסר או ריק מכשיל את הבקשה לפני שנשלח משהו, כי וואטסאפ דוחה בכל מקרה הודעה עם משתנה ריק. כל השדות החסרים מוחזרים יחד, כל אחד עם הנתיב שבו הוא היה מצופה, כך שסבב אחד מספר לכם הכול. השותף שלכם יכול להגדיר ערך ברירת מחדל לכל שדה כדי להפוך אותו לאופציונלי.
{
"error": "Payload is missing values for: body variable {{1}} (expects \"customer.customerName\")",
"code": "ACTION_FIELD_MISSING",
"missing_fields": [
{ "target": "body", "position": 1, "path": "customer.customerName" }
]
}GET/api/public/v1/collections/:collectionId/rows/:rowId/files/:columnKey
מחזיר את הקובץ שנשמר בתא אחד בטבלה. זה ה-downloadUrl שכל תא קובץ מכיל ב-Webhook של collection_row, כך שבדרך כלל לא צריך לבנות אותו בעצמכם. דורש את ההרשאה collections:read.
התשובה היא הפניה 302 לקישור אחסון חתום שתוקפו פג אחרי 15 דקות. ה-downloadUrl עצמו לא פג לעולם, כך שבטוח לשמור אותו ולהוריד מאוחר יותר. הוסיפו ?disposition=inline כדי שהקובץ יוצג בדפדפן במקום שיורד.
# 1. Ask for the file. The key goes only to us; the answer is a redirect.
read -r STATUS SIGNED_URL < <(curl -s -o response.json -w '%{http_code} %{redirect_url}' \
-H "X-API-Key: $CRIMBO_API_KEY" \
https://crimbo-gateway-833321703837.me-west1.run.app/api/public/v1/collections/12/rows/4471/files/quote)
if [ "$STATUS" != "302" ]; then
echo "No download link (HTTP $STATUS):" >&2; cat response.json >&2; exit 1
fi
# 2. Download from the signed link, without the key.
curl -f -o quote.pdf "$SIGNED_URL"אל תתנו ללקוח ה-HTTP שלכם לעקוב אחרי ההפניה אוטומטית עם המפתח: curl -L וספריות רבות ישלחו את ה-X-API-Key שלכם גם לשרת האחסון. קראו את כותרת Location, ואז הורידו ממנה בלי המפתח. הקישור החתום עובד עבור כל מי שמחזיק בו עד שתוקפו פג, לכן אל תרשמו אותו בלוגים ואל תעבירו אותו הלאה.
Webhooks שולחים בקשת HTTP POST לכתובת שלכם כשמשהו קורה בעסק. כל Webhook עוקב אחרי סוג משאב אחד ואחרי האירועים שבחרתם עבורו.
הגדרת Webhooks נעשית בלוח הבקרה: אינטגרציות ← מפתחים ← Webhooks מותאמים. שם גם נמצאים הסוד לחתימה של כל Webhook, דוגמת payload לכל אירוע, ו-100 המשלוחים האחרונים שלו.
| אירוע | תיאור |
|---|---|
task.created · task.updated · task.deleted | משימה נוצרה, השתנתה או נמחקה - על ידי סוכן ה-AI או על ידי מישהו בצוות. |
calendar_event.created · calendar_event.updated · calendar_event.deleted | פגישה נקבעה, הוזזה או בוטלה. |
collection_row.created · collection_row.updated · collection_row.deleted | שורה נוספה, השתנתה או הוסרה בטבלה היחידה שה-Webhook עוקב אחריה. התאים מגיעים תחת data.values, לפי מפתחות העמודות שלכם. |
template_reply.received | מישהו לחץ על כפתור תגובה מהירה בתבנית וואטסאפ ששלחתם. כולל את טקסט התגובה, מספר הטלפון שלו ואת ה-payload של הכפתור. |
client.created | נוסף לקוח חדש: הודעה ראשונה בכל ערוץ, טופס לידים, ה-API הזה או הדשבורד. כולל clientId, fullName, phoneNumber, email, source, tags, platformUserId, isActive ו-createdAt. ייבוא מקובץ CSV לא נשלח. לעיתים רחוקות אותו לקוח עשוי להגיע פעמיים, לכן בצעו סינון כפילויות לפי data.clientId. |
אם לא הגדרתם תבנית payload, כל משלוח הוא אובייקט JSON עם השדות הבאים:
| שדה | סוג | תמיד קיים | תיאור |
|---|---|---|---|
event | string | כן | סוג האירוע, לדוגמה "task.updated". |
businessId | number | כן | מזהה העסק שלכם. |
deliveryId | string (UUID) | כן | ייחודי לכל משלוח. שמרו אותו כדי להתעלם ממשלוח שכבר טיפלתם בו. |
timestamp | string (ISO 8601) | כן | מתי המשלוח נשלח, ב-UTC. |
data | object | כן | המשאב עצמו: המשימה, הפגישה, שורת הטבלה, התגובה המהירה או הלקוח החדש, כולל הלקוח שאליו הוא שייך כשיש כזה. |
changes | object | לא | רק באירועי *.updated: כל שדה שהשתנה עם הערך לפני ואחרי. |
{
"event": "task.updated",
"businessId": 42,
"deliveryId": "3f1c2a9e-8b7d-4c51-9a0e-2d6f4b8e1c07",
"timestamp": "2026-10-02T17:30:00.000Z",
"data": {
"taskId": 1234,
"businessId": 42,
"clientId": 88,
"client": {
"id": 88,
"fullName": "Dana Levi",
"phoneNumber": "+972501234567",
"email": "dana@example.com"
},
"title": "Call back about the quote",
"content": "Asked for a price on the premium package.",
"priority": 2,
"dueDate": "2026-10-04T09:00:00.000Z"
},
"changes": {
"priority": { "before": 1, "after": 2 }
}
}הדוגמה מקוצרת. לוח הבקרה מציג את הדוגמה המלאה לכל אירוע, ובאירועי collection_row היא נבנית מהטבלאות שלכם.
כל משלוח נשלח עם Content-Type: application/json, עם הכותרות המותאמות שהוספתם, ועם הכותרות הבאות:
| כותרת | תיאור |
|---|---|
X-Webhook-Event | סוג האירוע. אותו ערך כמו event בגוף. |
X-Webhook-Delivery | מזהה המשלוח. אותו ערך כמו deliveryId בגוף. |
X-Webhook-Signature | sha256= ואחריו HMAC-SHA256 בקידוד hex של גוף הבקשה הגולמי, עם הסוד של ה-Webhook כמפתח. |
User-Agent | תמיד CrimboWebhooks/1.0. |
כל מי שיודע את הכתובת שלכם יכול לשלוח אליה POST, לכן בדקו את החתימה לפני שאתם סומכים על משלוח. חשבו HMAC-SHA256 של גוף הבקשה הגולמי עם הסוד של ה-Webhook, קודדו ב-hex, הוסיפו בהתחלה sha256=, והשוו ל-X-Webhook-Signature בהשוואה בזמן קבוע. השתמשו בגוף בדיוק כפי שהתקבל: פענוח ה-JSON וסידורו מחדש משנים את הבתים ושוברים את ההתאמה.
חתימה תקפה מוכיחה שאנחנו שלחנו את הגוף, לא שזו הפעם הראשונה שהוא נשלח. כדי למנוע שליחה חוזרת של משלוח שיורט, דחו כל משלוח שה-timestamp שלו ישן מ-5 דקות, וזכרו כל deliveryId שכבר טיפלתם בו כדי להתעלם מחזרה. שני הערכים נמצאים בתוך הגוף החתום, כך שאי אפשר לשנות אותם.
const crypto = require('crypto');
const express = require('express');
const app = express();
const SECRET = process.env.CRIMBO_WEBHOOK_SECRET;
if (!SECRET) throw new Error('CRIMBO_WEBHOOK_SECRET is not set');
const MAX_AGE_MS = 5 * 60 * 1000;
// express.raw keeps the body as bytes: the signature covers them exactly as sent.
app.post('/webhooks/crimbo', express.raw({ type: 'application/json', limit: '1mb' }), async (req, res) => {
if (!Buffer.isBuffer(req.body)) return res.status(400).end(); // not JSON: not from us
const expected = Buffer.from(
'sha256=' + crypto.createHmac('sha256', SECRET).update(req.body).digest('hex')
);
const received = Buffer.from(req.get('X-Webhook-Signature') || '');
if (received.length !== expected.length || !crypto.timingSafeEqual(received, expected)) {
return res.status(401).end();
}
const event = JSON.parse(req.body);
const ageMs = Date.now() - Date.parse(event.timestamp);
if (!(Math.abs(ageMs) <= MAX_AGE_MS)) {
return res.status(400).end(); // missing, too old or in the future: possibly replayed
}
// One atomic step, e.g. INSERT into a table with a unique deliveryId column.
// A separate "check, then save" lets two copies through at the same moment.
if (!(await recordDelivery(event.deliveryId))) {
return res.status(200).end(); // duplicate: acknowledge, do nothing
}
await enqueue(event); // your job queue; do the real work there
res.status(200).end(); // answer within 5 seconds
});import hashlib, hmac, json, os
from datetime import datetime, timedelta, timezone
from flask import Flask, request, abort
app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = 1024 * 1024
SECRET = os.environ["CRIMBO_WEBHOOK_SECRET"].encode()
MAX_AGE = timedelta(minutes=5)
@app.post("/webhooks/crimbo")
def crimbo_webhook():
body = request.get_data()
expected = b"sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest().encode()
received = request.headers.get("X-Webhook-Signature", "").encode()
if not hmac.compare_digest(received, expected):
abort(401)
try:
event = json.loads(body)
sent_at = datetime.fromisoformat(event["timestamp"].replace("Z", "+00:00"))
age = abs(datetime.now(timezone.utc) - sent_at)
except (ValueError, KeyError, TypeError, AttributeError):
abort(400) # malformed, or a timestamp without a timezone
if age > MAX_AGE:
abort(400) # too old or in the future: possibly replayed
# One atomic step, e.g. INSERT into a table with a unique deliveryId column.
if not record_delivery(event["deliveryId"]):
return "", 200 # duplicate: acknowledge, do nothing
enqueue(event) # your job queue; do the real work there
return "", 200 # answer within 5 secondsכל אירוע נשלח פעם אחת. כל תשובת 2xx בתוך 5 שניות נחשבת כמשלוח מוצלח. חריגה מהזמן, תשובה שאינה 2xx או כתובת לא זמינה נרשמות ככישלון בהיסטוריית המשלוחים, והאירוע לא נשלח שוב - לכן ענו מהר ובצעו את העבודה עצמה ברקע. גם הפניות (redirects) לא נעקבות: תשובת 3xx נחשבת כישלון, לכן רשמו את הכתובת הסופית.
אין הבטחה שהמשלוחים יגיעו לפי הסדר. השתמשו ב-timestamp כדי לדעת איזה שינוי חדש יותר, וב-deliveryId כדי לדלג על מה שכבר טיפלתם בו.
שמירת Webhook ו"שליחת אירוע בדיקה" שולחים שניהם נתונים סינתטיים המסומנים ב-data._test: true, עם אותן כותרות, תבנית וחתימה כמו אירוע אמיתי. התעלמו מהם בצד שלכם אם אינכם רוצים שורות בדיקה.
כדי לשלוח ישירות לשירות אחר כמו Monday או Notion, הגדירו ל-Webhook תבנית payload: ה-JSON שאתם רוצים שיישלח, עם מצייני מקום לערכים שלנו. {{path}} מכניס ערך כמחרוזת מוגנת, לשימוש בתוך מירכאות. {{{path}}} מכניס אותו כמו שהוא, למספרים, ערכים בוליאניים ואובייקטים שלמים. הנתיבים מתחילים מ-event, timestamp, businessId, deliveryId, data ו-changes.
{
"name": "{{data.title}}",
"priority": {{{data.priority}}},
"client_phone": "{{data.client.phoneNumber}}",
"source_event": "{{event}}",
"deliveryId": "{{deliveryId}}",
"timestamp": "{{timestamp}}"
}החתימה מחושבת על התבנית אחרי המילוי, כך שהאימות עובד אותו דבר עם תבנית או בלעדיה. השאירו את {{deliveryId}} ואת {{timestamp}} בתבנית, כמו בדוגמה: הכותרת X-Webhook-Delivery אינה חתומה, כך שבלעדיהם בגוף אי אפשר לבדוק שליחות חוזרות.
שגיאות מחזירות גוף JSON עם שדות error ו-code יציבים והודעת error קריאה. סטטוס ה-HTTP משקף את הקטגוריה.
{
"error": "Invalid or revoked API key.",
"code": "API_KEY_INVALID"
}| סטטוס | קוד | תיאור |
|---|---|---|
| 401 | API_KEY_MISSING | לא נשלחה כותרת X-API-Key. |
| 401 | API_KEY_INVALID | המפתח לא ידוע, בוטל או פגום. |
| 403 | API_KEY_SCOPE_MISSING | המפתח תקף אך חסרה לו ההרשאה שה-endpoint דורש. התשובה מציינת אותה ב-`required_scope`. |
| 400 | TEMPLATE_NAME_REQUIRED | template_name חסר או ריק. |
| 400 | LANGUAGE_REQUIRED | language חסר או ריק. |
| 400 | PHONE_NUMBER_REQUIRED | phone_number חסר או ריק. |
| 400 | PHONE_NUMBER_INVALID | לא ניתן לנרמל את מספר הטלפון לצורה תקפה. |
| 400 | PARAMETERS_INVALID | parameters סופק אך אינו מערך JSON. |
| 400 | HEADER_MEDIA_INVALID | header_media אינו אובייקט, ה-type שלו אינו image, video או document, או ש-url שלו אינו קישור https תקין. |
| 400 | BUTTON_PARAMETERS_INVALID | button_parameters אינו מערך של אובייקטים { index, value }, index מחוץ לטווח 0-9 או חוזר, value ריק, אינו מחרוזת, מספר או בוליאני, או ארוך מ-2000 תווים, או ש-type אינו "url" או "quick_reply". |
| 403 | CLIENT_BLOCKED | הנמען חסום על ידי העסק שלכם. |
| 424 | WA_NOT_CONNECTED | העסק שלכם טרם השלים את חיבור הוואטסאפ. |
| 400 | ACTION_TYPE_REQUIRED | actionType חסר או ריק בבקשת /send-action. |
| 400 | ACTION_TYPE_UNKNOWN | לא קיימת הגדרה פעילה ל-actionType הזה. השותף שלכם מוסיף אותה בעמוד השותף. |
| 400 | ACTION_FIELD_MISSING | שדה שהפעולה ממפה חסר או ריק בגוף הבקשה. התשובה מפרטת כל אחד מהם ב-`missing_fields`. |
| 400 | ACTION_FIELD_INVALID | שדה ממופה הגיע אך לא ניתן לשלוח אותו כמו שהוא - לדוגמה ערך ארוך ממה שוואטסאפ מקבלת. התשובה מפרטת כל אחד מהם ב-`invalid_fields` יחד עם הסיבה. |
| 400 | PARTNER_NOT_CONFIGURED | העסק שמאחורי מפתח ה-API הזה אינו מנוהל על ידי שותף, ולכן אין לו הגדרת פעולות. השתמשו ב-/send-template. |
| 400 | RECIPIENT_REQUIRED | recipient חסר או ריק בבקשת /send-action. |
| 400 | RECIPIENT_INVALID | לא ניתן לנרמל את מספר הנמען לצורה תקפה. |
| 400 | TEMPLATE_SEND_FAILED | Meta דחתה את השליחה. התשובה כוללת את קוד השגיאה של Meta (`meta_code`) ו-trace id (`meta_trace_id`) כשזמינים. |
| 400 | INVALID_PATH_PARAM | מזהה טבלה, מזהה שורה או מפתח עמודה בכתובת הורדת הקובץ אינם תקינים. |
| 400 | NOT_A_FILE_COLUMN | העמודה בכתובת הורדת הקובץ אינה עמודת קבצים. |
| 404 | ROW_NOT_FOUND | אין שורה כזו בטבלה הזו. |
| 404 | CELL_EMPTY | התא הזה לא מכיל קובץ. |
| 404 | FILE_UNAVAILABLE | הקובץ שהתא מצביע עליו כבר לא שמור. |
| 500 | FILE_LINK_FAILED | הקובץ קיים אך לא ניתן היה ליצור קישור הורדה. נסו שוב בעוד רגע. |
| 400 | TAGS_INVALID | tags חסר, אינו מערך, שאחד האיברים בו אינו מחרוזת לא ריקה, או שחרג מהמגבלות: עד 100 שמות בבקשה ועד 100 תווים לכל שם. |
| 404 | CLIENT_NOT_FOUND | אין בעסק שלכם לקוח עם מספר הטלפון הזה. קריאות התגיות לעולם לא יוצרות לקוחות. |
| 404 | TAG_NOT_FOUND | שם תגית אחד או יותר לא קיימים בעסק שלכם. שום דבר לא שונה, והתשובה מפרטת את השמות הלא מוכרים ב-`missing_tags`. |
| 500 | CLIENT_TAGS_FAILED | בקשת תגיות ללקוח נכשלה בצד שלנו. ייתכן שהשינוי הוחל וייתכן שלא. בטוח לנסות שוב, כי הוספה, החלפה והסרה הן פעולות אידמפוטנטיות. |