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

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

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

اطلب من وكيلك

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

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

سطر التثبيت

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

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

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

المفتاح السرّي يبقى على خادمك

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

لا حساب بعد؟ ثبّتها الآن.

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

  1. أنشئ التثبيت

    POST /api/install
    curl -X POST https://app.hamla.io/api/install \
      -H "Content-Type: application/json" \
      -d '{
        "website": "raqmi.co",
        "name": "Raqmi",
        "locale": "en"
      }'

    خمسة تثبيتات في الساعة لكل عنوان IP.

  2. ضع الكود في الصفحة

    200 OK
    {
      "success": true,
      "data": {
        "businessId": "cmf8q1x4k0000",
        "snippet": "<script src=\"https://app.hamla.io/s/cmf8q1x4k0000.js\" async></script>",
        "claimUrl": "https://app.hamla.io/claim/9f3c...",
        "expiresAt": "2026-09-19T08:00:00.000Z",
        "note": "This install records anonymous traffic only until it is claimed. Print the claim link for the person who owns the site — it is single-use and expires."
      },
      "message": "Install created"
    }

    ضع snippet في الصفحة، واطبع claimUrl لصاحب الموقع — هذا هو الشيء الوحيد الذي لا يستطيعه غيرك، والتثبيت يُحذف إن لم يتبعه أحد.

  3. اطبع رابط الاستلام لصاحب الموقع

    ما يراه المالك حين يفتح ذلك الرابط: زياراته هو — الزوّار، ومن أين أتوا، وكم وصل إلى الدفع وغادر — وزرّ واحد. لا استمارة تسجيل.

مجهول فقط

حتى يُستلم، تسجّل الزيارات ولا شيء أكثر

مشاهدات الصفحات والجلسات والمصادر والأحداث داخل الموقع. وأي identity يحمل بريداً أو رقم هاتف يُرفض بـ 422 وبجملة تسمّي الاستلام حلاً — ولا يُسقط بصمت. أما platformCustomerId فمسموح: هو معرّفك المبهم ولا يدل على أحد خارج نظامك.

بلا بيانات اعتماد

لا مفتاح يمكن تسريبه

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

لا إرسال

لا حملة تنطلق قبل الاستلام

لا شيء يراسل شخصاً حقيقياً قبل أن يملك أحدهم النشاط ويستطيع الإجابة عنه.

٧٢ ساعة

الرابط يعمل مرة واحدة، ثم يُحذف التثبيت

مدة تكفي للوصول إلى مالك ليس هو الشخص الذي تعمل معه، في يوم العمل التالي. وإن لم يستلمه أحد، حُذف النشاط وكل ما جمعه.

تستخدم Lovable أو v0 أو Bolt؟

هذه الأدوات لا تستطيع تثبيت مهارة ولا وصل خادم MCP — الطريق الوحيد إليها نصٌّ تلصقه. وهذا النص يحمل الإجراء كاملاً بدل أن يشير إليه، لأن أداة تقرأ التعليمة نصف قراءة تكتب قيمة وهمية.

Add Hamla to this site so I get analytics and marketing on it.

1. POST to https://app.hamla.io/api/install with JSON {"website": "<this site's domain>"}.
   No API key, no account, no auth header. It returns
   { "data": { "businessId", "snippet", "claimUrl" } }.
2. Put the returned "snippet" string in the <head> of every page, exactly as given.
   Do not invent or edit the business id inside it.
3. When you are done, show me the "claimUrl" value. I need it to take ownership —
   it works once and expires in 72 hours.

Rules: never send a customer's email or phone to Hamla from this site, and never
put a Hamla secret key in front-end code. Neither is needed for the above.

الصقه كما هو. وإن كانت أداتك لا تستطيع إرسال طلب أثناء عملها، نفّذ الأمر أعلاه بنفسك وأعطها الكود الذي يعود.

الأحداث

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

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
انتهى — بلا إيراد
signup
تم إنشاء حساب — بلا إيراد
trial
بدأت تجربة مجانية — بلا إيراد
contact
تواصل معك — بلا إيراد
application
قدّم طلبًا — بلا إيراد

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

الأحداث لا تُحتسب أبداً، في أي خطة — أرسل كل ما لديك، إلى الأبد. و 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

> Hamla is an AI marketing agent 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.

## No account yet — POST /api/install

If you are an agent building someone a site, you do not have their Hamla login
and you will not get one mid-task. This returns a working install immediately,
with no authentication and no key issued.

```bash
curl -X POST https://app.hamla.io/api/install \
  -H "Content-Type: application/json" \
  -d '{
    "website": "raqmi.co",
    "name": "Raqmi",
    "locale": "en"
  }'
```

```json
{
  "success": true,
  "data": {
    "businessId": "cmf8q1x4k0000",
    "snippet": "<script src=\"https://app.hamla.io/s/cmf8q1x4k0000.js\" async></script>",
    "claimUrl": "https://app.hamla.io/claim/9f3c...",
    "expiresAt": "2026-09-19T08:00:00.000Z",
    "note": "This install records anonymous traffic only until it is claimed. Print the claim link for the person who owns the site — it is single-use and expires."
  },
  "message": "Install created"
}
```

Put `snippet` in the page. **Print `claimUrl` for the person who owns the
site** — that is the one step only you can take, and the install is deleted if
nobody follows it.

What an unclaimed install may do, and what it refuses:

- **Anonymous traffic only.** Page views, sessions, sources, on-site events. An
  `identity` carrying an `email` or `phone` is refused with **422** and a
  sentence naming the claim as the fix — never silently dropped.
  `platformCustomerId` stays allowed: it is your own opaque id and names
  nobody outside your system.
- **No credential is issued.** The snippet carries a business id, which is
  already public in every page that loads the SDK. `sk_live_` comes from
  Settings → API keys, after a human owns the business.
- **No campaign can launch.** Nothing messages a real person until someone owns
  the business and can answer for it.
- **Five installs per hour per IP.**
- **The claim link works once and expires in 72 hours.** If nobody claims it,
  the business and everything it collected are deleted.

The owner opening that link sees their own traffic — visitors, sources, how
many reached checkout and left — and one button. Not a signup form.

### Lovable, v0, Bolt

They cannot install a skill or connect an MCP server, so paste this in:

```
Add Hamla to this site so I get analytics and marketing on it.

1. POST to https://app.hamla.io/api/install with JSON {"website": "<this site's domain>"}.
   No API key, no account, no auth header. It returns
   { "data": { "businessId", "snippet", "claimUrl" } }.
2. Put the returned "snippet" string in the <head> of every page, exactly as given.
   Do not invent or edit the business id inside it.
3. When you are done, show me the "claimUrl" value. I need it to take ownership —
   it works once and expires in 72 hours.

Rules: never send a customer's email or phone to Hamla from this site, and never
put a Hamla secret key in front-end code. Neither is needed for the above.
```

## 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 list 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.
- `signup` — Account created. No revenue.
- `trial` — Free trial started. No revenue.
- `contact` — Reached out. No revenue.
- `application` — Applied. 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