حملة للمطوّرين

أخبر حملة بما حدث. وهي تتولى التسويق الذي يليه.

سطر واحد يرى المتصفح. وطلب HTTP واحد يخبر حملة بما جرى داخل نظامك أنت — دفعة، حجز، اشتراك أُلغي. وكل ما بعد ذلك شأن صاحب العمل، لا شأنك.

اطلب من وكيلك

Claude Code أو Cursor أو Codex — أو الصقه في Lovable و v0 و Bolt

ثبّت حملة على هذا الموقع وتتبّع التسجيلات والمشتريات

سطر التثبيت

انسخه من الإعدادات ← الموقع في حملة، أو دع لوحة التحكم تعطيك إياه. لا يحمل أي سرّ: معرّف النشاط بداخله ظاهر أصلاً في كل صفحة تُحمّل فيها المكتبة.

<script src="https://app.hamla.io/s/{businessId}.js" async></script>

هذا السطر وحده يغطي الزيارات ومصادرها والسلوك داخل الموقع وكل ما تستدعي لأجله hamla.track() في الصفحة — دون مفتاح، لأن حزمة منشورة لا تستطيع حفظ مفتاح.

أما الأحداث القادمة من خادمك فتحتاج مفتاحاً سرّياً: الإعدادات ← مفاتيح API، ويبدأ بـ sk_live_. أبقه على خادمك. يستطيع الكتابة في بيانات العملاء، فعامله معاملة كلمة مرور قاعدة البيانات.

الأحداث

سطر التثبيت لا يرى قاعدة بياناتك. حين يدفع أحدهم أو يحجز أو يلغي أو ينهي درساً، فذلك يقع في نظامك — واستدعاء واحد داخل كود موجود عندك أصلاً هو ما يتيح لحملة أن تتصرّف بناءً عليه.

curl -X POST https://app.hamla.io/api/sdk/track \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "event": "subscription_started",
    "type": "purchase",
    "identity": { "email": "omar@raqmi.co" },
    "value": 29,
    "currency": "JOD",
    "idempotencyKey": "invoice_9911"
  }'
الحقلماذا يفعل
identityمطلوبلمن حدث — واحد من email أو phone أو platformCustomerId. وواحد منها يكفي، ولا يلزم أن يكون البريد: عيادة لا تجمع سوى أرقام الهواتف ترسل phone وحده، دائماً.
eventمطلوباللحظة، بمفرداتك أنت، من حرف إلى 64 حرفاً. عيادة ترسل treatment_completed، ومدرسة ترسل lesson_finished. والمحفّزات والجماهير تطابقه حرفياً.
typeاختياريما الذي يعنيه الحدث، من الكلمات السبع أدناه. اتركه وستستنتج حملة من المبلغ ومن الأسماء التي تعرفها؛ أرسله ولن يُخمَّن شيء أبداً.
value, currencyاختياريالمبلغ وعملته. يُحتسب ضمن إيراد جهة الاتصال بحسب النوع — ومال العيادة مال.
occurredAtاختياريبصيغة ISO 8601 أو ميلي ثانية منذ الحقبة. الماضي مسموح، وهو ما يتيح استيراد السجل؛ وأبعد من خمس دقائق في المستقبل مرفوض.
propertiesاختياريأي JSON يستحق الحفظ مع الحدث، للأبد. حتى 32,768 بايت، تُخزَّن متداخلة لا مفروشة في جذر الحمولة.
traitsاختياريما هو صحيح الآن — plan و subscription_status. ينشئ حقله المخصص عند أول ظهور وتفوز آخر قيمة، فتستطيع الشرائح الترشيح عليه فوراً.
tagsاختياريتُضاف إلى وسوم جهة الاتصال دون أن تستبدل ما لديها.
idempotencyKeyاختياريرقم فاتورتك أو طلبك. المفتاح نفسه مرتين يُسجَّل مرة واحدة، وهذا ما يجعل إعادة المحاولة — أو إعادة تشغيل الاستيراد كاملاً — بلا تكلفة.

