> ## Documentation Index
> Fetch the complete documentation index at: https://learn.biq.li/llms.txt
> Use this file to discover all available pages before exploring further.

# Client-side conversion tracking

> Track leads and sales from the browser with safe identities and retries.

Browser conversion tracking is useful for actions known only to client code. Prefer server tracking when your backend can verify the result.

## Track a lead

```ts theme={null}
const result = await biqli.trackLead({
  eventId: 'signup:customer_1842',
  eventName: 'Signed up',
  customerExternalId: 'customer_1842',
  customerName: 'Ada Lovelace',
  customerEmail: 'ada@example.com',
  metadata: {plan: 'pro'},
});
```

The SDK uses its stored click ID when `clickId` is omitted.

## Track a sale

```ts theme={null}
const result = await biqli.trackSale({
  customerExternalId: 'customer_1842',
  amount: 4999,
  currency: 'usd',
  eventName: 'Purchase',
  paymentProcessor: 'custom',
  invoiceId: 'order_9381',
});
```

`4999` means \$49.99 USD. Amounts use integer minor units.

## Handle queued results

Temporary network and server failures are placed in a bounded browser retry queue.

```ts theme={null}
const result = await biqli.trackLead(input);

if ('queued' in result) {
  console.log('The event will retry', result.eventId);
} else {
  console.log('Created event', result.event.id);
}
```

The default queue:

* stores at most 100 events;
* expires events after seven days;
* stops after eight failed delivery attempts;
* retries with bounded exponential backoff and jitter;
* separates records by publishable key and API host.

Calling `setConsent(false)` clears the queue.

## Keep identifiers stable

Create an identifier from the business event, not from the request attempt.

```ts theme={null}
// Good: identical for every retry of this signup
eventId: `signup:${customer.id}`

// Good: identical for every retry of this order
invoiceId: order.id
```

Do not use a fresh timestamp or random ID every time retry code runs. That would describe a new logical event.

## Know the browser limitation

A browser event can be blocked by privacy software, lose connectivity, or disappear when storage is cleared. Do not use browser code as the only authority for paid orders, refunds, renewals, or other financial state.

For trusted events, forward `bq_id` to your backend and use the [server quickstart](/developers/server/quickstart).
