דילוג לתוכן
lychee

API

חיבור מערכות לתיבת הוואטסאפ העסקית, וחיבור עוזר AI משלכם דרך MCP.

26 פעולות26 כלי MCPREST על JSONMCP 2025-06-18

להתחיל

שלוש דקות: להנפיק מפתח בליצ׳י, בהגדרות, בלשונית API. אחר כך הקריאה הזו מחזירה את המספרים המחוברים לחשבון, וזו הדרך המהירה לוודא שהמפתח עובד.

בדיקה מהירה
curl https://app.lychee-ltd.com/api/wap/make-channels \
  -H "Authorization: Bearer lyc_live_..."

הכתובת הבסיסית היא https://app.lychee-ltd.com/api/wap. הכל JSON, הכל UTF-8, וכל תאריך הוא ISO-8601 ב-UTC.

אימות

כל קריאה נושאת מפתח. המפתח מוצג פעם אחת ונשמר מגובב, כך שגם לנו אין דרך לשחזר אותו. אם אבד, מנפיקים חדש ומבטלים את הישן.

Authorization: Bearer lyc_live_...

למפתח יש הרשאות, והן נאכפות ולא רק מוצגות: מפתח עם conversations:read בלבד מקבל 403 על שליחה.

הרשאהמה היא פותחת
conversations:readשיחות, צוות, מספרים, תבניות
conversations:writeשליחה, שיוך, הכנת אוטומציה
contacts:readכרטיסי לקוח ושדות
contacts:writeעדכון שם ושדות

כשבחירת פרופיל סוכן זמינה בהגדרות, אפשר ליצור מפתח לקריאה בלבד, או לקריאה והכנת טיוטות אוטומציה בלבד. שני הפרופילים אינם מאפשרים שליחה או הפעלת אוטומציות, גם בקריאה ישירה ל-API. פרסום טיוטה נשאר לאדם בליצ׳י. הרשאות המשתמש והערוצים ממשיכות להגביל את המפתח. מפתחות Make קיימים אינם משתנים. שומרים מפתח בצד השרת של החיבור, ולא בקישור, ב-iframe או בקוד שהדפדפן של הלקוח מקבל.

קריאה

שליפת מידע. לא משנות כלום.

list_channels

קריאה

מספרי הוואטסאפ המחוברים לחשבון, עם המזהה, השם והסוג של כל אחד. כל פרמטר channel_id בשאר הפעולות מגיע מכאן

GET/api/wap/make-channels
דורש conversations:read
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/make-channels`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

list_team

קריאה

אנשי הצוות בחשבון עם המזהה, השם והתפקיד של כל אחד. המזהה שמוחזר כאן הוא מה ש-assign_conversation מקבל

GET/api/wap/make-team
דורש conversations:read
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/make-team`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

list_templates

קריאה

התבניות שמטא אישרה. רק מאושרות חוזרות, כי רק בהן אפשר לפנות מחוץ לחלון 24 השעות

GET/api/wap/make-templates
דורש conversations:read
פרמטרים
channel_idstring
לסנן למספר אחד. בלעדיו, כל המספרים
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ channel_id: '...' })

const res = await fetch(`${BASE}/make-templates?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

search_conversations

קריאה

חיפוש שיחות לפי שם, שם שמור או טלפון. מוחזרות לפי סדר ההודעה האחרונה

GET/api/wap/make-conversations
דורש conversations:read
פרמטרים
searchstring
טקסט לחיפוש בשם או בטלפון
channel_idstring
לסנן למספר אחד
limitnumber
כמה להחזיר, 1 עד 200. ברירת מחדל 100
# search=דנה
curl -G \
  "https://app.lychee-ltd.com/api/wap/make-conversations" \
  --data-urlencode "search=דנה" \
  -d "limit=2" \
  -H "Authorization: Bearer lyc_live_..."
תשובה
[
  {
    "id": "8f21c4de-1b90-4a77-9c11-7d2e5b0a3f64",
    "channel_id": "32909401-63ba-4024-851f-59d106b9f1a2",
    "name": "דנה לוי",
    "phone": "972501234567",
    "last_msg_at": "2026-08-25T09:14:22.104Z",
    "unread": 2,
    "assignee_id": null
  }
]

read_conversation

קריאה

ההודעות של שיחה אחת, מהישנה לחדשה, בדפים. לקריאת הקשר לפני שעונים, להשלמה אחרי שהשרת שלכם היה למטה, ולייבוא היסטוריה. מחזירה גם את מצב חלון 24 השעות של אותה שיחה, ועם window_only רק אותו. מי שלח הודעה יוצאת מוחזר ב-sent_by_kind, והוא null כשאי אפשר לדעת: שליחה דרך ה-API לא משאירה סימן, וכך גם הודעות מלפני שהעמודה הזאת נוספה

GET/api/wap/read_conversation
דורש conversations:read
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. זו קריאה, ולכן איש קשר שאינו קיים אינו נוצר אלא מוחזר 404
channel_idstring
מאיזה מספר. נדרש כשמוסרים phone
sincestring
תאריך ISO. רק הודעות ממנו והלאה
cursorstring
ה-next_cursor של הדף הקודם. אטום בכוונה, ואין להרכיב אותו ביד
limitnumber
כמה הודעות בדף, 1 עד 200. ברירת מחדל 100. next_cursor הוא null בדף האחרון
window_onlyboolean
להחזיר רק את מצב חלון 24 השעות, בלי הודעות. למי שרק רוצה לדעת אם מותר לשלוח טקסט חופשי לפני שהוא מנסח אותו
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ contact_id: '...', phone: '...' })

const res = await fetch(`${BASE}/read_conversation?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

list_contact_fields

קריאה

השדות המותאמים שהוגדרו בחשבון, כולל key ו-type, כדי לדעת מה אפשר לעדכן ובאיזה מפתח. datetime הוא תאריך ושעה שניתן להשתמש בהם בצעד המתנה

GET/api/wap/make-contact-fields
דורש contacts:read
פרמטרים
channel_idstring
לסנן למספר אחד
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ channel_id: '...' })

