واجهة HTTP
أي شيء يستطيع إرسال طلب HTTPS يستطيع إرسال الأحداث. استخدم هذه الواجهة للطلبات التي تُؤكَّد بعد أن يغادر المشتري، وللاسترجاعات الصادرة من لوحة الإدارة، ولأي نظام لا متصفح فيه.
العنوان الأساسي: https://edge.flofy.co
المسارات
| المسار | الصيغة المختصرة | type | لأجل |
|---|---|---|---|
/v1/track | /v1/t | track | وقوع شيء ما |
/v1/identify | /v1/i | identify | من يكون الشخص |
/v1/page | /v1/p | page | زيارة صفحة |
/v1/screen | /v1/s | screen | عرض شاشة داخل تطبيق |
/v1/group | /v1/g | group | ربط شخص بشركة |
/v1/alias | /v1/a | alias | معرّفان لشخص واحد |
/v1/batch | /v1/b | — | عدة أحداث دفعة واحدة |
كلها POST مع Content-Type: application/json. والصيغ المختصرة تتصرّف تمامًا كالطويلة.
المصادقة
مفتاح الكتابة يوضع في ترويسة HTTP Basic، بوصفه اسم المستخدم مع كلمة مرور فارغة. رمّز المفتاح متبوعًا بنقطتين بترميز Base64:
printf 'YOUR_WRITE_KEY:' | base64
Authorization: Basic <that value>
النقطتان في آخره مطلوبتان، وكلمة المرور غير الفارغة تُرفض.
ويمكنك تمرير المفتاح كمعامل استعلام بدلًا من ذلك — ?writeKey=<base64 of the key> — وهذا ما تفعله مكتبة المتصفح، لتبقى الطلبات خالية من طلب CORS التمهيدي. وحين يوجد الاثنان معًا، يفوز معامل الاستعلام.
نموذج طلب
curl -X POST https://edge.flofy.co/v1/track \
-H "Authorization: Basic $(printf 'YOUR_WRITE_KEY:' | base64)" \
-H "Content-Type: application/json" \
-d '{
"type": "track",
"event": "Order Completed",
"userId": "customer_9931",
"messageId": "8f14e45f-ea0a-4c1f-9f2c-3b7d1a0e5c62",
"timestamp": "2026-08-25T10:31:00.000Z",
"properties": {
"order_id": "ORD-12345",
"currency": "SAR",
"value": 523.17,
"products": [
{ "product_id": "P-4471", "name": "Wireless Headphones", "price": 199.99, "quantity": 1 }
]
}
}'
الغلاف
| الحقل | مطلوب | المعنى |
|---|---|---|
type | نعم | يجب أن يطابق المسار |
event | في track | اسم الحدث |
messageId | نعم | فريد لكل حدث. وUUID يفي بالغرض |
timestamp | نعم | وقت وقوعه — ISO 8601 بتوقيت UTC |
userId | أحد الاثنين | معرّفك لشخص تعرفه |
anonymousId | أحد الاثنين | معرّف لشخص غير مسجّل الدخول |
properties | في track | خصائص الحدث |
traits | في identify | ما تعرفه عن الشخص |
context | لا | الصفحة والحملة وعنوان IP ووكيل المستخدم |
integrations | لا | تشغيل وجهات بعينها أو إيقافها |
messageId هو ما يجعل إعادة المحاولة تُعرَف بوصفها الحدث نفسه لا حدثًا ثانيًا. أنشئه مرة واحدة لكل حدث، وأعد استخدامه إن أعدت المحاولة.
حقول الغلاف بصيغة camelCase — userId وmessageId. وكل ما داخل properties وtraits بصيغة snake_case — order_id وfirst_name. الفصل مقصود: الغلاف يصف الرسالة، والخصائص تصف متجرك.
السياق
المكتبة تملأ هذا الحقل من المتصفح. أما عبر HTTP فترسل ما لديك، وكله اختياري:
{
"context": {
"ip": "203.0.113.9",
"userAgent": "Mozilla/5.0 …",
"locale": "ar-SA",
"timezone": "Asia/Riyadh",
"page": {
"url": "https://store.example.com/checkout",
"path": "/checkout",
"referrer": "https://www.google.com/"
},
"campaign": {
"source": "facebook",
"medium": "cpc",
"name": "ramadan-2026"
}
}
}
ip وuserAgent هما الحقلان اللذان يستحقان العناء. ميتا وتيك توك وسناب شات تستخدمهما لمطابقة تحويل من جهة الخادم بمشاهدة إعلان، وبدونهما يبقى جزء من طلباتك بلا إسناد. أرسل عنوان المشتري، لا عنوان خادمك.
الدفعات
{
"batch": [
{
"type": "identify",
"userId": "customer_9931",
"messageId": "…",
"timestamp": "…",
"traits": { "email": "sara@example.com" }
},
{
"type": "track",
"event": "Order Completed",
"userId": "customer_9931",
"messageId": "…",
"timestamp": "…",
"properties": { "order_id": "ORD-12345", "currency": "SAR", "value": 523.17 }
}
]
}
كل عنصر حدث كامل، له type وmessageId وtimestamp خاصة به. وتُتحقَّق العناصر كلها قبل قبول أي منها، فعنصر واحد معطوب يرفض الطلب كله — وهذا ما يجعل إعادة إرسال الطلب كوحدة واحدة آمنة.
الحدود
| الحدث الواحد | 256 KB |
| طلب الدفعة | 5 MB |
| عدد الأحداث في الدفعة | 1,000 |
الردود
| الرمز | المعنى |
|---|---|
204 | وصل |
400 | مفتاح كتابة ناقص أو معطوب، أو JSON غير صالح، أو عنصر دفعة خاطئ |
413 | أكثر من 1,000 حدث في دفعة واحدة |
503 | تعذّر على فلوفاي قبول الحدث — أعد المحاولة مع تباعد زمني |
لا جسم للرد عند النجاح. الرمز 204 يعني أن الطلب سليم البنية، لا أن مفتاح الكتابة يطابق مصدرًا: مفتاح يبدو صالحًا لمصدر غير موجود يُقبل هنا ثم يُسقَط لاحقًا. تأكّد من الأحداث المباشرة في صفحة المصدر داخل فلوفاي.
إذا واجهت مشكلة
اعمل على هذه القائمة بالترتيب:
- هل الترويسة صحيحة؟
Basic، ثم مسافة، ثم ترميز base64 لـkey:— بالنقطتين. - هل
typeيطابق المسار؟ جسمtrackيُرسَل إلى/v1/identifyلن يفعل ما قصدته. - هل الهوية داخل الجسم؟ لا بد أن يكون
userIdأوanonymousIdداخل الـJSON. والترويسة لا تُغني عنه. - هل
timestampبصيغة ISO 8601 وبتوقيت UTC؟2026-08-25T10:31:00.000Z، لا طابع زمني بصيغة Unix. - هل الخصائص بصيغة snake_case؟
order_idلاorderId. الصيغة الخاطئة تُقبل ثم تُهمَل، فيبدو الأمر مشكلة تسليم وهو ليس كذلك. - هل اسم الحدث يطابق المرجع؟ راجع مرجع الأحداث.