# JavaScript API

> Plaintext version for LLMs. Canonical HTML: https://askbowtie.com/learn/tracker/javascript-api/

The tracker exposes the `askbowtie` object globally. Use it to report conversions, errors, and custom events that can't be captured automatically.

---

## Conversions

### `bowtie.converted(goalName, details)`

Report a conversion when a user completes a goal.

```
// Basic conversion
bowtie.converted('signup');

// With details
bowtie.converted('purchase', {
  value: 99.00,
  product: 'pro_plan',
  currency: 'USD'
});

// Lead capture
bowtie.converted('lead_captured', {
  source: 'contact_form',
  industry: 'saas'
});

// Affiliate click (custom goal)
bowtie.converted('affiliate_click', {
  destination: 'partner-site.com',
  campaign: 'summer_promo'
});

// With enhanced conversion data (for Google Ads)
bowtie.converted('purchase', {
  value: 99.00,
  email: 'customer@example.com',
  phone: '+1-555-123-4567',
  transaction_id: 'order_12345'
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `goalName` | string | Yes | Identifier for this conversion type. Appears in dropdowns and filters. |
| `details` | object | No | Additional context. See fields below. |

**Details fields:**

| Field | Type | Description |
| --- | --- | --- |
| `value` | number | Conversion value for revenue tracking |
| `currency` | string | Currency code (e.g., `USD`) |
| `transaction_id` | string | Unique ID for deduplication |
| `email` | string | Customer email (hashed automatically for Google Ads) |
| `phone` | string | Customer phone (hashed automatically for Google Ads) |
| `pixels` | boolean/string | Control ad pixel firing (see below) |

**Pixel control:**

- `true` or `'primary'` — Fire primary conversion label only
- `'secondary'` — Fire secondary conversion label only
- `false` or `'off'` — Don't fire any ad pixels

**How it appears in the dashboard:**

- Listed in conversion type dropdowns as the goal name
- Filterable via `type=api:goalName` (e.g., `type=api:signup`)
- Included in "All Conversions" totals
- Visible in session timelines

**Goal naming tips:**

- Use lowercase with underscores: `lead_captured`, `free_trial_started`
- Be specific: `checkout_completed` vs just `converted`
- Keep names short but descriptive

---

## Errors

### `bowtie.error(code, details)`

Report an application error that your code handles gracefully but you still want to track.

```
// Payment declined
bowtie.error('payment_declined', {
  reason: 'insufficient_funds',
  amount: 99.00
});

// Validation failed
bowtie.error('validation_failed', {
  field: 'email',
  message: 'Invalid email format'
});

// API error your code caught
bowtie.error('api_timeout', {
  endpoint: '/api/checkout',
  duration_ms: 30000
});

// Feature unavailable
bowtie.error('feature_unavailable', {
  feature: 'video_upload',
  reason: 'browser_not_supported'
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | Error code identifier. Used for grouping in warnings. |
| `details` | object | No | Additional context. `message` is displayed if provided. |

**When to use this:**

- Payment failures (declined cards, insufficient funds)
- Validation errors users encounter
- API errors your code catches and handles
- Feature detection failures
- Rate limiting or quota exceeded

These appear as **Application Errors** in the Warnings view, separate from JavaScript exceptions.

---

## Guardrails

### `bowtie.guardrail(code, details)`

Report when your application intentionally blocks or limits an action. Guardrails are **not errors** — they're safety measures working as intended.

```
// Rate limiting
bowtie.guardrail('rate_limited', {
  endpoint: '/api/checkout',
  limit: '10/min',
  user_id: 'usr_123'
});

// Payment declined (business decision, not system failure)
bowtie.guardrail('payment_declined', {
  reason: 'insufficient_funds',
  amount: 99.00
});

// Access denied
bowtie.guardrail('access_denied', {
  resource: '/admin/settings',
  required_role: 'admin'
});

// Geo-blocking
bowtie.guardrail('geo_blocked', {
  country: 'XX',
  feature: 'checkout'
});

// Bot filtering
bowtie.guardrail('bot_filtered', {
  signal: 'headless_browser',
  action: 'captcha_shown'
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | Guardrail identifier. Used for grouping and filtering. |
| `details` | object | No | Additional context about what triggered the guardrail. |

**When to use guardrails vs errors:**

| Scenario | Use |
| --- | --- |
| Rate limit hit | `guardrail` — working as designed |
| Payment declined by processor | `guardrail` — business logic |
| API timeout | `error` — system failure |
| Validation failed | `error` — user mistake |
| Bot blocked | `guardrail` — protection working |
| Database connection failed | `error` — infrastructure issue |

Guardrails are stored separately from errors, so they won't clutter your error reports but can still be tracked and analyzed.

---

## Custom Events

### `bowtie.track(eventType, data)`

Track custom events for analytics or debugging.

```
// Feature usage
bowtie.track('feature_used', {
  feature: 'dark_mode',
  action: 'enabled'
});

// Funnel step
bowtie.track('checkout_step', {
  step: 2,
  name: 'shipping_address'
});

// Custom analytics event
bowtie.track('pricing_viewed', {
  plan: 'pro',
  source: 'upgrade_banner'
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `eventType` | string | Yes | Event type identifier. |
| `data` | object | No | Event data. |

Custom events appear in session timelines and can be used for debugging user journeys.

---

## Utility Methods

### `bowtie.getSessionId()`

Returns the current session ID. Useful for support tickets or debugging.

```
const sessionId = bowtie.getSessionId();
console.log('Session:', sessionId);
// "a1b2c3d4e5f6..."

// Include in support forms
document.getElementById('session-field').value = bowtie.getSessionId();
```

### `bowtie.flush()`

Immediately sends all queued events. Call this before navigation if you need to ensure events are captured.

```
// Before programmatic navigation
bowtie.converted('purchase', { value: 99 });
bowtie.flush();
window.location.href = '/thank-you';
```

### `bowtie.debug(enable)`

Enables or disables debug mode for the current session. When enabled, events appear in real-time at `/debug` in your dashboard.

```
// Enable debug mode
bowtie.debug();      // or bowtie.debug(true)
// { enabled: true, session: 'abc123...', message: '...' }

// Disable debug mode
bowtie.debug(false);
// { enabled: false }
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `enable` | boolean | No | Pass `false` to disable. Defaults to `true`. |

Debug mode persists for the browser session (survives page navigation within the same tab).

**Tip:** You can also enable debug mode via URL: `?bowtie_debug=1`

---

## Safety Check

Always check if `askbowtie` exists before calling methods:

```
if (typeof askbowtie !== 'undefined') {
  bowtie.converted('signup');
}
```

Or use optional chaining:

```
window.bowtie?.converted('signup');
```

This prevents errors if the tracker hasn't loaded yet or is blocked.

---

## Complete Example

```
// After successful checkout
async function handleCheckout(cart) {
  try {
    const result = await processPayment(cart);

    if (result.success) {
      // Track the conversion
      askbowtie?.converted('purchase', {
        value: cart.total,
        items: cart.items.length,
        coupon: cart.couponCode || null
      });

      // Ensure it's sent before redirect
      askbowtie?.flush();

      window.location.href = '/thank-you';
    }
  } catch (error) {
    // Track the error
    askbowtie?.error('checkout_failed', {
      message: error.message,
      cart_value: cart.total
    });

    showErrorMessage(error.message);
  }
}
```

---

## Related

- [Debug View](/docs/) — Real-time event streaming for testing
- [Conversion Tracking](/docs/) — How conversions work in the dashboard
- [Error Tracking](/docs/) — Automatic and manual error capture
- [Session Reconstruction](/docs/) — View events in session timelines
