Registration widget

The registration widget is a single, dependency-free JS bundle (under 60 kB gzipped) that mounts a lead-capture form inside a Shadow DOM on any page — your own site, a landing page, anywhere. It never touches the host page's styles, and the host page never touches its internals.

The script tag

html
<script
  src="https://cdn.institflow.com/widget.js"
  data-key="ifl_pub_9c1f2e7a4b8d3c6f0a5e9b2d7c4f1a8e"
  data-locale="ar"
  data-course-id="0190a1b2-0000-7000-8000-000000000002"
></script>

Drop it anywhere in your page's body. The widget reads its own <script> tag's attributes at load time — it must be a classic script (no type="module"), since that's the only way it can find its own tag on the page.

data-* attributes

AttributeRequiredDescription
data-keyYesYour publishable key (ifl_pub_…). Never a secret key.
data-localeNo"en", "ar", or "he" — defaults to the browser's language, falling back to "en".
data-courseNoFree-text course interest, recorded on the enquiry.
data-course-idNoThe id of a course from GET /public/courses — recorded as a real reference, unlike the free-text data-course.
data-group-idNoThe id of a specific group of that course.
data-captcha-site-keyNoYour Cloudflare Turnstile site key (the integration.captchaSiteKey setting). Set it and the form shows a challenge and will not submit without one.
data-themeNo"light", "dark", or "auto" (default — follows the visitor's OS preference).

What it creates

A submission calls POST /api/v1/public/registrations with your publishable key, which:

  • Creates a lead-status student, tagged widget-lead, in the key's tenant's default branch.
  • Creates (or reuses, matched by phone, if one already exists) a guardian, linked as primary and payer.
  • Emits student.created — the same event your webhook endpoints already subscribe to.

From there it's a normal student in your system: appears in GET /api/v1/students with status lead, ready to be enrolled once someone on your team follows up.

Origin allowlist and rate limits

Each publishable key only works from the origins you explicitly allow when creating it — an empty allowlist accepts no origin. Submissions are rate-limited per IP (30/minute) and per key (300/day).

Styling & theming

The form's colors, spacing, radius, and type come straight from the same design tokens the rest of Institflow uses, so it feels native next to your own product rather than an obviously embedded iframe. It respects data-theme (or the OS preference), lays out right-to-left automatically for ar/he using logical CSS properties (never a separate RTL stylesheet), and shows its own success/failure state inline — no page navigation, no popup.