const res = await fetch(`${BASE}/make-contact-fields?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

get_message

קריאה

מה קרה להודעה אחת: האם היא נמסרה, האם נכשלה ומה הסיבה. שליחה מחזירה ok כשוואטסאפ קיבלה את ההודעה, וזה לא אותו דבר כמו שהיא הגיעה. delivered ריק במספר סרוק, כי שם וואטסאפ לא מדווחת מסירה בכלל

GET/api/wap/message-get
דורש conversations:read
פרמטרים
message_idstring
המזהה שהשליחה החזירה
whatsapp_message_idstring
לחלופין, המזהה של וואטסאפ (wamid)
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ message_id: '...', whatsapp_message_id: '...' })

const res = await fetch(`${BASE}/message-get?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

get_message_media

קריאה

קישור הורדה לקובץ שהגיע בהודעה. הקישור חתום וקצר מועד, ואינו כתובת ציבורית: אין לשמור אותו ואין להעביר אותו הלאה. כשצריך שוב, מבקשים שוב. בתשובה: file_name הוא שם הקובץ שהשולח נתן למסמך, ו-null בכל סוג הודעה אחר וגם במסמכים שהתקבלו לפני 28.10.2026. הכיתוב שנכתב לצד הקובץ אינו שם הקובץ, והוא נמצא בשדה text של ההודעה

GET/api/wap/get_message_media
דורש conversations:read
פרמטרים
message_idstring
מזהה ההודעה בליצ׳י, מתוך האירוע או מ-get_message
whatsapp_message_idstring
מזהה ההודעה של מטא, wamid. אפשר במקום message_id
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ message_id: '...', whatsapp_message_id: '...' })

const res = await fetch(`${BASE}/get_message_media?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

list_contact_documents

קריאה

המסמכים של איש קשר, החדש ראשון, עם השם, הגודל, התאריך ומי העלה. מסמך שנמחק אינו מוחזר

GET/api/wap/list_contact_documents
דורש contacts:read
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי
channel_idstring
מאיזה מספר. נדרש כשמוסרים phone
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ contact_id: '...', phone: '...' })

const res = await fetch(`${BASE}/list_contact_documents?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

list_automations

קריאה

האוטומציות של מספר: שם, טריגר, מצב, ואם יש טיוטה שממתינה לפרסום

GET/api/wap/automation-list
דורש conversations:read
פרמטרים
channel_idstring
המספר
const BASE = 'https://app.lychee-ltd.com/api/wap'
const qs = new URLSearchParams({ channel_id: '...' })

const res = await fetch(`${BASE}/automation-list?${qs}`, {
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
  },
})
const data = await res.json()

get_automation

קריאה

אוטומציה אחת במלואה: הצעדים, הקישורים והטיוטה הממתינה. זה מה שקוראים לפני עדכון, כי עדכון מחליף את הכל

GET/api/wap/automation-read
דורש conversations:read
פרמטרים
idstring
מזהה האוטומציה
curl "https://app.lychee-ltd.com/api/wap/automation-read?id=ac8c2e1a-f5eb-4573-b0dd-3df171767498" \
  -H "Authorization: Bearer lyc_live_..."
תשובה
{
  "id": "ac8c2e1a-f5eb-4573-b0dd-3df171767498",
  "name": "מענה לשאלת מחיר",
  "trigger_type": "keyword",
  "enabled": false,
  "steps": [ ... ],
  "edges": [ ... ],
  "draft": null
}

עדכון

משנות נתונים בחשבון.

submit_template

