صدى
English لوحة التحكم
المرجع / مرجع REST API

مرجع REST API

الـ REST API في صدى خمسة مسارات تحت https://sada.g4t.io/api/v1، موثّقة بمفتاحك السري. JSON في الطلب وJSON في الرد.

حُدّث في 21 أكتوبر 2026 عدّل هذه الصفحة

01الأساسيات

كل الطلبات تحمل Authorization: Bearer sk_… وContent-Type: application/json. المفتاح يحدّد التطبيق والبيئة. الاستجابات JSON؛ والأخطاء تحمل دائماً message.

العنصرالقيمة
الرابط الأساسي https://sada.g4t.io/api/v1
التوثيق Authorization: Bearer sk_test_… أو sk_live_…
الصيغة أجسام طلبات واستجابات JSON؛ الأوقات بتوقيت UTC بصيغة ISO 8601.
المعرّفات المكالمات call_ + 10 أحرف وأرقام صغيرة؛ الأحداث evt_….
الإصدار المسار يحمل الإصدار (/v1). الحقول تُضاف فقط ولا تُحذف.

02حدّ الطلبات

لكل مفتاح سري 120 طلباً في الدقيقة. فوق الحد يردّ الـ API بـ 429 مع Retry-After؛ وترويسات X-RateLimit-* المعتادة على كل استجابة. الطلبات بلا مفتاح صالح تُحدّ بحسب IP.

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
Retry-After: 37
{ "message": "Too Many Attempts." }

03المسارات

المفتاح لا يرى إلا مكالمات تطبيقه وبيئته؛ أي شيء آخر 404.

الطريقةالمسارالوصف
POST /calls إنشاء مكالمة.
GET /calls قائمة المكالمات، الأحدث أولاً، مقسّمة صفحات.
GET /calls/{call_id} مكالمة واحدة بمشاركيها وخطها الزمني.
POST /calls/{call_id}/tokens إصدار رمز انضمام لمشارك.
POST /calls/{call_id}/end إنهاء مكالمة حيّة.

04إنشاء مكالمةPOST /calls

يعيد 201 مع المكالمة. مع ring: true (الافتراضي) تبدأ المكالمة ringing؛ ومع ring: false تبدأ in_progress.

الاسمالنوعإلزاميالافتراضيالوصف
type string لا one_to_one one_to_one أو group.
ring boolean لا true استدعاء المتلقي بالرنين الأصلي.
region string لا auto auto أو baghdad أو dubai أو istanbul. يستخدم auto المنطقة الرئيسية لمؤسستك.
metadata object لا — حتى 20 مفتاحاً، يُعاد على المكالمة وفي الـ webhooks.
curl -X POST https://sada.g4t.io/api/v1/calls \
-H "Authorization: Bearer sk_test_4vN8kR2pXa61Jd0s" \
-H "Content-Type: application/json" \
-d '{"type": "one_to_one", "ring": true, "metadata": {"order_id": "ord_42"}}'
الاستجابة
1 {
2 "message": "Call created successfully",
3 "call": {
4 "call_id": "call_k3j9x2m7qa",
5 "env": "test",
6 "type": "one_to_one",
7 "status": "ringing",
8 "status_text": "Ringing",
9 "region": "baghdad",
10 "ring": true,
11 "metadata": { "order_id": "ord_42" },
12 "duration_seconds": 0,
13 "participant_minutes": 0,
14 "avg_latency_ms": null,
15 "started_at": "2026-10-21T09:30:00.000000Z",
16 "connected_at": null,
17 "ended_at": null,
18 "created_at": "2026-10-21T09:30:00.000000Z",
19 "updated_at": "2026-10-21T09:30:00.000000Z"
20 }
21 }

05قائمة المكالماتGET /calls

الأحدث أولاً، 20 في الصفحة افتراضياً، مع participants. تقسيم Laravel القياسي: data وlinks وmeta؛ مرّر page للصفحة التالية.

الاسمالنوعإلزاميالافتراضيالوصف
search string لا — يطابق معرّف المكالمة أو اسم المشارك أو user_ref.
status string لا — واحد من ringing أو in_progress أو completed أو missed أو declined أو failed.
type string لا — one_to_one أو group.
per_page integer لا 20 من 1 إلى 100.
page integer لا 1 رقم الصفحة.
curl "https://sada.g4t.io/api/v1/calls?status=ringing&per_page=20" \
-H "Authorization: Bearer sk_test_4vN8kR2pXa61Jd0s"
الاستجابة
1 {
2 "data": [
3 { "call_id": "call_k3j9x2m7qa", "status": "ringing", "type": "one_to_one", "participants": [ … ], … }
4 ],
5 "links": { "first": "…/api/v1/calls?page=1", "last": "…/api/v1/calls?page=1", "prev": null, "next": null },
6 "meta": { "current_page": 1, "last_page": 1, "per_page": 20, "total": 1, … }
7 }

06جلب مكالمةGET /calls/{call_id}

المكالمة مع participants والخط الزمني events ‏(call.created وcall.connected وcall.ended…). المعرّفات المجهولة ومكالمات التطبيقات الأخرى تردّ بـ 404 Call not found.

