المواعيد
تتيح لك واجهة برمجة تطبيقات المواعيد (Appointments API) حجز مواعيد لجهات الاتصال الخاصة بك ضمن أنواع الأحداث لديك، ثم جلبها أو سردها أو تحديثها أو إلغائها أو حذفها. كما أنها تجيب على السؤال الذي يطرح أولاً في معظم عمليات الحجز — ما هي الأوقات المتاحة فعلياً — وتغطي جانب التقويم: سرد تقويمات Google التي قمت بربطها واستيراد الأحداث الموجودة فيها بالفعل. عند تفعيل اتصال تقويم Google، يتم إنشاء حدث التقويم المطابق ومزامنته تلقائياً في الخلفية. يمكن أيضاً التحقق من المطاعم التي تستخدم Zenchef أو Formitable أو OpenTable أو TheFork لأنظمة الحجز الخاصة بها وربطها هنا، بحيث يقوم وكيل الذكاء الاصطناعي بحجز طاولات حقيقية بدلاً من المواعيد الداخلية — كما يمكن للشركات التي تعتمد على المواعيد وتدير جداولها في Trafft الاتصال بنفس الطريقة.
جميع المسارات في هذه الصفحة نسبية إلى عنوان URL الأساسي https://api.youraiconnector.com/v1. يتطلب كل طلب مفتاح واجهة برمجة التطبيقات الخاص بك — راجع المصادقة للحصول على القائمة الكاملة لطرق إرساله. تستخدم الأمثلة أدناه ترويسة X-API-Key، مع مثال cURL واحد يوضح نموذج استعلام ?apiKey= أيضًا.
الأحداث مقابل المواعيد: نوع الحدث هو تعريف لفترة زمنية قابلة للحجز (نوع الاجتماع، مدته، غرفه). الموعد هو حالة حجز واحدة لنوع حدث معين لجهة اتصال محددة. يمكنك حجز موعد عن طريق الإشارة إلى جهة الاتصال ونوع الحدث.
كائن الموعد
كل نقطة نهاية تُرجع موعدًا تستخدم نفس الهيكل:
| الحقل | الوصف |
|---|---|
id |
المعرف الفريد للموعد. |
contact_id |
معرف جهة الاتصال التي تم حجز الموعد معها. |
event_id |
معرف نوع الحدث الذي تم حجز الموعد عليه. null للحجوزات الخارجية — المواعيد المسجلة بدون نوع حدث. |
status |
Confirmed أو Canceled. |
start_time |
وقت بدء الموعد، بتنسيق ISO 8601 بالتوقيت العالمي المنسق (UTC). |
end_time |
وقت انتهاء الموعد، بتنسيق ISO 8601 بالتوقيت العالمي المنسق (UTC). |
created_at |
وقت إنشاء الموعد. |
last_modified_at |
وقت آخر تعديل للموعد. |
room_name |
الغرفة أو المورد الذي تم حجز الموعد فيه، عندما يستخدم نوع الحدث غرفاً. |
description |
وصف حر للموعد. |
summary |
ملخص قصير أو عنوان. بالنسبة للحجز الخارجي، هذا هو title الذي تم تسجيله به. |
external_reference |
معرفك الخاص لهذا الحجز (من نظام إدارة علاقات العملاء أو نظام الحجز الخاص بك)، كما أرسلته، أو null. |
cancelation_reason |
السبب المقدم عند إلغاء الموعد، إن وجد. |
google_calendar_event_id |
معرف حدث تقويم Google المرتبط. يتم تعيينه بمجرد اكتمال مزامنة التقويم؛ null عند عدم توصيل تقويم أو أثناء استمرار المزامنة. |
calendar_synced |
true بمجرد ربط الموعد بحدث تقويم. |
imported |
true عندما تم استيراد الموعد من تقويم خارجي بدلاً من حجزه مباشرة. |
is_recurring |
true عندما يكون الموعد جزءاً من سلسلة متكررة. |
recurrence_frequency |
عدد مرات تكرار الموعد، عند كونه متكرراً. |
recurring_event_id |
معرف السلسلة المتكررة التي ينتمي إليها هذا الموعد. |
recurring_interval |
الفاصل الزمني بين التكرارات، عند كونه متكرراً. |
recurring_sequence |
موقع هذا الموعد ضمن سلسلته المتكررة. |
end_after_x_occurrences |
عدد مرات التكرار التي تنتهي بعدها السلسلة المتكررة. |
booking_provider |
النظام المصدر الذي جاء منه الحجز، عند الحجز من خلال مزود حجز متصل. |
حول مزامنة التقويم: مباشرة بعد حجز موعد أو تغييره، قد يظل
google_calendar_event_idهوnullوقد يكونcalendar_syncedهوfalseلأن المزامنة تعمل في الخلفية بعد لحظات. قم بجلب الموعد مرة أخرى بعد فترة قصيرة لرؤية حقول التقويم المعبأة.
العثور على الفترات المتاحة
GET /appointments/available-slots
تُرجع الأوقات المتاحة فعلياً لنوع حدث معين بين لحظتين زمنيتين. عادة ما يكون هذا هو الاستدعاء الأول في عملية الحجز: اعرض هذه الفترات، واسمح للشخص باختيار واحدة منها، ثم أرسل الوقت المختار إلى حجز موعد.
تأخذ الإجابة في الاعتبار بالفعل ساعات عمل نوع الحدث وطول الفترة الزمنية، وغرفه، والمواعيد التي حجزتها عليه مسبقاً، وكل ما هو محجوز في تقويمات Google المرتبطة — لذا فإن أي فترة تظهر هنا هي فترة يمكنك حجزها.
| معلمة الاستعلام | مطلوبة | الوصف |
|---|---|---|
event_id |
نعم | نوع الحدث المراد التحقق منه. يجب أن ينتمي إلى حسابك. يمكنك العثور عليه في التطبيق عن طريق فتح نوع الحدث في صفحة المواعيد (علامة تبويب أنواع الأحداث): تعرض نافذة التعديل معرف نوع الحدث الخاص به مع زر للنسخ. |
start_time |
نعم | بداية النافذة التي تريد الحصول على فترات زمنية لها، بتنسيق ISO 8601 للتاريخ والوقت. |
end_time |
نعم | نهاية النافذة، بتنسيق ISO 8601 للتاريخ والوقت. يتم تضمين يوم النهاية بالكامل. |
تظهر النتائج مجمعة حسب اليوم — وعندما يستخدم نوع الحدث غرفاً، تظهر مجموعة واحدة لكل غرفة في كل يوم:
| الحقل | الوصف |
|---|---|
date |
اليوم الذي تغطيه المجموعة، مكتوباً بصيغة DD/MM/YYYY. |
day |
اسم يوم الأسبوع بأحرف صغيرة، على سبيل المثال monday. |
room_name |
الغرفة أو المورد الذي تنتمي إليه هذه المجموعة، عندما يستخدم نوع الحدث غرفاً. |
available_slots |
الفترات القابلة للحجز في ذلك اليوم، مرتبة من الأقدم إلى الأحدث. |
يحتوي كل إدخال في available_slots على:
| الحقل | الوصف |
|---|---|
start_time |
بداية الفترة بصيغة HH:mm. |
end_time |
نهاية الفترة بصيغة HH:mm. |
available |
true — يتم إرجاع الوقت المتاح فقط. |
spots_left |
عدد المواعيد التي لا تزال تتسع لها هذه الفترة. تظهر فقط في أنواع الأحداث التي تقبل أكثر من حجز واحد لكل فترة. |
الأوقات محلية لنوع الحدث، وليست بتوقيت UTC. قيم
dateوstart_timeوend_timeهي قيم ساعة الحائط في المنطقة الزمنية الخاصة بنوع الحدث (تجاوزه، أو المنطقة الزمنية لحسابك في حال عدم وجود تجاوز). يتوقع حجز موعد لحظة زمنية بتنسيق ISO 8601 UTC، لذا قم بتحويل الفترة التي اخترتها قبل إرسالها.
cURL
curl "https://api.youraiconnector.com/v1/appointments/available-slots?event_id=event_xyz789&start_time=2026-06-15T00:00:00.000Z&end_time=2026-06-19T00:00:00.000Z" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const params = new URLSearchParams({
event_id: "event_xyz789",
start_time: "2026-06-15T00:00:00.000Z",
end_time: "2026-06-19T00:00:00.000Z",
});
const res = await fetch(
`https://api.youraiconnector.com/v1/appointments/available-slots?${params}`,
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.data);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/appointments/available-slots",
headers={"X-API-Key": "YOUR_API_KEY"},
params={
"event_id": "event_xyz789",
"start_time": "2026-06-15T00:00:00.000Z",
"end_time": "2026-06-19T00:00:00.000Z",
},
)
print(res.json()["data"])
الاستجابة (200 OK):
{
"success": true,
"data": [
{
"date": "15/06/2026",
"day": "monday",
"room_name": "Room A",
"available_slots": [
{ "start_time": "10:00", "end_time": "10:30", "available": true },
{ "start_time": "10:30", "end_time": "11:00", "available": true }
]
},
{
"date": "16/06/2026",
"day": "tuesday",
"room_name": "Room A",
"available_slots": [
{ "start_time": "09:00", "end_time": "09:30", "available": true, "spots_left": 2 }
]
}
]
}
اليوم الذي لا يحتوي على أي وقت متاح ببساطة لا يظهر. فقدان event_id أو start_time أو end_time يُرجع 400؛ ونوع الحدث غير الموجود في حسابك يُرجع 404.
حجز موعد
POST /appointments
ينشئ موعداً لأحد جهات الاتصال الخاصة بك. هناك طريقتان لاستخدامه:
- على أحد أنواع الأحداث الخاصة بك — أرسل
event_id، وسيعمل الحجز تماماً كما كان دائماً: يتم احترام التوفر والسعة، ويتم حساب وقت الانتهاء من مدة الفترة الزمنية لنوع الحدث، ويتم مزامنة الموعد مع تقويم Google الخاص بك عند توصيله. - كحجز خارجي — اترك
event_idفارغاً وأرسلtitleبدلاً منه. يسجل هذا حجزاً تم إجراؤه في مكان آخر (نظام إدارة علاقات العملاء الخاص بك، جدول فصول دراسية، أداة حجز أخرى) بحيث يظهر في صفحة المواعيد بجانب البقية.
يجب أن يكون الحجز في نوع حدث يتضمن غرفاً في وقت يتيح العثور على فترات زمنية متاحة: ضمن ساعات عمل الغرفة، وخارج فترة الإشعار، وضمن النطاق الزمني المسموح به لحجز نوع الحدث، وعلى شبكة الفترات الزمنية، وليس في الماضي، وغير محظور في تقويم متصل. يتم رفض أي وقت آخر باستخدام 400 ولا يتم إنشاء أي شيء. وينطبق الأمر نفسه على room_name الذي لا يطابق أياً من غرف نوع الحدث (تسرد الرسالة الأسماء الصالحة). يتم الحفاظ على أوقات التخزين المؤقت المحددة في نوع الحدث (تخزين مؤقت قبل وتخزين مؤقت بعد في محرر نوع الحدث، buffer_before وbuffer_after بالدقائق) خالية حول كل حجز.
يتم أيضاً التحقق من تعارض الحجز في نوع الحدث: إذا كانت الفترة الزمنية ممتلئة بالفعل، يفشل الطلب مع 409 ولا يتم إنشاء أي شيء. لا يحتوي الحجز الخارجي على نوع حدث خلفه، لذا لا يتم التحقق من أي شيء مقابل توافرك أو سعتك ولا تتم مزامنة أي شيء مع التقويم.
إعادة المحاولة آمنة. إذا كان لدى جهة الاتصال نفسها بالفعل حجز مؤكد في نفس نوع الحدث في نفس وقت البدء (في نفس الغرفة، عند تسمية واحدة)، على سبيل المثال لأن طلبك الأول انتهت مهلته بعد إتمامه، فستستعيد ذلك الحجز مع 200 و "replayed": true بدلاً من حجز ثانٍ أو 409.
يعمل external_reference كمفتاح لضمان عدم التكرار (idempotency key). وهو فريد على مستوى حسابك: إذا كان الموعد يحمل بالفعل المرجع الذي أرسلته، فسيتم إرجاع ذلك الموعد مع 200 و "replayed": true ولن يتم إنشاء أي شيء جديد، حتى لو كانت إعادة المحاولة تشير إلى وقت أو جهة اتصال مختلفة وبغض النظر عن حالة ذلك الموعد. استخدمه للحجوزات المدفوعة (أرسل معرف الدفع أو الطلب الخاص بك)، وأرسل مرجعاً جديداً لأي حجز جديد تماماً.
| الحقل | مطلوب | الوصف |
|---|---|---|
contact_id |
نعم | معرف جهة الاتصال المراد الحجز لها. يجب أن ينتمي إلى حسابك. |
start_time |
نعم | وقت البدء المطلوب بتنسيق ISO 8601. الوقت المرسل بدون إزاحة المنطقة الزمنية يُقرأ وفقاً للمنطقة الزمنية لحسابك. |
event_id |
لا | معرف نوع الحدث المراد الحجز عليه. يجب أن ينتمي إلى حسابك. اتركه فارغاً لتسجيل حجز خارجي. |
title |
فقط بدون event_id |
الاسم الذي يظهر به الموعد في صفحة المواعيد — اسم الفئة، على سبيل المثال. بحد أقصى 200 حرف. يتم إرجاعه كـ summary. |
end_time |
لا | نهاية الحجز الخارجي بتنسيق ISO 8601، يجب أن يكون لاحقاً لـ start_time. غير مطلوب مع event_id: حيث يتم استمداد وقت النهاية من مدة الفترة الزمنية لنوع الحدث. |
duration_minutes |
لا | مدة الحجز الخارجي، رقم صحيح من الدقائق يتراوح بين 1 و 1440. استخدم هذا أو end_time، وليس كلاهما. في حال عدم استخدام أي منهما، تكون مدة الحجز الخارجي 60 دقيقة. |
description |
لا | ملاحظات حرة للاحتفاظ بها مع الموعد. |
room_name |
لا | اسم الغرفة أو المورد، عندما يستخدم نوع الحدث غرفاً. يجب أن يطابق إحدى غرفه. اتركه فارغاً لحجز أول غرفة متاحة. |
external_reference |
لا | معرفك الخاص لهذا الحجز، حتى تتمكن من مطابقته مع السجل في نظام إدارة علاقات العملاء (CRM) أو نظام الحجز الخاص بك. بحد أقصى 255 حرفاً. يتم إرجاعه عند كل عملية قراءة وفي خطافات الويب (webhooks) الخاصة بالموعد المحجوز، والملغي، والمعاد جدولته. فريد على مستوى حسابك: المرجع المستخدم بالفعل يعيد ذلك الموعد بدلاً من الحجز مرة أخرى (انظر أعلاه). |
أرسل event_id و title معاً، أو لا ترسل أياً منهما، وسيعيد الطلب 400 — وكذلك الحال عند إرسال كل من end_time و duration_minutes.
cURL (باستخدام نموذج استعلام ?apiKey=)
curl -X POST "https://api.youraiconnector.com/v1/appointments?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contact_id": "contact_abc123",
"event_id": "event_xyz789",
"start_time": "2026-06-15T10:00:00.000Z",
"room_name": "Room A"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/appointments", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
contact_id: "contact_abc123",
event_id: "event_xyz789",
start_time: "2026-06-15T10:00:00.000Z",
room_name: "Room A",
}),
});
const data = await res.json();
console.log(data.appointment_id);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/appointments",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"contact_id": "contact_abc123",
"event_id": "event_xyz789",
"start_time": "2026-06-15T10:00:00.000Z",
"room_name": "Room A",
},
)
print(res.json()["appointment_id"])
الاستجابة (201 Created):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678",
"appointment": {
"id": "aBcD1234eFgH5678",
"contact_id": "contact_abc123",
"event_id": "event_xyz789",
"status": "Confirmed",
"start_time": "2026-06-15T10:00:00.000Z",
"end_time": "2026-06-15T10:30:00.000Z",
"created_at": "2026-06-10T09:00:00.000Z",
"last_modified_at": "2026-06-10T09:00:00.000Z",
"room_name": "Room A",
"google_calendar_event_id": null,
"calendar_synced": false
}
}
تسجيل حجز تم إجراؤه في مكان آخر
نفس نقطة النهاية، بدون نوع حدث: يكفي وجود title و start_time، ويحدد duration_minutes مدة استمراره.
cURL
curl -X POST "https://api.youraiconnector.com/v1/appointments" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contact_id": "contact_abc123",
"title": "Beginner guitar class",
"start_time": "2026-06-15T10:00:00.000Z",
"duration_minutes": 90,
"external_reference": "class-slot-4812"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/appointments", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
contact_id: "contact_abc123",
title: "Beginner guitar class",
start_time: "2026-06-15T10:00:00.000Z",
duration_minutes: 90,
}),
});
const data = await res.json();
console.log(data.appointment_id);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/appointments",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"contact_id": "contact_abc123",
"title": "Beginner guitar class",
"start_time": "2026-06-15T10:00:00.000Z",
"duration_minutes": 90,
},
)
print(res.json()["appointment_id"])
الاستجابة (201 Created):
{
"success": true,
"appointment_id": "eFgH5678aBcD1234",
"appointment": {
"id": "eFgH5678aBcD1234",
"contact_id": "contact_abc123",
"event_id": null,
"status": "Confirmed",
"start_time": "2026-06-15T10:00:00.000Z",
"end_time": "2026-06-15T11:30:00.000Z",
"created_at": "2026-06-10T09:00:00.000Z",
"last_modified_at": "2026-06-10T09:00:00.000Z",
"summary": "Beginner guitar class",
"google_calendar_event_id": null,
"calendar_synced": false
}
}
تعتبر الحجوزات الخارجية مواعيد عادية من تلك اللحظة فصاعداً: فهي تظهر في صفحة المواعيد وفي قائمة المواعيد، ويمكن إعادة جدولتها أو إلغاؤها أو حذفها في التطبيق أو من خلال واجهة برمجة التطبيقات هذه، ويتم إرسال بريد إلكتروني لتأكيد الحجز كالمعتاد، ويتم تشغيل مشغل أتمتة حجز الموعد وخطاف الويب (webhook) لها مثل أي حجز آخر يتم إجراؤه من خلال واجهة برمجة التطبيقات. الاختلافات الوحيدة هي المذكورة أعلاه — لا يوجد فحص للتوفر أو السعة، ولا مزامنة للتقويم، ويبقى event_id كـ null.
الحصول على موعد
GET /appointments/{appointmentId}
إرجاع موعد واحد بواسطة المعرف الخاص به، بما في ذلك حالة مزامنة التقويم الخاصة به.
cURL
curl "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.appointment);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["appointment"])
الاستجابة (200 OK):
{
"success": true,
"appointment": {
"id": "aBcD1234eFgH5678",
"contact_id": "contact_abc123",
"event_id": "event_xyz789",
"status": "Confirmed",
"start_time": "2026-06-15T10:00:00.000Z",
"end_time": "2026-06-15T10:30:00.000Z",
"room_name": "Room A",
"google_calendar_event_id": "abc123googleevent",
"calendar_synced": true
}
}
سرد المواعيد
GET /appointments
سرد المواعيد الخاصة بحسابك، بدءاً من الأحدث، مع استخدام الترقيم الصفحي المستند إلى المؤشر.
| معلمة الاستعلام | مطلوبة | الوصف |
|---|---|---|
contact_id |
لا | إرجاع المواعيد الخاصة بهذا جهة الاتصال فقط. تتضمن القوائم المفلترة حسب جهة الاتصال المواعيد المؤكدة فقط |
date |
لا | إرجاع المواعيد في يوم التقويم هذا فقط (YYYY-MM-DD). يتطلب contact_id. |
status |
لا | التصفية حسب Confirmed أو Canceled. متاح فقط بدون contact_id. |
limit |
لا | حجم الصفحة، عدد صحيح بين 1 و100. القيمة الافتراضية 50. |
cursor |
لا | قيمة next_cursor من استجابة سابقة. |
بضع قواعد يجب وضعها في الاعتبار:
- بدون عوامل تصفية، ستحصل على كل موعد في الحساب، صفحة بصفحة.
- حسب جهة الاتصال — اضبط
contact_idلرؤية المواعيد المؤكدة لجهة اتصال واحدة. يمكنك تضييق نطاق ذلك ليوم واحد عن طريق تمريرdateأيضاً. - حسب الحالة — اضبط
status(بدونcontact_id) لسرد المواعيدConfirmedفقط أوCanceledفقط عبر الحساب. - عامل التصفية
dateبدونcontact_id، أوstatus=Canceledمعcontact_id، يرجع400.
cURL
curl "https://api.youraiconnector.com/v1/appointments?contact_id=contact_abc123&date=2026-06-15" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const params = new URLSearchParams({
contact_id: "contact_abc123",
date: "2026-06-15",
});
const res = await fetch(
`https://api.youraiconnector.com/v1/appointments?${params}`,
{ headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.appointments, data.next_cursor);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/appointments",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"contact_id": "contact_abc123", "date": "2026-06-15"},
)
data = res.json()
print(data["appointments"], data["next_cursor"])
الاستجابة (200 OK):
{
"success": true,
"appointments": [
{
"id": "aBcD1234eFgH5678",
"contact_id": "contact_abc123",
"event_id": "event_xyz789",
"status": "Confirmed",
"start_time": "2026-06-15T10:00:00.000Z",
"end_time": "2026-06-15T10:30:00.000Z",
"calendar_synced": true
}
],
"next_cursor": null
}
للتنقل بين النتائج، مرر next_cursor من استجابة واحدة كـ cursor للطلب التالي. استمر في ذلك حتى تصبح next_cursor مساوية لـ null. راجع الأخطاء والترقيم الصفحي لمعرفة نمط الترقيم الصفحي المشترك.
تحديث موعد
PUT /appointments/{appointmentId}
إعادة جدولة موعد أو تغيير تفاصيله. أرسل فقط الحقول التي تريد تغييرها — يلزم حقل واحد على الأقل. يجب أن يظل وقت البدء ووقت الانتهاء مجتمعين بترتيب زمني (يجب أن يكون end_time بعد start_time). تتم مزامنة التغييرات مع حدث التقويم المرتبط تلقائياً.
يتم التحقق من تعارض نقل حجز مؤكد في نوع حدث (جديد start_time أو room_name) مثل الحجز الجديد: الفترة الزمنية الممتلئة بالفعل تجيب بـ 409 ولا يتغير شيء، و room_name الذي لا يطابق أياً من غرف نوع الحدث يجيب بـ 400. أرسل فقط start_time وسيحافظ الحجز على طوله. لا يتم تطبيق ساعات عملك وفترة الإشعار الخاصة بك هنا، لذا لا يزال بإمكانك نقل حجز إلى أي وقت متاح.
| الحقل | الوصف |
|---|---|
start_time |
وقت البدء الجديد، بتنسيق ISO 8601. الوقت المرسل بدون إزاحة المنطقة الزمنية يُقرأ وفقاً للمنطقة الزمنية لنوع الحدث (أو حسابك)، تماماً كما هو الحال عند الحجز. |
end_time |
وقت النهاية الجديد، بتنسيق ISO 8601، يُقرأ بنفس الطريقة. يجب أن يكون لاحقاً لوقت البدء. |
room_name |
اسم الغرفة أو المورد الجديد. |
description |
الوصف الجديد، أو null لمسحه. |
summary |
الملخص الجديد، أو null لمسحه. |
external_reference |
المرجع الجديد (بحد أقصى 255 حرفاً)، أو null لمسحه. المرجع الذي يمتلكه موعد آخر بالفعل يتم رفضه مع 409 و "code": "external_reference_taken". |
cURL
curl -X PUT "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"start_time": "2026-06-16T10:00:00.000Z",
"end_time": "2026-06-16T10:30:00.000Z"
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
{
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
start_time: "2026-06-16T10:00:00.000Z",
end_time: "2026-06-16T10:30:00.000Z",
}),
}
);
const data = await res.json();
console.log(data.appointment);
Python
import requests
res = requests.put(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"start_time": "2026-06-16T10:00:00.000Z",
"end_time": "2026-06-16T10:30:00.000Z",
},
)
print(res.json()["appointment"])
الاستجابة (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678",
"appointment": {
"id": "aBcD1234eFgH5678",
"contact_id": "contact_abc123",
"event_id": "event_xyz789",
"status": "Confirmed",
"start_time": "2026-06-16T10:00:00.000Z",
"end_time": "2026-06-16T10:30:00.000Z",
"calendar_synced": true
}
}
إلغاء موعد
POST /appointments/{appointmentId}/cancel
يؤدي هذا إلى إلغاء موعد مؤكد، مع إمكانية تسجيل سبب للإلغاء. يظل الموعد في حسابك بحالة Canceled، ويتم حذف حدث التقويم المرتبط تلقائياً في الخلفية. يؤدي إلغاء موعد تم إلغاؤه بالفعل إلى إرجاع 400.
| الحقل | مطلوب | الوصف |
|---|---|---|
cancellation_reason |
لا | سبب الإلغاء، يتم تخزينه مع الموعد. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/cancel" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"cancellation_reason": "Client asked to reschedule next month"
}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/cancel",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
cancellation_reason: "Client asked to reschedule next month",
}),
}
);
const data = await res.json();
console.log(data.success);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/cancel",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"cancellation_reason": "Client asked to reschedule next month"},
)
print(res.json()["success"])
الاستجابة (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678"
}
إعادة إرسال تأكيد الحجز
POST /appointments/{appointmentId}/resend-confirmation
يعيد إرسال تأكيد الحجز إلى جهة الاتصال، على سبيل المثال عندما يذكرون أنه لم يصلهم أو أنه انتقل إلى مجلد الرسائل غير المرغوب فيها. يتكون من جزأين، يتم إرسال كليهما ما لم تقم بإيقاف تشغيل أحدهما: رسالة التأكيد الإلكترونية (نفس الرسالة التي تلقتها جهة الاتصال عند الحجز) ودعوة تقويم Google، وذلك عند وجود الموعد في تقويم Google الخاص بك. يتم إرسال كلاهما إلى عنوان البريد الإلكتروني الخاص بجهة الاتصال.
| الحقل | مطلوب | الوصف |
|---|---|---|
email |
لا | false يتخطى رسالة التأكيد الإلكترونية. القيمة الافتراضية هي true. |
calendar_invite |
لا | false يتخطى دعوة تقويم Google. القيمة الافتراضية هي true. |
يأتي كل جزء بنتيجته الخاصة: sent، أو not_requested، أو no_contact_email، أو turned_off_for_event_type (مفتاح إرسال رسالة الموعد الإلكترونية إلى جهة الاتصال الخاص بنوع الحدث متوقف)، أو not_on_google_calendar، أو imported (المواعيد المستوردة من تقويمك لا تتلقى رسالة تأكيد إلكترونية) أو failed.
200عند إرسال جزء واحد على الأقل.recipientهو العنوان الذي تم الإرسال إليه.409للمواعيد الملغاة، أو المواعيد التي انتهت بالفعل، أو الحجوزات التي تمت من خلال Zenchef أو Formitable أو OpenTable أو TheFork أو Trafft (حيث يرسل ذلك النظام تأكيده الخاص).codeهيappointment_canceledأوappointment_in_pastأوmanaged_by_provider.422عندما تعذر إرسال أي شيء، مع توضيح السبب فيerror.
cURL
curl -X POST "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/resend-confirmation" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/resend-confirmation",
{
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ calendar_invite: false }),
}
);
const data = await res.json();
console.log(data.email, data.recipient);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678/resend-confirmation",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={},
)
print(res.json())
الاستجابة (200 OK):
{
"success": true,
"appointment_id": "aBcD1234eFgH5678",
"email": "sent",
"calendar_invite": "sent",
"recipient": "jane@example.com"
}
حذف موعد
DELETE /appointments/{appointmentId}
يحذف الموعد ومراجعه نهائياً. إذا كنت ترغب فقط في إلغاء الحجز مع الاحتفاظ بالسجل، استخدم إلغاء بدلاً من ذلك.
cURL
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
{ method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);
Python
import requests
res = requests.delete(
"https://api.youraiconnector.com/v1/appointments/aBcD1234eFgH5678",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])
الاستجابة (200 OK):
{
"success": true
}
سرد تقويمات Google المرتبطة بك
GET /appointments/google-calendars
تُرجع تقويمات Google المتاحة في هذا الحساب، مباشرة من Google — وهي مفيدة لعرض أداة اختيار لصاحب الحساب لتحديد التقويم الذي سيتم الاستيراد منه أدناه، أو لمجرد تأكيد أن الاتصال نشط.
لا يعمل هذا إلا بعد ربط الحساب بـ Google Calendar (الإعدادات ← عمليات الربط) مع صلاحية القراءة على الأقل. إذا لم يتم ذلك، أو إذا لم يعد الوصول الممنوح يتضمن نطاق قراءة التقويم، فستتلقى 400 يطلب منك ربطه (أو إعادة ربطه).
cURL
curl "https://api.youraiconnector.com/v1/appointments/google-calendars" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/appointments/google-calendars", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data);
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/appointments/google-calendars",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["data"])
الاستجابة (200 OK):
{
"success": true,
"data": [
{
"id": "primary",
"summary": "jane@example.com",
"timeZone": "America/New_York",
"accessRole": "owner",
"primary": true
},
{
"id": "abcdefg1234567890@group.calendar.google.com",
"summary": "Bookings",
"timeZone": "America/New_York",
"accessRole": "writer"
}
]
}
كل إدخال هو عبارة عن شكل CalendarListEntry خاص بـ Google، لذا تتبع أسماء الحقول camelCase الخاصة بـ Google، وليس snake_case المعتادة لهذه الواجهة البرمجية — فهذه بيانات Google التي يتم تمريرها كما هي، وليست بياناتنا. يؤدي فقدان الاتصال أو إلغاؤه إلى إرجاع 400 مع خطأ يوضح الحاجة إلى ربط (أو إعادة ربط) Google Calendar.
استيراد الأحداث من تقويم Google
POST /appointments/import-calendar-events
يقوم بسحب الأحداث الموجودة بالفعل في تقويم (تقاويم) Google المرتبطة بحملة أو وكيل ذكاء اصطناعي (AI Agent) ويحولها إلى مواعيد — وهو أمر مفيد في المرة الأولى التي تربط فيها تقويماً يحتوي بالفعل على حجوزات. قد يستغرق هذا بعض الوقت (حيث يمر كل حدث عبر عملية استخراج لمعرفة لمن يخص)، لذا فهو لا يعمل بشكل فوري: يضع الطلب مهمة في الخلفية ويعيد لك job_id للاستعلام عن حالتها.
| الحقل | مطلوب | الوصف |
|---|---|---|
campaign_id |
واحد من هذين الاثنين | الحملة التي سيتم الاستيراد من تقويمها (تقاويمها) المرتبط. |
agent_id |
واحد من هذين الاثنين | وكيل الذكاء الاصطناعي (AI Agent) الذي سيتم الاستيراد من تقويمه (تقاويمها) المرتبط. |
identifier |
نعم | "EMAIL" أو "PHONE_NUMBER" — أي جزء من معلومات الاتصال يجب استخراجه من كل حدث في التقويم لمطابقة جهة الاتصال التي ينتمي إليها أو إنشائها. |
أرسل واحداً فقط من campaign_id / agent_id، ولا ترسل كلاهما أبداً ولا تترك كلاهما فارغاً — أي من هاتين الحالتين ستؤدي إلى إرجاع 400. يجب أن ينتمي أي منهما ترسله إلى حسابك، وإلا فستتلقى 404.
cURL
curl -X POST "https://api.youraiconnector.com/v1/appointments/import-calendar-events?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agent_abc123",
"identifier": "EMAIL"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/appointments/import-calendar-events", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
agent_id: "agent_abc123",
identifier: "EMAIL",
}),
});
const data = await res.json();
console.log(data.job_id);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/appointments/import-calendar-events",
headers={
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
json={"agent_id": "agent_abc123", "identifier": "EMAIL"},
)
print(res.json()["job_id"])
الاستجابة (202 Accepted):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "queued",
"campaign_id": null,
"agent_id": "agent_abc123"
}
يعيد campaign_id و agent_id صدى أيهما أرسلت؛ والآخر يكون دائماً null.
الاستعلام عن حالة مهمة الاستيراد
GET /appointments/import-calendar-events/{jobId}
curl "https://api.youraiconnector.com/v1/appointments/import-calendar-events/jK9mQ2xR7pL4wN1t" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK):
{
"success": true,
"job_id": "jK9mQ2xR7pL4wN1t",
"status": "completed",
"message": "Imported 12 events as appointments.",
"error": null
}
status |
المعنى |
|---|---|
queued |
لم يتم البدء بها بعد. استمر في الاستعلام. |
processing |
عملية الاستيراد قيد التشغيل. استمر في الاستعلام. |
completed |
تم الانتهاء — يحتوي message على ملخص قصير ومقروء. |
failed |
حدث خطأ ما — يحتوي error على السبب. |
يؤدي تنفيذ GET على jobId غير موجود (أو ينتمي إلى حساب مختلف) إلى إرجاع 404.
عمليات تكامل الحجز الخارجية (Zenchef / Formitable / OpenTable / TheFork / Trafft)
تعد Zenchef و Formitable أنظمة حجز مطاعم يمكن لوكيل الذكاء الاصطناعي الخاص بك حجز طاولات حقيقية من خلالها؛ أما Trafft فهي منصة جدولة للشركات التي تعتمد على المواعيد، ويتم ربطها مرة واحدة لكل حساب بدلاً من ربطها لكل مطعم. تحتوي منصتا المطاعم على أداة حجز عامة وغير مصادق عليها (https://api.youraiconnector.com/v1/zenchef-widget/... و https://api.youraiconnector.com/v1/formitable-widget/...) تظهر داخل الدردشة للعميل — مسارات الأداة هذه هي صفحات HTML عادية مخصصة للفتح في المتصفح، وليست نقاط نهاية لواجهة برمجة تطبيقات JSON، لذا فهي غير موثقة هنا. ما يلي هو نقاط نهاية إدارة الحساب: التحقق من أن معرف المطعم ينتمي إلى صاحب الحساب، ثم إضافته أو تحديثه أو إزالته.
Zenchef
يعد ربط مطعم Zenchef عملية تحقق من خطوتين، حيث يثبت صاحب الحساب أنه يدير المطعم فعلياً قبل ربطه بالبوت: أولاً، يتم التحقق من وجود المعرف (دون الكشف عن الاسم)، ثم يُطلب منهم كتابة اسم المطعم بأنفسهم للتحقق من تطابقه.
الخطوة 1 — التحقق من وجود معرف المطعم
POST /appointments/zenchef-restaurants/check
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف مطعم Zenchef المراد التحقق منه. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/check?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "12345" }'
الاستجابة (200 OK):
{
"success": true,
"data": { "exists": true, "requiresNameVerification": true }
}
تعني exists: false أنه لا يوجد مطعم Zenchef بهذا المعرف — لا يوجد شيء آخر للقيام به. الحد المسموح به هو 10 عمليات تحقق لكل 5 دقائق لكل حساب؛ تجاوز هذا الحد يؤدي إلى إرجاع 429.
الخطوة 2 — التحقق من اسم المطعم
POST /appointments/zenchef-restaurants/verify-name
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف مطعم Zenchef من الخطوة 1. |
user_input_name |
نعم | الاسم الذي كتبه صاحب الحساب — تتم مقارنته بالاسم الحقيقي للمطعم على Zenchef (غير حساس لحالة الأحرف/المسافات). |
curl -X POST "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/verify-name?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "12345", "user_input_name": "The Blue Door Bistro" }'
الاستجابة (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"id": "12345",
"name": "The Blue Door Bistro",
"address": "1 Rue de Rivoli, Paris",
"status": "active"
}
}
}
تعني verified: false أن الاسم غير متطابق — يتم حذف restaurantDetails، اطلب من صاحب الحساب المحاولة مرة أخرى. الحد المسموح به هو 3 محاولات لكل 5 دقائق (أكثر صرامة من التحقق من الوجود، لأن هذه هي خطوة الإثبات الفعلية). يؤدي استخدام restaurant_id لم يعد متاحاً على Zenchef إلى إرجاع 404.
الخطوة 3 — حفظ المطعم
POST /appointments/zenchef-restaurants
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | 1–64 حرفاً، أحرف/أرقام/شرطة سفلية/واصلة. |
restaurant_name |
نعم | اسم المطعم الذي تم التحقق منه من الخطوة 2. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "12345", "restaurant_name": "The Blue Door Bistro" }'
الاستجابة (201 Created):
{ "success": true, "data": { "restaurantId": "12345" } }
تحديث مطعم Zenchef محفوظ
PUT /appointments/zenchef-restaurants/{restaurantId}
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_name |
لا | اسم العرض الجديد. |
is_active |
لا | اضبط false لإيقاف البوت عن الحجز في هذا المطعم دون إزالته. |
curl -X PUT "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/12345" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
الاستجابة (200 OK): نفس شكل استجابة الحفظ أعلاه.
إزالة مطعم Zenchef
DELETE /appointments/zenchef-restaurants/{restaurantId}
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/zenchef-restaurants/12345" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK): { "success": true, "data": { "restaurantId": "12345" } }
المطعم restaurantId غير الموجود حالياً في الحساب يُرجع 404 عند التحديث أو الحذف.
Formitable
لا يحتاج Formitable إلى إثبات الاسم المكون من خطوتين كما هو الحال مع Zenchef — فمعرفات المطاعم الخاصة به محددة بالفعل لكل نشاط تجاري، لذا يكفي إجراء مكالمة تحقق واحدة. كما أنه يحتوي على بحث عن التفاصيل يُستخدم لتخزين عنوان URL الخاص بموقع المطعم مؤقتاً أثناء الإعداد.
التحقق من معرف المطعم
POST /appointments/formitable-restaurants/verify
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف مطعم Formitable. |
language |
لا | علامة اللغة لطلب الفحص. القيمة الافتراضية هي "nl". |
curl -X POST "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/verify?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "the-blue-door", "language": "en" }'
الاستجابة (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "the-blue-door",
"productCount": 4,
"sampleProductTitle": "Dinner for two",
"language": "en"
}
}
}
إرجاع restaurant_id لا يتعرف عليه Formitable يؤدي إلى 404. يخضع لمعدل محدد بـ 10 محاولات كل 5 دقائق لكل حساب.
الحصول على تفاصيل المطعم
GET /appointments/formitable-restaurants/{restaurantId}/details?language=en
يجلب الملف الشخصي العام للمطعم من Formitable، بما في ذلك موقعه الإلكتروني — يُستخدم لتخزين عنوان URL الخاص بالموقع مؤقتاً أثناء إعداد المطعم. language هو معامل استعلام اختياري، وقيمته الافتراضية هي "en".
curl "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door/details?language=en" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK):
{
"success": true,
"data": {
"uid": "the-blue-door",
"name": "The Blue Door Bistro",
"website": "https://thebluedoorbistro.com",
"email": "info@thebluedoorbistro.com",
"telephone": "+31201234567",
"streetAddress": "Prinsengracht 1",
"zipcode": "1015 AB",
"city": "Amsterdam",
"country": "Netherlands",
"countryCode": "NL",
"currency": "EUR"
}
}
حفظ المطعم
POST /appointments/formitable-restaurants
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | 1–64 حرفاً، أحرف/أرقام/شرطة سفلية/واصلة. |
restaurant_name |
نعم | اسم العرض. |
language |
نعم | وسم لغة ISO، على سبيل المثال "en" أو "en-GB". |
website_url |
لا | الموقع الإلكتروني للمطعم، من بحث التفاصيل أعلاه. يجب أن يكون http(s)://. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/formitable-restaurants?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"restaurant_id": "the-blue-door",
"restaurant_name": "The Blue Door Bistro",
"language": "en",
"website_url": "https://thebluedoorbistro.com"
}'
الاستجابة (201 Created): { "success": true, "data": { "restaurantId": "the-blue-door" } }
تحديث مطعم Formitable محفوظ
PUT /appointments/formitable-restaurants/{restaurantId}
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_name |
لا | اسم العرض الجديد. |
language |
لا | وسم لغة ISO جديد. |
is_active |
لا | اضبط false لإيقاف البوت عن الحجز في هذا المطعم دون إزالته. |
website_url |
لا | رابط الموقع الإلكتروني الجديد. |
curl -X PUT "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
الاستجابة (200 OK): نفس شكل استجابة الحفظ أعلاه.
إزالة مطعم Formitable
DELETE /appointments/formitable-restaurants/{restaurantId}
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/formitable-restaurants/the-blue-door" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK): { "success": true, "data": { "restaurantId": "the-blue-door" } }
المطعم restaurantId غير الموجود حالياً في الحساب يُرجع 404 عند التحديث أو الحذف.
OpenTable
يتم الوصول إلى مطاعم OpenTable من خلال بيانات اعتماد شريك OpenTable الخاصة بالمنصة، ولا تسمح OpenTable لهذه البيانات إلا برؤية المطاعم التي ربطت قائمة المنصة داخل سوق تكاملات OpenTable. لذا، مثل Formitable، يكفي إجراء مكالمة تحقق واحدة: معرف المطعم القابل للوصول (رقم “RID”) يثبت وجود المطعم وأنه قام بربط التكامل. إلى أن يتم تمكين قائمة شركاء OpenTable على المنصة، ستجيب مكالمة التحقق بـ 503.
التحقق من مطعم OpenTable
POST /appointments/opentable-restaurants/verify
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف مطعم OpenTable (RID)، وهو رقم مثل 1038007. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/opentable-restaurants/verify?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "1038007" }'
الاستجابة (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "1038007",
"diningAreaCount": 2,
"diningAreaNames": ["Main Room", "Garden"],
"tableTypes": ["default", "outdoor", "bar"]
}
}
}
تعني verified: false أنه لا يوجد مطعم OpenTable بهذا المعرف. وتعني 403 أن المطعم موجود ولكنه لم يربط تكامل المنصة داخل OpenTable بعد. الحد الأقصى للمحاولات هو 10 محاولات كل 5 دقائق لكل حساب.
إضافة مطعم OpenTable
POST /appointments/opentable-restaurants
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف المطعم الذي تم التحقق منه. |
restaurant_name |
نعم | اسم العرض (تسمية؛ وهو أيضاً ما يطلقه الذكاء الاصطناعي على المطعم). |
website_url |
لا | رابط http(s) يتم عرضه للضيوف عندما يحيلهم الذكاء الاصطناعي إلى المطعم. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/opentable-restaurants?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "1038007", "restaurant_name": "The Blue Door", "website_url": "https://thebluedoor.example" }'
الاستجابة (201 Created): { "success": true, "data": { "restaurantId": "1038007" } }
تحديث مطعم OpenTable محفوظ
PUT /appointments/opentable-restaurants/{restaurantId}
أرسل أيًا من restaurant_name أو is_active (أوقف مؤقتاً باستخدام false) أو website_url (سلسلة نصية فارغة تمسح القيمة)؛ الحقول المحذوفة تظل دون تغيير.
curl -X PUT "https://api.youraiconnector.com/v1/appointments/opentable-restaurants/1038007" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
الاستجابة (200 OK): { "success": true, "data": { "restaurantId": "1038007" } }
إزالة مطعم OpenTable
DELETE /appointments/opentable-restaurants/{restaurantId}
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/opentable-restaurants/1038007" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK): { "success": true, "data": { "restaurantId": "1038007" } }
تُرجع عملية تحديث restaurantId غير موجود حالياً في الحساب 404.
TheFork
يتم الوصول إلى مطاعم TheFork من خلال بيانات اعتماد شريك TheFork الخاصة بالمنصة، ولا تسمح TheFork لهذه البيانات إلا برؤية المطاعم التي قامت بتفعيل شريك المنصة على حسابها في TheFork. لذا، مثل Formitable وOpenTable، يكفي إجراء مكالمة تحقق واحدة: فمعرف المطعم (Restaurant ID) القابل للوصول يثبت وجود المطعم وأن الشريك مفعل عليه. المعرف هو UUID الذي تمنحه TheFork للمطعم في TheFork Manager، ويتم إرساله كسلسلة نصية. إلى أن توافق TheFork على المنصة كشريك وتصدر بيانات الاعتماد، ستجيب مكالمة التحقق بـ 503 — راجع TheFork لمعرفة ما يعنيه ذلك اليوم.
التحقق من مطعم TheFork
POST /appointments/thefork-restaurants/verify
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف مطعم TheFork، وهو UUID مثل 9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/thefork-restaurants/verify?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" }'
الاستجابة (200 OK):
{
"success": true,
"data": {
"verified": true,
"restaurantDetails": {
"restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60",
"partySizes": [1, 2, 3, 4, 5, 6, 7, 8]
}
}
}
partySizes هي أحجام المجموعات التي يقبلها المطعم عبر الإنترنت خلال الثلاثين يوماً القادمة. يعني 404 أو 403 أن TheFork لن تعطينا مطعماً بهذا المعرف — إما أن المعرف خاطئ، أو أن شريك المنصة غير مفعل على ذلك المطعم بعد؛ ويعني 400 أن المعرف ليس UUID. الحد الأقصى للمعدل هو 10 محاولات كل 5 دقائق لكل حساب.
إضافة مطعم TheFork
POST /appointments/thefork-restaurants
| الحقل | مطلوب | الوصف |
|---|---|---|
restaurant_id |
نعم | معرف المطعم الذي تم التحقق منه (UUID). |
restaurant_name |
نعم | اسم العرض (تسمية؛ وهو أيضاً ما يسمي به الذكاء الاصطناعي المطعم). |
website_url |
لا | رابط http(s) يتم عرضه للضيوف عندما يحيلهم الذكاء الاصطناعي إلى المطعم. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/thefork-restaurants?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "restaurant_id": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60", "restaurant_name": "The Blue Door", "website_url": "https://thebluedoor.example" }'
الاستجابة (201 Created): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }
تحديث مطعم TheFork محفوظ
PUT /appointments/thefork-restaurants/{restaurantId}
أرسل أيًا من restaurant_name أو is_active (أوقف مؤقتاً باستخدام false) أو website_url (سلسلة نصية فارغة تمسح القيمة)؛ الحقول المحذوفة تظل دون تغيير.
curl -X PUT "https://api.youraiconnector.com/v1/appointments/thefork-restaurants/9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
الاستجابة (200 OK): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }
إزالة مطعم TheFork
DELETE /appointments/thefork-restaurants/{restaurantId}
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/thefork-restaurants/9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK): { "success": true, "data": { "restaurantId": "9f2a1c34-5b6d-4e7f-8a90-1b2c3d4e5f60" } }
المطعم restaurantId غير الموجود حالياً في الحساب يُرجع 404 عند التحديث أو الحذف.
Trafft
يتم ربط Trafft مرة واحدة للحساب بالكامل، وليس لكل موقع: عنوان شركة واحد بالإضافة إلى بيانات اعتماد واجهة برمجة التطبيقات من لوحة تحكم Trafft (الميزات وعمليات التكامل ← واجهة برمجة التطبيقات والموصلات، وهي جزء من خطة الأعمال في Trafft). يتحقق استدعاء الربط من بيانات الاعتماد هذه مقابل Trafft قبل تخزين أي شيء، لذا فإن العنوان الخاطئ أو بيانات الاعتماد الخاطئة أو الخطة التي لا تحتوي على وصول لواجهة برمجة التطبيقات ستفشل هنا بدلاً من الفشل أثناء محادثة العميل. يتم تخزين سر العميل (client secret) مشفراً ولا يتم إرجاعه أبداً بواسطة أي نقطة نهاية.
تتطلب جميع استدعاءات الكتابة الثلاثة (POST، PUT، DELETE) إذن تعديل عمليات التكامل؛ بينما تتطلب الحالة GET إذن عرض عمليات التكامل.
ربط Trafft
POST /appointments/trafft/connect
| الحقل | مطلوب | الوصف |
|---|---|---|
subdomain |
نعم | عنوان الشركة — الجزء الذي يسبق .admin.trafft.com في عنوان URL الذي تسجل الدخول منه، على سبيل المثال acme. يتم قبول العنوان الكامل واختصاره إلى نفس القيمة. |
client_id |
نعم | معرف العميل (Client ID) من صفحة واجهة برمجة التطبيقات والموصلات في Trafft. |
client_secret |
نعم | سر العميل (Client Secret) من نفس الصفحة. يتم تخزينه مشفراً ولا يتم إرجاعه أبداً. |
company_name |
لا | تسمية لقائمتك الخاصة. |
curl -X POST "https://api.youraiconnector.com/v1/appointments/trafft/connect?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subdomain": "acme",
"client_id": "YOUR_TRAFFT_CLIENT_ID",
"client_secret": "YOUR_TRAFFT_CLIENT_SECRET",
"company_name": "Acme Salon"
}'
الاستجابة (200 OK):
{
"success": true,
"data": {
"subdomain": "acme",
"service_count": 12,
"employee_count": 4,
"location_count": 2
}
}
تأتي الأعداد من Trafft أثناء التحقق — وهي أسرع طريقة للتأكد من أن بيانات الاعتماد تشير إلى الحساب الذي تقصده.
الحصول على حالة الاتصال
GET /appointments/trafft
curl "https://api.youraiconnector.com/v1/appointments/trafft" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK):
{
"success": true,
"data": {
"connected": true,
"subdomain": "acme",
"hostname": "acme.admin.trafft.com",
"client_id": "YOUR_TRAFFT_CLIENT_ID",
"company_name": "Acme Salon",
"is_active": true,
"service_count": 12,
"employee_count": 4,
"location_count": 2
}
}
تعني connected: false أنه لم يتم إعداد أي شيء بعد. لا يتم تضمين سر العميل أبداً في هذا الرد.
تحديث الاتصال
PUT /appointments/trafft
| الحقل | مطلوب | الوصف |
|---|---|---|
is_active |
لا | اضبط false على الإيقاف المؤقت — سيتوقف الذكاء الاصطناعي عن الحجز في Trafft، ويبقى الاتصال قائماً. true يستأنفه. |
company_name |
لا | تسمية جديدة. |
curl -X PUT "https://api.youraiconnector.com/v1/appointments/trafft" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
الاستجابة (200 OK): نفس كائن الاتصال المذكور في GET أعلاه.
قطع اتصال Trafft
DELETE /appointments/trafft
curl -X DELETE "https://api.youraiconnector.com/v1/appointments/trafft" \
-H "X-API-Key: YOUR_API_KEY"
الاستجابة (200 OK): { "success": true }
يؤدي قطع الاتصال إلى إزالة بيانات الاعتماد المخزنة فقط. تظل المواعيد الموجودة بالفعل في Trafft دون تغيير.
شكل الخطأ في جميع نقاط نهاية Zenchef/Formitable/OpenTable/TheFork: على عكس بقية هذه الصفحة، تحمل الأخطاء هنا حالتها مرتين — مرة كحالة HTTP ومرة كـ
error_codeفي النص الأساسي — على سبيل المثال{ "success": false, "error": "Restaurant not found", "error_code": 404 }. تعامل معها بنفس طريقة التعامل مع أي خطأ آخر: تحقق منsuccess، واقرأerrorللحصول على الرسالة.
أخطاء واجهة برمجة تطبيقات المواعيد
تُرجع نقاط نهاية المواعيد غلاف الخطأ القياسي:
{
"success": false,
"error": "Appointment not found"
}
| الحالة | متى تحدث في نقطة نهاية الموعد |
|---|---|
400 |
حقل مطلوب مفقود أو غير صالح — على سبيل المثال start_time خاطئ، أو end_time ليس لاحقاً لـ start_time، أو تركيبة عوامل تصفية غير صالحة، أو عدم وجود حقول للتحديث، أو موعد ملغى بالفعل. عند الحجز: لم يتم إرسال event_id ولا title، أو تم إرسالهما معاً، أو تم إرسال كل من end_time و duration_minutes، أو تجاوز title 200 حرف، أو كان duration_minutes خارج النطاق 1–1440. |
404 |
لم يتم العثور على الموعد أو جهة الاتصال أو نوع الحدث. |
409 |
الفترة الزمنية المطلوبة محجوزة بالفعل (تعارض في الحجز)، أو عند التحديث، يكون external_reference مستخدماً بالفعل من قبل موعد آخر. |
الرموز المشتركة التي يمكن أن تُرجعها كل نقطة نهاية — 401، و 403 (خطتك لا تتضمن الوصول إلى واجهة برمجة التطبيقات)، و 429 (حد المعدل)، و 500 — مدرجة مع إرشادات إعادة المحاولة في الأخطاء والترقيم.
الخطوات التالية
- جهات الاتصال — إنشاء جهات الاتصال التي تحجز لها والبحث عنها.
- الرسائل والمحادثات — إرسال تأكيد أو تذكير إلى جهة اتصال.
- خطافات الويب (Webhooks) — تلقي إشعارات عند تغيير المواعيد.