עדכון

הגשת תבנית חדשה לאישור מטא. לא נשלחת לאף אחד: התבנית ממתינה לאישור, ואפשר להשתמש בה רק אחרי שהיא APPROVED ב-list_templates

POST/api/wap/make-submit-template
דורש conversations:write
פרמטרים
channel_idstring
המספר הרשמי שאליו התבנית מוגשת. תבנית שייכת לחשבון הוואטסאפ של המספר ולא עוברת בין מספרים
namestring
אותיות קטנות באנגלית, מספרים וקו תחתון בלבד. בלי רווחים ובלי עברית
categorystring
UTILITY לעדכון על עסקה או פגישה, MARKETING לתוכן פרסומי, AUTHENTICATION לקוד אימות. בחירה נכונה חוסכת כסף וגם נזק: מטא מגבילה כמה הודעות MARKETING אדם מקבל ופשוט לא מוסרת מעבר לזה
bodystring
גוף ההודעה, עד 1024 תווים. משתנים נכתבים {{1}}, {{2}} ברצף שמתחיל ב-1. אסור שמשתנה יהיה בתחילת ההודעה או בסופה
examplesarray
ערך דוגמה לכל משתנה, באותו סדר. חובה כשיש משתנים: מטא דוחה תבנית בלי דוגמה לכל אחד
languagestring
קוד שפה. ברירת מחדל he
headerstring
כותרת טקסט קבועה, עד 60 תווים, בלי משתנים
footerstring
כותרת תחתונה, עד 60 תווים
buttonsarray
כפתורים, עד 10 בסך הכול ועד 25 תווים בטקסט של כל אחד. כפתור תגובה מהירה נשלח כטקסט, למשל "אישור". כפתור קישור נשלח כאובייקט {type:"URL",text,url} ומותרים עד 2 כאלה. מעל 3 כפתורים, וואטסאפ מציג את שני הראשונים ועוד "הצגת כל האפשרויות" שפותח את כולם כרשימה. כתובת שהסוף שלה משתנה בכל שליחה נכתבת {{1}} בסוף ה-url ודורשת example עם סוף כתובת לדוגמה. מטא לא מדווחת על לחיצה בכפתור קישור, ולכן אוטומציה לא יכולה להסתעף עליה
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/make-submit-template`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    channel_id: '...',
    name: '...',
    category: '...',
  }),
})
const data = await res.json()

assign_conversation

עדכון

שיוך שיחה לאיש צוות, כדי שרק הוא יראה אותה ויטפל בה. מזהה איש הצוות מגיע מ-list_team

POST/api/wap/conversation-assign
דורש conversations:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
assignee_idstring
מזהה איש הצוות שיטפל בשיחה
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/conversation-assign`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

unassign_conversation

עדכון

הסרת השיוך משיחה, כדי שתחזור לתור הכללי ותהיה גלויה לכל הצוות. לא שולח כלום ללקוח

POST/api/wap/conversation-unassign
דורש conversations:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/conversation-unassign`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

update_contact_field

עדכון

עדכון שדות בכרטיס איש הקשר. המפתחות מגיעים מ-list_contact_fields

POST/api/wap/contact-fields-update
דורש contacts:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
fieldsobject
מיפוי של מפתח שדה לערך, למשל {"city":"תל אביב"}. לשדה datetime שולחים ISO 8601 עם אזור זמן, למשל 2026-09-16T14:00:00+03:00. ערך מקומי בלי אזור זמן מפורש נקרא לפי שעון ישראל
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/contact-fields-update`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

update_contact_name

עדכון

עדכון השם השמור של איש קשר. גובר על השם מפרופיל הוואטסאפ

