Skip to main content
Most analytics tools treat a signup like any other click. In Orwel a conversion is different: it becomes a lead, tied to the visitor and everything they did before, enriched with their company, scored, sent to your inbox and to your integrations (HubSpot, Hyperflow, Zapier, Brevo). Use track() for behavior and conversion() for the moments that matter to revenue.

The short version

Three rules cover almost every install:
  1. Await it before you navigate away or unmount the form.
  2. Always include email (or a phone).
  3. Call it once per outcome, after your own validation passed.

Examples by type of form

identify() links the anonymous visitor to the person, so their earlier visits show up on the lead.
Purchases confirmed only on your server (for example a Stripe webhook) can be created with POST /api/v1/leads and a secret key. Keep conversion() in the browser for everything the visitor does on your site, because only the browser knows the visitor and their campaign.

What the SDK does when you call it

1

Waits for the visitor

It waits up to 5 seconds for the visitor id, so the conversion attaches to the visitor and their history. If the id never resolves, nothing is sent and you get { success: false, reason: 'visitor_unresolved' }. A lead with no visitor behind it would have no history and no source.
2

Gives it an id

Each call gets a conversionId generated in the browser. The server deduplicates on it, so a retry or a double click creates one lead.
3

Adds the campaign

The first and last touch UTMs and ad click ids the SDK kept for this visitor travel with the conversion. See Attribution.
4

Sends immediately

A conversion does not wait for the next batch: it is sent on its own right away, with keepalive so it survives a page change. The promise resolves with what the server answered.

The result

A delivery problem never rejects the promise, so your form keeps working when Orwel is unreachable. The promise rejects only for invalid input: a code that is not snake_case, properties that are not an object, or a malformed email. Those are bugs to catch while you build, not at runtime.

Mistakes that lose leads

Choosing codes

Use snake_case codes that name the outcome: demo_request, contact_form, signup, trial_started, purchase, newsletter_signup. Unlike track(), conversion codes do not need to be in the workspace catalog. Keep one code per outcome rather than one per form. Two contact forms on different pages should both send contact_form; the visitor’s session already shows which page each one was sent from.

track or conversion

Where conversions show up

  • Leads lists every lead with its score, company and source. Open one to see the conversions, the pages visited before them and the campaign that brought the visitor.
  • Campaigns joins leads with ad spend, for cost per lead and cost per qualified lead.
  • Your inbox and email get a notification for each new lead from the production key.

Testing

Use the development key while you build. Conversions are stored as test leads with a Dev badge, no email or integration fires, and Dev mode shows each request with warnings such as a missing email or missing attribution. Add ?utm_source=test to the URL to check that attribution reaches the lead.

Attribution

How leads get their source and campaign.

Troubleshooting

What to do when a conversion fails.