مرجع API
API ویجت
API ویجت، سطح HTTP عمومی است که جاوااسکریپت بستهبندیشده با آن ارتباط برقرار میکند. معمولاً خودتان آن را فراخوانی نمیکنید — بارگذار ویجت این کار را انجام میدهد — اما قرارداد در اینجا مستند شده است تا بتوانید کلاینتهای سفارشی بسازید، ترافیک را حسابرسی کنید یا ویجت را برای تست شبیهسازی کنید.
تمام نقاط پایانی در /api/v1/widget قرار دارند. احراز هویت یک JWT امضا شده است که توسط /init صادر میشود. CORS برای POST بهخاطر نصبهای بین دامنهای مجاز است.
POST POST /v1/widget/init
ویجت را برای یک بازدیدکننده راهاندازی میکند. بدون احراز هویت — اما هدر Origin درخواست باید با allowed_origins دستیار فروش مطابقت داشته باشد (مشاهده کنید دامنههای مجاز).
درخواست
POST /api/v1/widget/init
Origin: https://your-site.com
Content-Type: application/json
{
"agent_id": "01HXY...",
"page_url": "https://your-site.com/pricing",
"anon_id": "anon_abc123" // اختیاری؛ بازدیدکننده را در بارگذاریهای مجدد حفظ میکند
}
پاسخ (۲۰۰)
{
"data": {
"conversation_id": "01HXZ...",
"visitor_id": "01HXY...",
"anonymous_id": "anon_abc123",
"jwt": "eyJhbGciOiJIUzI1NiI...",
"expires_at": "2026-05-07T13:00:00Z",
"agent": {
"id": "01HXY...",
"name": "آریا",
"persona": { "name": "آریا", "tone": "دوستانه" },
"theme": { "primary": "#111827", ... },
"starter_prompts": [ "..." ],
"language_default": "fa"
},
"branding": { "show": true, "label": "...", "url": "...", "logo_url": "...", "display_mode": "logo_only" },
"behavior_rules": [ ... ],
"messages": [ ... ], // ۳۰ پیام آخر مکالمه از سر گرفتهشده
"reverb": { "app_key": "...", "host": "...", "port": 8080, "scheme": "wss" }
}
}
پاسخهای خطا
| وضعیت | کد | دلیل |
|---|---|---|
| ۴۰۴ | agent_not_found | دستیار فروش وجود ندارد یا منتشر نشده است. |
| ۴۰۳ | origin_forbidden | دامنه در allowed_origins نیست. |
| ۴۲۹ | plan_limit_reached | فضای کاری از سهمیه مکالمات ماهانه خود فراتر رفته است. |
| ۴۲۹ | (محدودیت نرخ) | محدودیت نرخ به ازای هر IP (بهطور پیشفرض ۶۰ دور در دقیقه). |
POST POST /v1/widget/messages/stream
نقطه پایانی پخش جریانی. پاسخ SSE. احراز هویت: Authorization: Bearer <jwt>. از این برای تجربه بازدیدکننده استفاده کنید — هر روش دیگر همزمان و کندتر است.
درخواست
POST /api/v1/widget/messages/stream
Authorization: Bearer eyJhbGciOiJIUzI1NiI...
Content-Type: application/json
{
"message": "سیاست بازپرداخت شما چیست؟",
"page_url": "https://your-site.com/pricing",
"page_context": { ... } // اختیاری؛ دادههای ساختاریافته استخراجشده از صفحه فعلی
}
پاسخ (رویدادهای ارسالشده توسط سرور)
HTTP/1.1 200 OK
content-type: text/event-stream
data: {"event":"token","token":"سیاست "}
data: {"event":"token","token":"بازپرداخت "}
data: {"event":"token","token":"ما ۳۰ روز است "}
data: {"event":"citations","citations":[{"id":1,"url":"https://your-site.com/refunds"}]}
data: {"event":"done","conversation_id":"01HXZ..."}
رویدادهای توکن در چند صد میلیثانیه اول سریعترین هستند — این هدف ۱ ثانیه تا اولین توکن در مسیر اصلی است. رویداد citations یک بار پس از اتمام پخش جریانی میرسد. done جریان را میبندد.
POST POST /v1/widget/messages
نسخه همزمان /messages/stream. پاسخ کامل را در یک payload JSON برمیگرداند. کندتر است (بازدیدکننده منتظر پاسخ کامل میماند) اما یکپارچهسازی با کلاینتهای غیر مرورگر آسانتر است.
پاسخ
{
"data": {
"message_id": "01HXZ...",
"conversation_id": "01HXZ...",
"content": "سیاست بازپرداخت ما ۳۰ روز است...",
"citations": [{"id": 1, "url": "..."}],
"low_confidence": false
}
}
POST POST /v1/widget/leads
ارسال اطلاعات تماس جذبشده. احراز هویت: همان JWT پیامها.
POST /api/v1/widget/leads
Authorization: Bearer eyJhbGciOiJIUzI1NiI...
{
"name": "الکس",
"email": "alex@example.com",
"phone": "+1...",
"fields": { "company": "آکمه" } // هر فیلد سفارشی تعریفشده توسط دستیار فروش
}
حذف تکراری براساس (agent_id, email): ارسالهای مجدد، مشتری بالقوه موجود را بهجای ایجاد یک مشتری جدید بهروز میکنند. محدودیت نرخ ۵ درخواست به ازای هر JWT در هر پنجره — مقاوم در برابر سوءاستفاده.
POST POST /v1/widget/events
تحلیلهای سمت کلاینت سبک. ویجت این را با رویدادهای تلهمتری فراخوانی میکند (راهانداز باز شد، فراخوان کلیک شد، رد شد، محرک اسکرول فعال شد). احراز هویت: JWT. محدودیت نرخ.
{
"event": "cta.click",
"rule_id": "01HXY...",
"metadata": { ... }
}
POST POST /v1/widget/request-human
بازدیدکننده به یک اپراتور زنده ارجاع میدهد. پاسخ ربات متوقف میشود. مکالمه به human_requested_at تغییر میکند و هشدار صندوق ورودی درون برنامهای به هر اپراتور فضای کاری میرسد. احراز هویت: JWT.
{ "reason": "میخواهم با فروش صحبت کنم" } // دلیل اختیاری، حداکثر ۵۰۰ کاراکتر
POST POST /v1/widget/typing
نشانگر تایپ بازدیدکننده. ویجت در حالی که بازدیدکننده در حال نوشتن است، پینگ میزند تا اپراتورها "در حال تایپ است…" را بهصورت بیدرنگ ببینند. محدودیت نرخ ۶۰۰ دور در دقیقه به ازای هر IP (بالا برای جذب انفجارهای کلید؛ به ازای هر IP بهجای هر JWT تا چندین زبانه بودجه را به اشتراک بگذارند). بدنه لازم نیست — یک POST خالی کافی است.
POST POST /v1/widget/satisfaction
ثبت امتیاز CSAT بازدیدکننده در پایان مکالمه. احراز هویت: JWT. محدودیت نرخ ۶۰ دور در دقیقه به ازای هر IP.
{
"rating": "good", // good | bad
"comment": "از کمک لذت بردم" // اختیاری، حداکثر ۵۰۰ کاراکتر
}
POST POST /v1/widget/coupon/apply
فقط عمودی فروشگاهی. بازدیدکننده یک فراخوان کوپن ارائهشده را میپذیرد. کنترلکننده مکالمه را با کد کوپن مهر میکند تا انتساب پاییندستی بتواند ربات را اعتبار دهد. احراز هویت: JWT. محدودیت نرخ ۱۲۰ دور در دقیقه به ازای هر IP.
{ "code": "SAVE20" } // ۳-۳۲ کاراکتر، الفبایی + خط تیره
قالب JWT
HS256، امضا شده با WIDGET_JWT_SECRET. ادعاها:
{
"iss": "pitchbar",
"iat": 1714900000,
"exp": 1714903600, // ۶۰ دقیقه
"agent_id": "01HXY...",
"visitor_id": "01HXY...",
"conversation_id": "01HXZ..."
}
توکنها به یک مکالمه محدود میشوند. برای یک مکالمه جدید، دوباره init کنید تا یک توکن جدید دریافت کنید. تأیید در WidgetJwt::verify() انجام میشود — امضاهای نامعتبر، توکنهای منقضیشده یا ادعاهای دستکاریشده همه ۴۰۱ برمیگردانند.
محدودیتهای نرخ
| نقطه پایانی | محدودیت | کلید |
|---|---|---|
/init | ۶۰ دور در دقیقه | به ازای هر IP + agent_id (throttle:widget-init) |
/messages، /messages/stream، /events، /conversation/*، DELETE /me | ۳۰ دور در دقیقه | به ازای هر JWT (throttle:widget-session) |
/leads | ۵ دور در دقیقه | به ازای هر JWT (throttle:widget-leads) |
همه در صورت محدودیت، ۴۲۹ با هدر Retry-After برمیگردانند.