POST/api/wap/contact-name-update
דורש contacts:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
namestring
השם שיוצג לצוות
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/contact-name-update`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

manage_contact_tag

עדכון

הוספה או הסרה של תגית אחת אצל איש קשר. תגית שנוספת מפעילה אוטומציות עם הטריגר "נוספה תגית", בדיוק כמו תיוג מהמסך, והסרה אינה מפעילה כלום. בתשובה: רשימת התגיות המעודכנת ו-changed, שאומר אם משהו השתנה בכלל. הוספת תגית שכבר קיימת והסרת תגית שאינה שם מצליחות ואינן משנות דבר

POST/api/wap/manage_contact_tag
דורש contacts:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
operationstring
add להוספת התגית, remove להסרתה
tagstring
שם התגית, בדיוק כפי שהוא מופיע בליצ׳י. תגית חדשה נוצרת מעצם התיוג, ואין צורך להגדיר אותה קודם
curl -X POST \
  https://app.lychee-ltd.com/api/wap/manage_contact_tag \
  -H "Authorization: Bearer lyc_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: lead-8841" \
  -d '{
    "phone": "972501234567",
    "channel_id": "32909401-63ba-4024-851f-59d106b9f1a2",
    "operation": "add",
    "tag": "lead-october"
  }'
תשובה
{
  "ok": true,
  "contact_id": "8f21c4de-1b90-4a77-9c11-7d2e5b0a3f64",
  "contact_created": false,
  "phone": "0501234567",
  "operation": "add",
  "tag": "lead-october",
  "changed": true,
  "tags": ["lead-october"]
}

create_contact_field

עדכון

יצירת שדה מותאם חדש בכרטיסי אנשי הקשר. הפעולה יוצרת את הגדרת השדה, לא ערך אצל איש קשר מסוים

POST/api/wap/create_contact_field
דורש contacts:write
פרמטרים
channel_idstring
המספר שבו השדה יהיה זמין
labelstring
השם שיוצג למשתמשים, למשל תאריך שיחה
keystring
מפתח קבוע לאינטגרציות. אם לא נשלח, ליצ׳י ייצור אותו מהשם
typestring
סוג השדה: text, number, date, datetime, url, select או multiselect. datetime הוא תאריך ושעה. ברירת המחדל text
optionsarray
האפשרויות המותרות בשדה select או multiselect
sortnumber
מיקום השדה בכרטיס. ברירת המחדל 0
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/create_contact_field`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    channel_id: '...',
    label: '...',
    key: '...',
  }),
})
const data = await res.json()

upload_contact_document

עדכון

שמירת מסמך בכרטיס איש הקשר. מקבל קישור לקובץ או את הקובץ עצמו, ושומר אותו באחסון פרטי. לא נשלח לאף אחד

POST/api/wap/upload_contact_document
דורש contacts:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
file_namestring
שם הקובץ כפי שיוצג, כולל סיומת. שם בעברית נשמר בעברית
urlstring
כתובת שממנה נוריד את הקובץ. אפשר במקומה file_base64
file_base64string
תוכן הקובץ מקודד base64, כשאין כתובת להורדה ממנה
mimestring
סוג הקובץ, למשל application/pdf. בלעדיו ננחש לפי מה שהשרת אמר
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/upload_contact_document`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

delete_contact_document

עדכון

מחיקת מסמך מכרטיס איש הקשר. הקובץ עצמו נמחק מהאחסון ואי אפשר לשחזר אותו. נשמר רישום של מי מחק ומתי

POST/api/wap/delete_contact_document
דורש contacts:write
פרמטרים
idstring
מזהה המסמך, מתוך list_contact_documents
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/delete_contact_document`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    id: '...',
  }),
})
const data = await res.json()

manage_incoming_message_trigger

עדכון

חיבור או הסרה של טריגר Make על מספר רשמי. בברירת מחדל הטריגר רץ פעם אחת על כל הודעה נכנסת. עם event שהוא contact.opted_out הוא רץ כשאיש קשר מבקש להסיר את עצמו מהתפוצה, ומקבל את מזהה איש הקשר, השם, הטלפון, המספר והזמן, בלי הטקסט שהאדם כתב. טריגר ההסרה אינו מסיר אף אחד ואינו שולח הודעה: ליצ׳י עונה ומסמנת בעצמה, וזה הדיווח למערכות אחרות

