نشان lemonailemonai شروع ۳۰ روز رایگان
در همان پلن CRM، بدون هزینهٔ جدا، از ماه رایگان

API و وب‌هوک lemonai

سایت، اپ یا CRM خودتان را به نوبت دهی و پرونده‌های lemonai وصل کنید. وقت آزاد را بخوانید، نوبت بگیرید و لغو کنید، و هر نوبت تازه یا لید ربات دایرکت را همان لحظه در سیستم خودتان بگیرید. اگر CRM دیگری دارید و فقط ربات دایرکت ما را می‌خواهید، لیدها با وب‌هوک به همان CRM می‌رود.

شروع در سه قدم

۱. در پنل کلینیک به تنظیمات ← ربات و اتصال‌ها ← API و وب‌هوک بروید و «کلید تازه» بسازید. این کار فقط از حساب صاحب کلینیک ممکن است.

۲. کلید فقط همان یک بار نشان داده می‌شود. آن را در سرور خودتان نگه دارید و با هر درخواست در هدر Authorization بفرستید.

۳. همهٔ نشانی‌ها زیر https://api.lemonai.ir/v1 هستند. پاسخ همیشه JSON است: موفق {"ok":true,"data":…} و ناموفق {"ok":false,"error":"…"} با متن فارسی.

کلید را هرگز داخل کد صفحهٔ سایت (سمت مرورگر) نگذارید. هر کسی که صفحه را باز کند کلید را می‌بیند. API فقط برای ارتباط سرور به سرور است و هدر CORS نمی‌دهد. اگر کلید لو رفت، همان لحظه از پنل باطلش کنید.

کلید و دسترسی

هر کلید فقط به دادهٔ همان کلینیکی می‌رسد که آن را ساخته. ابطال در همان لحظه اثر می‌کند. سرور خود کلید را نگه نمی‌دارد، فقط اثر انگشتش را؛ پس کلید گم‌شده بازیابی نمی‌شود و باید کلید تازه بسازید.

Authorization: Bearer lai_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
دسترسیچه کاری را باز می‌کند
readخواندن مشخصات کلینیک، لاین‌ها، خدمات، پرسنل نوبت‌پذیر و وقت آزاد
bookثبت، لغو و جابه‌جایی نوبت، و دیدن نوبت‌ها با نام و شمارهٔ مراجع
patientsجست‌وجو و ساخت پرونده
sensitiveکد ملی و یادداشت پرونده؛ فقط همراه patients و فقط اگر صریحا تیک بخورد

قواعد نوبت: همان قواعد صفحهٔ نوبت دهی کلینیک

نوبتی که از API می‌آید از همان مسیری رد می‌شود که نوبت صفحهٔ آنلاین کلینیک. پس API هیچ میانبری ندارد:

  • ساعت کار کلینیک و ساعت کار هر لاین، و مهلت پیش از نوبت که کلینیک تعیین کرده
  • فقط خدمت‌هایی که در تنظیمات نوبت دهی برای نوبت آنلاین تیک خورده‌اند (فیلد bookable در فهرست خدمات)
  • وقت‌هایی که منشی بسته (مرخصی، جلسه) و سقف نوبت هم‌زمان هر لاین و هر خدمت
  • سقف روزانهٔ نوبت آنلاین برای هر شماره، و پیامک «نوبت ثبت شد» با الگوی خود کلینیک
  • نوبت در همان تقویم منشی می‌نشیند و نشان «آنلاین» با کانال api می‌گیرد

همهٔ زمان‌ها به وقت تهران هستند. تاریخ را هم میلادی (2026-10-12) و هم شمسی (۱۴۰۵/۰۷/۲۰) می‌پذیریم، با رقم فارسی یا لاتین. ساعت به شکل 10:30.

وضعیت نوبت یکی از این پنج است: booked ثبت‌شده، done انجام شد، canceled لغو، moved جابه‌جاشده، noshow نیامد.

یک شماره، چند نفر: شماره کلید جست‌وجوست نه هویت (مثلا دو خواهر با یک گوشی). اگر شماره پرونده دارد و نام فرستاده‌شده با آن نمی‌خواند، پاسخ 409 با code: "choose_patient" و فهرست پرونده‌ها برمی‌گردد. درخواست را با patient_id یا "new_person": true دوباره بفرستید.