الكلمات السبع

اسم الحدث يبقى اسمك أنت وبلغتك أنت. و`type` هو كيف تقول ماذا تفعل حملة به — وهو الفرق بين أن تُحتسب مئة دينار في عيادة إيراداً وألّا تُحتسب شيئاً.

الحقلالمعنىالأثر
purchaseمبلغ مستلميضيف إلى الإيراد، ويُحتسب طلباً
refundمبلغ مُعاديخصم من الإيراد
bookingالتزام قبل الدفعبلا إيراد
leadتم التقاط بيانات التواصلبلا إيراد
checkout_startedبدأ ولم يُكملبلا إيراد
fulfilledتم التسليمبلا إيراد
cancelledانتهىبلا إيراد

الإرسال مجاني. والوصول إلى الناس هو ما يُدفع مقابله.

الأحداث لا تُحتسب أبداً، في أي خطة — أرسل كل ما لديك، إلى الأبد. و POST /api/sdk/track/batch يستقبل 500 حدث ماضٍ في المرة، فلا يكون يومك الأول يوماً صفرياً، والسجل المستورد لا يرسل رسالة إلى أحد.

ماذا يشتري لك حدث واحد

تكتب الاستدعاء مرة. وكل ما يلي يصبح متاحاً لمن يدير التسويق، دون أي كود إضافي منك.

يبدأ

حملة تنطلق عليه

رسالة متابعة بعد ساعة من treatment_completed. وتهيئة المشترك لحظة أن يدفع. لا غداً ولا في الدفعة التالية — بل حينها.

يختار

جمهور يُبنى منه

حقلان يظهران لكل اسم حدث: متى حدث آخر مرة، وكم مرة حدث. و«اشترى ٣ مرات فأكثر وانقطع ٦٠ يوماً» قائمة استرجاع تبقى صحيحة وحدها.

يوقف

تسلسل ينتهي عليه

من يفعل ما أردته يتوقف عن تلقّي الطلب، ويصير نجاح الحملة يُقاس عليه.

على Node

npm install @gethamla/node

طابور وإعادة محاولة و flush() لبيئات serverless. لا يرمي استثناءً ولا يحجب التنفيذ — والمفتاح الناقص يتحوّل إلى تحذير مسجَّل، لأن بيانات التسويق لا تساوي أبداً إتمام عملية شراء لعميل.

شغّل حملة من مساعدك

https://app.hamla.io/mcp

نقطة OAuth واحدة تكشف الأدوات نفسها التي يعمل عليها وكيل حملة: قراءة التحليلات، وبناء الحملات، وإدارة جهات الاتصال، واستيراد قائمة.

مُدرجة في سجل MCP باسم io.hamla/hamla، ومتاحة كتطبيق في ChatGPT.

إن كنت وكيلاً

كل ما سبق موجود بصيغة تستطيع تحليلها، مولَّدة من السجلات نفسها التي تتحقق بها الواجهة — فلا تستطيع هذه الصفحة أن تصف حقلاً سترفضه النقطة.

الفهرس

hamla.io/llms.txt

كل صفحة في هذا الموقع مع سطر يصفها. و docs.hamla.io/llms.txt يفهرس التوثيق كاملاً.

هذه الصفحة

hamla.io/developers.md

المحتوى نفسه بصيغة markdown — بلا وسوم تُزال ولا تخطيط يُخمَّن.

المرجع

docs.hamla.io/reference/events

حقلاً حقلاً، مع كل حالة خطأ ومعناها. الصيغة المطوّلة للجدول أعلاه.

GET /developers.md
# Hamla for developers

> Marketing automation a business installs with one script tag.
> Events are free and unmetered on every plan; contacts and sending are what cost.

## Install