POST/api/wap/make-incoming-message-trigger
דורש conversations:read
פרמטרים
operationstring
attach לחיבור או detach להסרה
eventstring
message.received להודעה נכנסת, שזו ברירת המחדל, או contact.opted_out לבקשת הסרה. בהסרה צריך לציין את אותו אירוע שאיתו חוברה
channel_idstring
המספר הרשמי לצפייה. נדרש בחיבור
make_webhook_idstring
מזהה ה-webhook ש-Make יצר. נדרש בחיבור
target_urlstring
כתובת ה-webhook הייעודית של Make. נדרשת בחיבור
idstring
מזהה המנוי שהוחזר בחיבור. נדרש בהסרה
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/make-incoming-message-trigger`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    operation: '...',
    event: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

שליחה

יוצאות החוצה אל אדם אמיתי. מוגבלות בקצב.

send_message

שליחה

שליחת הודעת טקסט אחת לאיש קשר אחד. עובדת רק בתוך חלון 24 השעות, כלומר רק אם הוא כתב לאחרונה. בתשובה שני מזהים, כל אחד בשני שמות: message_id (וגם messageId) הוא ההודעה בליצ׳י, ו-whatsapp_message_id (וגם waId) הוא המזהה של מטא, והוא זה שמשווים אליו reply_to_whatsapp_message_id. שני השמות של כל מזהה הם אותו ערך

POST/api/wap/make-send-text
דורש conversations:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
textstring
תוכן ההודעה
reply_to_whatsapp_message_idstring
לשלוח כתשובה להודעה מסוימת, לפי מזהה מטא. הנמען רואה את ההודעה המצוטטת, והתשובה שלו תחזור עם reply_to_whatsapp_message_id שמצביע לכאן. זו הדרך לקשר תשובת כפתור למסמך מסוים
buttonsarray
עד 10 כפתורי תשובה, כל אחד {text, automation_id}. עד 20 תווים לכפתור. automation_id לא חובה: לחיצה על כפתור שיש לו אוטומציה מריצה אותה, ולחיצה על כפתור אחר מגיעה כהודעה רגילה. עם כפתורים ההודעה מוגבלת ל-1024 תווים
list_buttonstring
הטקסט של הכפתור שפותח את הרשימה, כשיש יותר מ-3 כפתורים
curl -X POST \
  https://app.lychee-ltd.com/api/wap/make-send-text \
  -H "Authorization: Bearer lyc_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-8841" \
  -d '{
    "phone": "972501234567",
    "channel_id": "32909401-63ba-4024-851f-59d106b9f1a2",
    "text": "ההזמנה יצאה אליך"
  }'
תשובה
{
  "ok": true,
  "message_id": "0c6f1b52-4a2d-4d1e-9f30-6b1c7a2e5d84",
  "whatsapp_message_id": "wamid.HBgMOTcyNTAxMjM0NTY3FQIAERgSMUY0M0E5...",
  "messageId": "0c6f1b52-4a2d-4d1e-9f30-6b1c7a2e5d84",
  "waId": "wamid.HBgMOTcyNTAxMjM0NTY3FQIAERgSMUY0M0E5...",
  "contact_created": false
}

send_template

שליחה

שליחת תבנית מאושרת לאיש קשר אחד. הדרך היחידה לפנות למי שלא כתב ב-24 השעות האחרונות. בתשובה שני מזהים, כל אחד בשני שמות, כמו ב-send_message: whatsapp_message_id (וגם waId) הוא המזהה של מטא ואליו משווים reply_to_whatsapp_message_id

POST/api/wap/make-send-template
דורש conversations:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
template_namestring
שם התבנית כפי שהוא ב-list_templates
languagestring
קוד השפה של התבנית, ברירת מחדל he
body_variablesarray
הערכים למשתני התבנית, לפי הסדר
reply_to_whatsapp_message_idstring
לשלוח כתשובה להודעה מסוימת, לפי מזהה מטא
button_url_valuesarray
לתבנית עם כפתור קישור שהכתובת שלו מסתיימת ב-{{1}}: סוף הכתובת לכל כפתור כזה, לפי הסדר. בלי רווחים. נוסף לסוף הכתובת שאושרה
button_automationsarray
אוטומציה לכפתור של התבנית, כל פריט {button, automation_id}. button הוא הטקסט של כפתור תשובה מהירה בתבנית. לחיצה עליו מריצה את האוטומציה, וכפתור בלי אוטומציה מגיע כהודעה רגילה
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/make-send-template`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

run_automation

שליחה

הרצת אוטומציה קיימת על איש קשר אחד. האוטומציה מחליטה בעצמה מה לשלוח לפי השדות של אותו איש קשר, ולכן זו שליחה לאדם אמיתי לכל דבר

POST/api/wap/run-automation
דורש conversations:write
פרמטרים
contact_idstring
מזהה איש הקשר. אפשר במקומו phone
phonestring
מספר טלפון בפורמט בינלאומי. אם אין איש קשר כזה, הוא ייווצר
channel_idstring
מאיזה מספר לפעול. נדרש כשמוסרים phone
idstring
מזהה האוטומציה שתרוץ
const BASE = 'https://app.lychee-ltd.com/api/wap'

const res = await fetch(`${BASE}/run-automation`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.LYCHEE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    contact_id: '...',
    phone: '...',
    channel_id: '...',
  }),
})
const data = await res.json()

טיוטה

מכינות משהו שממתין לאישור אדם.

draft_automation

טיוטה לאישור

הכנת אוטומציה חדשה או עדכון טיוטה של אוטומציה קיימת. אוטומציה חדשה נוצרת כבויה, ואוטומציה פעילה ממשיכה לרוץ מהגרסה שפורסמה עד שאדם מפרסם את הטיוטה

