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:
trueor'primary'— Fire primary conversion label only'secondary'— Fire secondary conversion label onlyfalseor'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_completedvs justconverted - 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 — Real-time event streaming for testing
- Conversion Tracking — How conversions work in the dashboard
- Error Tracking — Automatic and manual error capture
- Session Reconstruction — View events in session timelines