اندپوینت‌ها

متد و مسیردسترسیکار
GET /v1/clinicreadنام، هندل، نشانی صفحهٔ نوبت، امروز به وقت تهران، روشن بودن نوبت دهی
GET /v1/linesreadلاین‌های کلینیک
GET /v1/servicesreadخدمات با لاین، مدت، و bookable: online یا direct (فقط تلفنی) یا off
GET /v1/staff?service_id=readپرسنل نوبت‌پذیر، فقط نام و شناسه
GET /v1/slots?date=&service_id=readوقت‌های آزاد یک روز برای یک خدمت
GET /v1/appointments?from=&to=&phone=bookنوبت‌های یک بازه (حداکثر ۶۲ روز)، با فیلتر اختیاری شماره
GET /v1/appointments/{id}bookیک نوبت
POST /v1/appointmentsbookثبت نوبت: service_id، date، time، phone، name، و اختیاری patient_id، new_person، note
POST /v1/appointments/{id}/movebookجابه‌جایی: date و time تازه؛ اگر وقت پر باشد نوبت دست نمی‌خورد
POST /v1/appointments/{id}/cancelbookلغو، فقط نوبت ثبت‌شده و فقط پیش از ساعت خود نوبت
GET /v1/patients?phone= یا ?q=patientsجست‌وجوی پرونده با شماره، یا با نام و شمارهٔ پرونده
GET /v1/patients/{id}patientsیک پرونده
POST /v1/patientspatientsساخت پرونده: name، phone، sex، birth_date؛ شمارهٔ تکراری 409 می‌دهد مگر "confirm_new": true

نمونه

وقت آزاد یک روز

curl -H "Authorization: Bearer $LEMONAI_KEY" \
  "https://api.lemonai.ir/v1/slots?date=2026-10-12&service_id=12"

# {"ok":true,"data":{"date":"2026-10-12","booking_enabled":true,
#   "rows":[{"time":"10:00"},{"time":"10:30"},{"time":"11:00"}]}}

ثبت نوبت

curl -X POST https://api.lemonai.ir/v1/appointments \
  -H "Authorization: Bearer $LEMONAI_KEY" -H "Content-Type: application/json" \
  -d '{"service_id":12,"date":"2026-10-12","time":"10:30","phone":"09121234567","name":"مریم رضایی"}'

# 201 {"ok":true,"data":{"created":true,"appointment":{"id":845,"status":"booked",
#   "start_at":"2026-10-12T10:30","date_jalali":"۱۴۰۵/۰۷/۲۰","time":"۱۰:۳۰",
#   "service":"لیزر صورت","channel":"api","client":{"patient_id":311,"name":"مریم رضایی",
#   "phone":"09121234567"}}}}
# 409 {"ok":false,"error":"این وقت همین الان پر شد؛ وقت دیگری انتخاب کنید"}

خطاها و سقف‌ها

کدیعنی
400ورودی ناقص یا نامعتبر (تاریخ، ساعت، شماره)
401کلید نیست، اشتباه است یا باطل شده
403کلید این دسترسی را ندارد، یا ماژول CRM برای کلینیک خاموش است
404چنین نوبت، پرونده یا مسیری در این کلینیک نیست
409وقت پر است، خدمت آنلاین نوبت نمی‌گیرد، نوبت دیگر قابل لغو نیست، یا choose_patient
429از سقف گذشتید؛ هدر Retry-After می‌گوید چند ثانیه صبر کنید

سقف هر کلید: ۱۲۰ درخواست و ۳۰ نوشتن در دقیقه. هر کلینیک روزانه تا ۲۰۰ نوبت از API می‌گیرد. اگر بیشتر لازم دارید در واتساپ بگویید.

وب‌هوک: خبر خودکار به سیستم شما

در همان صفحهٔ تنظیمات «نشانی تازه» بزنید، نشانی https:// سرور خودتان را بدهید و رویدادها را انتخاب کنید. یک راز امضا می‌گیرید که فقط همان بار نشان داده می‌شود. دکمهٔ «ارسال آزمایشی» یک رویداد ping می‌فرستد و نتیجهٔ هر ارسال در همان کارت دیده می‌شود.