POST/api/wap/automation-draft
דורש conversations:write
פרסום או הפעלה במסך האוטומציות בליצ׳י
פרמטרים
idstring
מזהה אוטומציה קיימת שרוצים לעדכן כטיוטה. בלי id נוצרת אוטומציה חדשה
channel_idstring
על איזה מספר האוטומציה פועלת
namestring
שם שיזהה אותה במסך
trigger_typestring
מה מפעיל אותה: keyword, first_message, any_message, field_changed, tag_added, contact_created, daily, manual, webhook
trigger_configobject
הגדרות הטריגר. ב-daily בוחרים scope: contacts להרצה לכל איש קשר, עם tag אופציונלי, או once להרצה כללית אחת. weekdays הם ימי השבוע 0 עד 6, מראשון עד שבת. לדוגמה {"time":"10:00","timezone":"Asia/Jerusalem","scope":"once","weekdays":[0,1,2,3,4]}
stepsarray
הצעדים. לכל צעד key ייחודי (אפשר גם id; בלי שניהם נוצר key אוטומטי) ו-kind: send_text, send_template, send_buttons, ask_field, set_field, add_tag, remove_tag, create_task, wait, http_request, ai_agent, condition, stop_if_tag, handoff, stop. בהמתנה קבועה שולחים seconds. להמתנה לפי שדה תאריך ושעה שולחים wait_mode: "field", wait_field_key ואת wait_offset_seconds: מספר שלילי לפני המועד, חיובי אחריו, או 0 במועד עצמו. כדי לדחות שבת וחגי ישראל ליום המותר הבא שולחים wait_calendar_policy: "israel_rest_days". kind לא מוכר נדחה עם רשימת הסוגים. כפתורים ב-send_buttons הם מחרוזות, עד 10, עד 20 תווים. עד 3 נשלחים ככפתורים, ומ-4 כרשימה שנפתחת מכפתור אחד, שהטקסט שלו ב-list_button (עד 20 תווים, ברירת מחדל "בחירת אפשרות")
edgesarray
הקישורים בין הצעדים: [{"from":"a","to":"b","port":"next"}]. בלי edges הצעדים רצים לפי הסדר. port קובע את ההסתעפות: next (ברירת מחדל) להמשך רגיל; yes ו-no ב-condition וב-http_request; btn:<טקסט הכפתור> או else ב-send_buttons; text, timeout ו-invalid ב-ask_field; intent:<מפתח מטרה>, other ו-error ב-ai_agent. קישור ליציאה שלא קיימת נשמר עם אזהרה ולא ירוץ. עדכון מחליף את כל הצעדים והקישורים, אין מיזוג: קוראים קודם עם get_automation, משנים, ושולחים הכל
curl -X POST \
  https://app.lychee-ltd.com/api/wap/automation-draft \
  -H "Authorization: Bearer lyc_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "32909401-63ba-4024-851f-59d106b9f1a2",
    "name": "מענה לשאלת מחיר",
    "trigger_type": "keyword",
    "trigger_config": { "keywords": ["מחיר"] },
    "steps": [
      { "key": "ask", "kind": "send_buttons", "text": "על מה תרצו לשמוע?", "buttons": ["מחירים", "מועדים"] },
      { "key": "prices", "kind": "send_text", "text": "המחירון אצלנו באתר" },
      { "key": "dates", "kind": "send_text", "text": "המחזור הבא נפתח בנובמבר" }
    ],
    "edges": [
      { "from": "ask", "to": "prices", "port": "btn:מחירים" },
      { "from": "ask", "to": "dates", "port": "btn:מועדים" }
    ]
  }'
תשובה
{
  "id": "ac8c2e1a-f5eb-4573-b0dd-3df171767498",
  "enabled": false,
  "status": "draft",
  "step_count": 3,
  "steps": [ ...כפי שנשמרו, עם x ו-y לקנבס... ],
  "edges": [ ...כפי שנשמרו... ],
  "warnings": []
}

שגיאות

קודמה קרה
401המפתח חסר, שגוי, פג או בוטל
403למפתח אין את ההרשאה לפעולה הזו
404הפעולה או המשאב לא נמצאו
503תקלה זמנית. אפשר לנסות שוב

הגוף תמיד באותו מבנה:

{ "error": "אין הרשאה לשלוח מהמספר הזה" }

בפעולות שמשנות משהו שולחים Idempotency-Key. מפתח API חדש דורש אותו, ובלעדיו התשובה היא 428. אותו מפתח לא יתבצע פעמיים, וזה מה שמונע שליחה כפולה כשאוטומציה מנסה שוב אחרי שגיאת רשת.

MCP

חיבור עוזר AI משלכם לתיבה.

ההסקה רצה אצלכם, על המנוי שלכם, והשיחות לא עוברות דרך מודל שאנחנו מפעילים. המפתח שאתם שמים כאן הוא המפתח האישי שלכם, והכלים עובדים בדיוק עם ההרשאות, הערוצים והשיחות שיש לו.

חיבור

הכלי נגיש ב-https://app.lychee-ltd.com/api/mcp מעל HTTP, עם המפתח בכותרת Authorization. בוחרים את הלקוח שאתם עובדים בו:

claude mcp add lychee \
  --transport http \
  --url https://app.lychee-ltd.com/api/mcp \
  --header "Authorization: Bearer lyc_live_..."
פרומפט לעוזר