curl https://sada.g4t.io/api/v1/calls/call_k3j9x2m7qa \
-H "Authorization: Bearer sk_test_4vN8kR2pXa61Jd0s"
الاستجابة
1 {
2 "call_id": "call_k3j9x2m7qa",
3 "env": "test",
4 "type": "one_to_one",
5 "status": "completed",
6 "status_text": "Completed",
7 "region": "baghdad",
8 "ring": true,
9 "metadata": { "order_id": "ord_42" },
10 "duration_seconds": 600,
11 "participant_minutes": 20,
12 "avg_latency_ms": 48,
13 "started_at": "2026-10-21T09:30:00.000000Z",
14 "connected_at": "2026-10-21T09:30:04.000000Z",
15 "ended_at": "2026-10-21T09:40:00.000000Z",
16 "participants": [
17 { "user_ref": "u_1842", "display_name": "محمود عباس", "platform": "android", "muted": false,
18 "latency_ms": 52, "loss_pct": 0.4, "jitter_ms": 6, "joined_at": "…", "left_at": "…" },
19 { "user_ref": "u_77", "display_name": "حسين علاء", "platform": "ios", "muted": false,
20 "latency_ms": 44, "loss_pct": 0.1, "jitter_ms": 3, "joined_at": "…", "left_at": "…" }
21 ],
22 "events": [
23 { "type": "call.created", "ts": "…", "payload": { "type": "one_to_one", "env": "test", "ring": true, "region": "baghdad", "by": "api" } },
24 { "type": "call.connected", "ts": "…", "payload": { "region": "baghdad" } },
25 { "type": "call.ended", "ts": "…", "payload": { "reason": "hangup", "by": "api", "participant_minutes": 20 } }
26 ],
27 "created_at": "2026-10-21T09:30:00.000000Z",
28 "updated_at": "2026-10-21T09:40:00.000000Z"
29 }

07إصدار رمز انضمامPOST /calls/{call_id}/tokens

يعيد 201 مع الرمز ووقت انتهائه والمشارك. راجع رموز الانضمام للحقول والقواعد.

الاسمالنوعإلزاميالافتراضيالوصف
user_ref string ≤ 120 نعم — معرّفك للمستخدم.
display_name string ≤ 80 نعم — يظهر لبقية المشاركين.
ttl integer 60–3600 لا 300 العمر بالثواني.
curl -X POST https://sada.g4t.io/api/v1/calls/call_k3j9x2m7qa/tokens \
-H "Authorization: Bearer sk_test_4vN8kR2pXa61Jd0s" \
-H "Content-Type: application/json" \
-d '{"user_ref": "u_1842", "display_name": "محمود عباس", "ttl": 300}'
الاستجابة
1 {
2 "message": "Join token issued successfully",
3 "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzYWRhIiwic3ViIjoidV8xODQyIiwi…",
4 "expires_at": "2026-10-21T09:35:00.000000Z",
5 "participant": {
6 "user_ref": "u_1842",
7 "display_name": "محمود عباس",
8 "platform": null,
9 "muted": false,
10 "latency_ms": null,
11 "loss_pct": null,
12 "jitter_ms": null,
13 "joined_at": "2026-10-21T09:30:04.000000Z",
14 "left_at": null
15 }
16 }

08إنهاء مكالمةPOST /calls/{call_id}/end

يفصل كل المشاركين ويفوتر المكالمة. يُرسل call.ended (أو call.missed إن لم يتصل أحد) إلى الـ webhooks. المكالمة غير الحيّة تردّ بـ 422 Call is not live.

curl -X POST https://sada.g4t.io/api/v1/calls/call_k3j9x2m7qa/end \
-H "Authorization: Bearer sk_test_4vN8kR2pXa61Jd0s"
الاستجابة
{ "message": "Call ended successfully" }

09الكائنات

كائن المكالمة كما يعيده كل مسار.

الحقلالنوعالوصف
call_id string المعرّف العام.
env test | live بيئة المفتاح الذي أنشأها.
type one_to_one | group نوع المكالمة.
status string راجع الحالات أدناه.
status_text string تسمية status بلغة لوحة التحكم.
region string | null منطقة الترحيل.
ring boolean أُنشئت بالرنين الأصلي.
metadata object | null بياناتك الوصفية.
duration_seconds integer من started_at إلى ended_at، أو إلى الآن ما دامت حيّة.
participant_minutes integer الدقائق المفوترة؛ 0 حتى تنتهي المكالمة.
avg_latency_ms integer | null متوسط زمن الاستجابة بين المشاركين.
started_at timestamp وقت الإنشاء.
connected_at timestamp | null حين حصل المشارك الثاني على رمز.
ended_at timestamp | null حين انتهت المكالمة.
participants Participant[] في استجابتي القائمة والجلب.
events Event[] الخط الزمني؛ في استجابة الجلب فقط.
created_at timestamp إنشاء الصف.
updated_at timestamp آخر تغيير.

المشارك

الحقلالنوعالوصف
user_ref string معرّفك.
display_name string الاسم الظاهر.
platform string | null android أو ios أو web بعد اتصال الـ SDK.
muted boolean حالة الميكروفون.
latency_ms integer | null متوسط زمن الذهاب والإياب.
loss_pct number | null متوسط فقد الحزم، بالمئة.
jitter_ms integer | null متوسط التذبذب.
joined_at timestamp | null حين أُصدر الرمز.
left_at timestamp | null حين غادر، أو null.

الحالات

الحالةالمعنى
ringing بانتظار المتلقي.
in_progress متصلة، أو أُنشئت بلا رنين.
completed انتهت بعد الاتصال.
missed انتهت قبل الاتصال.
declined رفضها المتلقي.
failed تعذّر الاتصال.
✓ شكراً، وصلتنا ملاحظتك.