Add before `</head>`. The business id comes from Settings → Website in Hamla
and is public — it appears in every page that loads the SDK.

```html
<script src="https://app.hamla.io/s/{businessId}.js" async></script>
```

This covers visits, sources, on-site behaviour, and `hamla.track()` calls made
in the page. No key: a published bundle cannot hold one.

## Events — POST /api/sdk/track

Server-side. Requires a secret key from Settings → API keys.

```
Authorization: Bearer sk_live_...
```

A publishable key (`pk_live_`) is refused with 403 here: it ships in page
source, so honouring it would let any visitor invent revenue.

```bash
curl -X POST https://app.hamla.io/api/sdk/track \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "event": "subscription_started",
    "type": "purchase",
    "identity": { "email": "omar@raqmi.co" },
    "value": 29,
    "currency": "JOD",
    "idempotencyKey": "invoice_9911"
  }'
```

### Fields

- `identity` **(required)** — Who it happened to — one of email, phone or platformCustomerId. Any one is enough, and it does not have to be the email: a clinic that only ever collects phone numbers sends phone, forever.
- `event` **(required)** — The moment, in your own vocabulary, 1–64 characters. A clinic sends treatment_completed, a school sends lesson_finished. Triggers and audiences match it exactly.
- `type` — What the event MEANS, from the seven below. Leave it out and Hamla infers from the amount and from names it recognises; send it and nothing is ever guessed.
- `value, currency` — The amount and its currency. Counted toward the contact's revenue according to the type — a clinic's money is money.
- `occurredAt` — ISO 8601 or epoch milliseconds. The past is allowed, which is what makes backfilling possible; more than five minutes into the future is refused.
- `properties` — Any JSON worth keeping with the event, forever. Up to 32,768 bytes, stored nested rather than spread into the payload root.
- `traits` — What is true NOW — plan, subscription_status. Creates its own custom field on first sight and newest value wins, so segments can filter on it immediately.
- `tags` — Merge-added to the contact, never replacing tags it already carries.
- `idempotencyKey` — Your invoice or order id. The same key twice is recorded once, which is what makes a retry — or a re-run of your whole backfill — free.

### What `type` means

Your `event` name stays yours, in your own language. `type` says what Hamla
should do with it.

- `purchase` — Money received. Adds to revenue, counts as an order.
- `refund` — Money returned. Subtracts from revenue.
- `booking` — Committed, not yet paid. No revenue.
- `lead` — Identity captured. No revenue.
- `checkout_started` — Started, not finished. No revenue.
- `fulfilled` — They received it. No revenue.
- `cancelled` — It ended. No revenue.

### Backfill — POST /api/sdk/track/batch

1–500 past events per request, same field rules, each with its real
`occurredAt`. Backfilled history **never starts a campaign** and never fires a
segment-entry trigger. Give every row an `idempotencyKey` and the job is safe
to re-run.

### Browser

`hamla.track('download_ebook', { asset: 'guide.pdf' })` — no key needed. These
count as deliberate and can start campaigns. Anything involving money or your
own records should come from your server.

## Node

```bash
npm install @gethamla/node
```

Wraps the same HTTP API with queueing and retries. Never throws, never blocks;
call `flush()` before a serverless runtime freezes.

## MCP

```
https://app.hamla.io/mcp
```

OAuth. Registry name `io.hamla/hamla`. Exposes the same tools Hamla's own
agent runs on — analytics, campaigns, contacts, segments, imports.

## More

- https://hamla.io/llms.txt — this site, indexed
- https://docs.hamla.io/llms.txt — the documentation, indexed
- https://docs.hamla.io/reference/events — every field and error status
- https://github.com/usehamla — agent skills and rules

Handles: `usehamla` on GitHub, `@gethamla` on npm, `hamla.io` on the web.

منتج واحد بثلاثة أسماء

usehamlaGitHub
@gethamlanpm
hamla.ioالويب

المرجع الكامل على docs.hamla.io