שלושה דברים בליצ׳י לא מובנים מאליהם לעוזר שרק רואה רשימת כלים, והם בדיוק אלה שגורמים לו לייצר קריאות שנכשלות או פעולות שלא רציתם. מדביקים את זה בהוראות המערכת שלו:

system prompt
יש לך גישה לתיבת הוואטסאפ העסקית של העסק דרך הכלים של lychee.
שלושה כללים שחלים על כל שימוש בהם:

1. חלון 24 השעות. אפשר לשלוח הודעה חופשית רק למי שכתב לעסק
   ב-24 השעות האחרונות. אחרי זה אפשר לפתוח שיחה רק בתבנית
   מאושרת, עם שם התבנית והמשתנים שלה. אם אין תבנית מתאימה,
   תגיד את זה במקום לנסות לשלוח טקסט חופשי.

2. אוטומציה נוצרת כבויה, תמיד. אין פרמטר שמדליק אותה ואין
   כלי שמדליק אותה. אחרי שיצרת אחת, תגיד לאדם שהיא ממתינה
   להדלקה במסך האוטומציות של lychee.

3. לכל פעולה שכותבת (שליחה, יצירה, עדכון) תעביר idempotency_key
   קבוע משלך. אם קריאה נכשלה ואתה חוזר עליה עם אותו מזהה, היא
   לא תתבצע פעמיים. בלי מזהה, כל נסיון חוזר הוא שליחה נוספת.

שליחה אחד על אחד מותרת ומוגבלת בקצב. שליחה לקבוצת אנשים נעשית
דרך קמפיין במסך של lychee, לא דרך הכלים האלה.
לפני שליחה לאדם, כדאי לקרוא את השיחה שלו כדי לא לחזור על מה
שכבר נאמר לו.
הכלים

26 כלים, תחת אותם שמות ציבוריים ואותן הרשאות של המפתח.