رویدادکی می‌رسد
appointment.createdهر نوبت تازه: از منشی، صفحهٔ آنلاین، ربات یا API
appointment.canceledلغو نوبت
appointment.movedعوض شدن ساعت نوبت
appointment.doneمنشی نوبت را «انجام شد» زد
appointment.noshowمنشی نوبت را «نیامد» زد
lead.createdربات دایرکت اینستاگرام گفتگو را به آدم سپرد و مراجع شماره داد یا نوبت خواست

شکل درخواست

POST https://crm.example.com/lemonai
Content-Type: application/json; charset=utf-8
X-Lemonai-Event: appointment.created
X-Lemonai-Event-Id: evt_5355d7892e9979e44193a147
X-Lemonai-Signature: sha256=8c1f…

{"id":"evt_5355d7892e9979e44193a147","event":"appointment.created",
 "created_at":"2026-10-07T11:13:43","clinic":"my-clinic",
 "data":{"appointment":{"id":845,"status":"booked","start_at":"2026-10-12T10:30",
   "date_jalali":"۱۴۰۵/۰۷/۲۰","time":"۱۰:۳۰","duration_min":30,"service":"لیزر صورت",
   "line":"لیزر","staff":null,"source":"online","channel":"api"},
  "client":{"patient_id":311,"name":"مریم رضایی","phone":"09121234567"}}}

# lead.created:
# "data":{"lead":{"id":17,"channel":"instagram","created_at":"…","service":"بوتاکس",
#   "time":null,"summary":"برای بوتاکس وقت می‌خوام 0912…","reason":"…"},
#  "client":{"name":null,"phone":"09121234567","instagram":"username","patient_id":null}}
  • ظرف ۱۵ ثانیه با کد 2xx جواب بدهید. هر جواب دیگر یا قطعی یعنی شکست.
  • شکست دوباره فرستاده می‌شود: ۱ دقیقه، ۵ دقیقه، ۳۰ دقیقه، ۲ ساعت و ۶ ساعت بعد. بعد از آن «نرسید» ثبت می‌شود.
  • در تلاش دوباره id رویداد عوض نمی‌شود. اگر یک id را دو بار گرفتید، دومی را نادیده بگیرید.
  • ارسال از سرورهای lemonai بیرون از ایران است. اگر سرور شما آی‌پی خارجی را نمی‌پذیرد، ارسال در پنل «نرسید» می‌خورد؛ نشانی را روی سروری بگذارید که از بیرون در دسترس است.
  • فقط نشانی https با دامنهٔ عمومی پذیرفته می‌شود، نه آی‌پی یا نشانی داخلی.

سنجش امضا

امضا HMAC-SHA256 روی بدنهٔ خام درخواست است، با راز همان نشانی. بدنه را پیش از JSON کردن بسنجید و مقایسه را با تابع زمان‌ثابت انجام دهید. درخواست بی امضای درست را رد کنید.

import crypto from 'node:crypto';

// rawBody: Buffer همان بدنهٔ دریافتی، پیش از JSON.parse
function verify(rawBody, header, secret) {
  const want = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const a = Buffer.from(want), b = Buffer.from(String(header || ''));
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Express: app.post('/lemonai', express.raw({ type: 'application/json' }), (req, res) => {
//   if (!verify(req.body, req.get('X-Lemonai-Signature'), process.env.LEMONAI_SECRET)) return res.sendStatus(401);
//   const event = JSON.parse(req.body); res.sendStatus(200);
// });

کدام داده بیرون می‌رود

داده مال کلینیک است و مقصدش را خود کلینیک تعیین می‌کند. در وب‌هوک فقط این‌ها می‌رود: نام، شماره، خدمت، زمان، کانال، و خلاصهٔ پیام (برای لید).

کد ملی، یادداشت پزشکی، یادداشت منشی روی نوبت و شرح کار هرگز در وب‌هوک نمی‌روند. در API هم کد ملی و یادداشت پرونده فقط با دسترسی sensitive که صاحب کلینیک صریحا تیکش زده باشد.

هر استفاده از کلید در «گزارش کارها»ی پنل کلینیک ثبت می‌شود.

API در همان پلن CRM است

هزینهٔ جدا ندارد و در ماه رایگان هم باز است. برای مشتری فقط ربات دایرکت، وب‌هوک لید در همان پلن ربات است.