askbowtie

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: '[email protected]',
  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:

How it appears in the dashboard:

Goal naming tips:


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:

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