כלימה הוא עושה
list_channelsמספרי הוואטסאפ המחוברים לחשבון, עם המזהה, השם והסוג של כל אחד. כל פרמטר channel_id בשאר הפעולות מגיע מכאן
list_teamאנשי הצוות בחשבון עם המזהה, השם והתפקיד של כל אחד. המזהה שמוחזר כאן הוא מה ש-assign_conversation מקבל
list_templatesהתבניות שמטא אישרה. רק מאושרות חוזרות, כי רק בהן אפשר לפנות מחוץ לחלון 24 השעות
submit_templateהגשת תבנית חדשה לאישור מטא. לא נשלחת לאף אחד: התבנית ממתינה לאישור, ואפשר להשתמש בה רק אחרי שהיא APPROVED ב-list_templates
search_conversationsחיפוש שיחות לפי שם, שם שמור או טלפון. מוחזרות לפי סדר ההודעה האחרונה
read_conversationההודעות של שיחה אחת, מהישנה לחדשה, בדפים. לקריאת הקשר לפני שעונים, להשלמה אחרי שהשרת שלכם היה למטה, ולייבוא היסטוריה. מחזירה גם את מצב חלון 24 השעות של אותה שיחה, ועם window_only רק אותו. מי שלח הודעה יוצאת מוחזר ב-sent_by_kind, והוא null כשאי אפשר לדעת: שליחה דרך ה-API לא משאירה סימן, וכך גם הודעות מלפני שהעמודה הזאת נוספה
list_contact_fieldsהשדות המותאמים שהוגדרו בחשבון, כולל key ו-type, כדי לדעת מה אפשר לעדכן ובאיזה מפתח. datetime הוא תאריך ושעה שניתן להשתמש בהם בצעד המתנה
get_messageמה קרה להודעה אחת: האם היא נמסרה, האם נכשלה ומה הסיבה. שליחה מחזירה ok כשוואטסאפ קיבלה את ההודעה, וזה לא אותו דבר כמו שהיא הגיעה. delivered ריק במספר סרוק, כי שם וואטסאפ לא מדווחת מסירה בכלל
assign_conversationשיוך שיחה לאיש צוות, כדי שרק הוא יראה אותה ויטפל בה. מזהה איש הצוות מגיע מ-list_team
unassign_conversationהסרת השיוך משיחה, כדי שתחזור לתור הכללי ותהיה גלויה לכל הצוות. לא שולח כלום ללקוח
update_contact_fieldעדכון שדות בכרטיס איש הקשר. המפתחות מגיעים מ-list_contact_fields
update_contact_nameעדכון השם השמור של איש קשר. גובר על השם מפרופיל הוואטסאפ
manage_contact_tagהוספה או הסרה של תגית אחת אצל איש קשר. תגית שנוספת מפעילה אוטומציות עם הטריגר "נוספה תגית", בדיוק כמו תיוג מהמסך, והסרה אינה מפעילה כלום. בתשובה: רשימת התגיות המעודכנת ו-changed, שאומר אם משהו השתנה בכלל. הוספת תגית שכבר קיימת והסרת תגית שאינה שם מצליחות ואינן משנות דבר
create_contact_fieldיצירת שדה מותאם חדש בכרטיסי אנשי הקשר. הפעולה יוצרת את הגדרת השדה, לא ערך אצל איש קשר מסוים
get_message_mediaקישור הורדה לקובץ שהגיע בהודעה. הקישור חתום וקצר מועד, ואינו כתובת ציבורית: אין לשמור אותו ואין להעביר אותו הלאה. כשצריך שוב, מבקשים שוב. בתשובה: file_name הוא שם הקובץ שהשולח נתן למסמך, ו-null בכל סוג הודעה אחר וגם במסמכים שהתקבלו לפני 28.10.2026. הכיתוב שנכתב לצד הקובץ אינו שם הקובץ, והוא נמצא בשדה text של ההודעה
upload_contact_documentשמירת מסמך בכרטיס איש הקשר. מקבל קישור לקובץ או את הקובץ עצמו, ושומר אותו באחסון פרטי. לא נשלח לאף אחד
list_contact_documentsהמסמכים של איש קשר, החדש ראשון, עם השם, הגודל, התאריך ומי העלה. מסמך שנמחק אינו מוחזר
contact_document_linkקישור הורדה למסמך אחד. הקישור קצר מועד בכוונה ואינו כתובת ציבורית, ולכן אין לשמור אותו ואין להעביר אותו הלאה
delete_contact_documentמחיקת מסמך מכרטיס איש הקשר. הקובץ עצמו נמחק מהאחסון ואי אפשר לשחזר אותו. נשמר רישום של מי מחק ומתי
manage_incoming_message_triggerחיבור או הסרה של טריגר Make על מספר רשמי. בברירת מחדל הטריגר רץ פעם אחת על כל הודעה נכנסת. עם event שהוא contact.opted_out הוא רץ כשאיש קשר מבקש להסיר את עצמו מהתפוצה, ומקבל את מזהה איש הקשר, השם, הטלפון, המספר והזמן, בלי הטקסט שהאדם כתב. טריגר ההסרה אינו מסיר אף אחד ואינו שולח הודעה: ליצ׳י עונה ומסמנת בעצמה, וזה הדיווח למערכות אחרות
send_messageשליחת הודעת טקסט אחת לאיש קשר אחד. עובדת רק בתוך חלון 24 השעות, כלומר רק אם הוא כתב לאחרונה. בתשובה שני מזהים, כל אחד בשני שמות: message_id (וגם messageId) הוא ההודעה בליצ׳י, ו-whatsapp_message_id (וגם waId) הוא המזהה של מטא, והוא זה שמשווים אליו reply_to_whatsapp_message_id. שני השמות של כל מזהה הם אותו ערך שולח הודעה לאדם אמיתי. כפוף למגבלת קצב, ואי אפשר לבטל אחרי השליחה.
send_templateשליחת תבנית מאושרת לאיש קשר אחד. הדרך היחידה לפנות למי שלא כתב ב-24 השעות האחרונות. בתשובה שני מזהים, כל אחד בשני שמות, כמו ב-send_message: whatsapp_message_id (וגם waId) הוא המזהה של מטא ואליו משווים reply_to_whatsapp_message_id שולח הודעה לאדם אמיתי. כפוף למגבלת קצב, ואי אפשר לבטל אחרי השליחה.
run_automationהרצת אוטומציה קיימת על איש קשר אחד. האוטומציה מחליטה בעצמה מה לשלוח לפי השדות של אותו איש קשר, ולכן זו שליחה לאדם אמיתי לכל דבר שולח הודעה לאדם אמיתי. כפוף למגבלת קצב, ואי אפשר לבטל אחרי השליחה.
draft_automationהכנת אוטומציה חדשה או עדכון טיוטה של אוטומציה קיימת. אוטומציה חדשה נוצרת כבויה, ואוטומציה פעילה ממשיכה לרוץ מהגרסה שפורסמה עד שאדם מפרסם את הטיוטה לא מבוצע. נשמר וממתין לפרסום או הפעלה במסך האוטומציות בליצ׳י. צריך לומר ללקוח מה לאשר.
list_automationsהאוטומציות של מספר: שם, טריגר, מצב, ואם יש טיוטה שממתינה לפרסום
get_automationאוטומציה אחת במלואה: הצעדים, הקישורים והטיוטה הממתינה. זה מה שקוראים לפני עדכון, כי עדכון מחליף את הכל
שליחה אחד על אחד מותרת ומוגבלת בקצב. הכנת אוטומציה יוצרת אותה כבויה, ואין פרמטר שמדליק אותה: ההדלקה נעשית במסך של ליצ׳י בלבד.
פרוטוקול MCP 2025-06-18