Getting Started with Multibuzz

Server-side multi-touch attribution tracking for your application.


Platform Integrations

Using a supported platform? Follow the dedicated guide:

Platform Integration Type Guide
Shopify Zero-code (App + Pixel) Shopify Integration →
Server-Side GTM Tag template (no code) sGTM Integration →

For custom applications, continue with the SDK integration below.


The 4-Call Model

Multibuzz uses a simple 4-call SDK model:

Method Purpose When to Call
init Configure SDK App startup
event Track journey steps User interactions (page views, add to cart, etc.)
conversion Track revenue outcomes Purchases, signups, subscriptions
identify Link visitor to user Login, signup (enables cross-device attribution)

That's it. Four methods to complete multi-touch attribution.


Quick Start

1. Get Your API Key

  1. Log in to your dashboard
  2. Navigate to API Keys
  3. Click Create API Key
  4. Choose Test environment for development
  5. Copy your API key (starts with sk_test_...)

2. Install the Client Library

# Gemfile gem 'mbuzz' # Then run: bundle install
npm install mbuzz # or yarn add mbuzz
pip install mbuzz # or uv pip install mbuzz
No installation needed. Use any HTTP client.

3. Initialize (init)

# config/initializers/mbuzz.rb Mbuzz.init( api_key: ENV['MBUZZ_API_KEY'], debug: Rails.env.development? )
// app.js or server.js const mbuzz = require('mbuzz'); mbuzz.init({ apiKey: process.env.MBUZZ_API_KEY, debug: process.env.NODE_ENV === 'development' });
# app.py or settings.py import os import mbuzz mbuzz.init( api_key=os.environ['MBUZZ_API_KEY'], debug=os.environ.get('FLASK_ENV') == 'development' )
# Set your API key as environment variable export MBUZZ_API_KEY=sk_test_your_key_here # Use in Authorization header curl -H "Authorization: Bearer $MBUZZ_API_KEY" \ https://mbuzz.co/api/v1/events

⚠️ Security: Never commit API keys to git. Use environment variables.


4. Track Events (event)

Track steps in the customer journey:

# Track user interactions Mbuzz.event("page_view", url: "/pricing") Mbuzz.event("add_to_cart", product_id: "SKU-123", price: 49.99) Mbuzz.event("checkout_started", cart_total: 99.99) # Group events into funnels for focused analysis Mbuzz.event("signup_start", funnel: "signup", source: "homepage") Mbuzz.event("signup_complete", funnel: "signup")
// Track user interactions mbuzz.event('page_view', { url: '/pricing' }); mbuzz.event('add_to_cart', { productId: 'SKU-123', price: 49.99 }); mbuzz.event('checkout_started', { cartTotal: 99.99 }); // Group events into funnels for focused analysis mbuzz.event('signup_start', { funnel: 'signup', source: 'homepage' }); mbuzz.event('signup_complete', { funnel: 'signup' });
# Track user interactions mbuzz.event('page_view', url='/pricing') mbuzz.event('add_to_cart', product_id='SKU-123', price=49.99) mbuzz.event('checkout_started', cart_total=99.99) # Group events into funnels for focused analysis mbuzz.event('signup_start', funnel='signup', source='homepage') mbuzz.event('signup_complete', funnel='signup')
curl -X POST https://mbuzz.co/api/v1/events \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "event_type": "add_to_cart", "visitor_id": "abc123...", "funnel": "purchase", "properties": { "product_id": "SKU-123", "price": 49.99 } }'

Core Concepts

Sessions (The Foundation of Attribution)

A session is a single visit to your site with acquisition context. Sessions are the touchpoints used for attribution.

What a session captures:
- UTM parameters (utm_source, utm_medium, utm_campaign, etc.)
- Referrer URL (for organic/referral traffic)
- Channel (derived from UTMs + referrer: paid_search, organic, email, etc.)
- Landing page

Session behavior:
- Auto-created: SDK middleware creates sessions automatically
- 30-minute timeout: New session after 30 min of inactivity
- Non-blocking: Session POST is async (doesn't slow your app)

Why sessions matter: Without sessions, you can't know how a visitor arrived. Sessions make multi-touch attribution possible.

Visitors

Anonymous users tracked via cookies.

  • Lifetime: 2 years
  • Auto-generated: By SDK (64-char hex, stored in _mbuzz_vid cookie)
  • Thread-safe: Works with multi-threaded servers
  • Privacy-first: No PII required

A single person may have multiple visitors (multiple devices/browsers).

Users

Known, identified users in your system.

  • Cross-device: One user identity across all devices
  • Permanent: Persists beyond cookies
  • Your ID: Use your application's user identifier

Link visitors to users with the identify() method.

Events

Actions users take in your application.

Required fields:
- event_type - Event name (e.g., "signup", "purchase", "add_to_cart")
- user_id OR visitor_id - At least one identifier required

Recommended fields:
- session_id - Links event to session for attribution
- funnel - Group events into funnels for focused analysis

Optional fields:
- properties - Custom metadata (JSON object)
- timestamp - When event occurred (defaults to now)

Funnels

Group related events into funnels for focused conversion analysis.

Why use funnels?
- Separate signup flow from purchase flow
- Analyze each conversion path independently
- Filter dashboard to specific customer journeys

Example funnels:

# Signup funnel Mbuzz.event("pricing_view", funnel: "signup") Mbuzz.event("signup_start", funnel: "signup") Mbuzz.event("signup_complete", funnel: "signup") # Purchase funnel Mbuzz.event("add_to_cart", funnel: "purchase") Mbuzz.event("checkout_started", funnel: "purchase") Mbuzz.event("purchase_complete", funnel: "purchase")
// Signup funnel mbuzz.event('pricing_view', { funnel: 'signup' }); mbuzz.event('signup_start', { funnel: 'signup' }); mbuzz.event('signup_complete', { funnel: 'signup' }); // Purchase funnel mbuzz.event('add_to_cart', { funnel: 'purchase' }); mbuzz.event('checkout_started', { funnel: 'purchase' }); mbuzz.event('purchase_complete', { funnel: 'purchase' });
# Signup funnel mbuzz.event('pricing_view', funnel='signup') mbuzz.event('signup_start', funnel='signup') mbuzz.event('signup_complete', funnel='signup') # Purchase funnel mbuzz.event('add_to_cart', funnel='purchase') mbuzz.event('checkout_started', funnel='purchase') mbuzz.event('purchase_complete', funnel='purchase')
# Include funnel in event properties curl -X POST https://mbuzz.co/api/v1/events \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "events": [{ "event_type": "signup_start", "visitor_id": "abc123...", "funnel": "signup" }] }'

Dashboard filtering: Use the funnel dropdown to view specific funnels. "All Funnels" shows everything.


Automatic Session Tracking

The SDK includes middleware that automatically tracks visitors and enables server-side session resolution.

What happens on each request:
1. SDK checks for existing visitor cookie (_mbuzz_vid)
2. SDK captures IP address and User-Agent
3. Events are sent to API with visitor context
4. Server resolves sessions using device fingerprint + 30-minute sliding window

Context captured automatically:
- Full URL (including UTM parameters)
- Referrer URL
- User-Agent (for session resolution)
- IP address (for session resolution + geo lookup)

Session resolution (server-side):
- Server generates device fingerprint from IP + User-Agent
- Finds active session for visitor + fingerprint (activity < 30 min ago)
- Creates new session if no active session found
- True 30-minute sliding window (not fixed time buckets)

The API handles:
- Session resolution and creation
- UTM parameter extraction
- Referrer analysis
- Channel derivation (paid_search, organic, email, etc.)
- Visitor/Session record creation

Important: All API calls are async and non-blocking. Your page render is not slowed.

Disable if needed:

# config/initializers/mbuzz.rb Mbuzz.init( api_key: ENV['MBUZZ_API_KEY'], skip_paths: ["/health", "/admin"] # Skip specific paths )
// app.js or server.js mbuzz.init({ apiKey: process.env.MBUZZ_API_KEY, skipPaths: ['/health', '/admin'] // Skip specific paths });
# app.py mbuzz.init( api_key=os.environ['MBUZZ_API_KEY'], skip_paths=['/health', '/admin'] # Skip specific paths )
N/A - Session tracking is SDK-only. REST API users manage their own sessions.

Background Jobs & Async Processing

When tracking events from background jobs or async processes (e.g., Sidekiq, Celery, queue workers),
there's no HTTP request context. This means the SDK cannot automatically capture the visitor ID from cookies.

The Problem

ruby
Background Job Mbuzz.event('order_shipped', ...) No HTTP Request = No Cookies = No visitor_id Event rejected or orphan visitor created

Solution 1: Rails 7+ with CurrentAttributes (Automatic)

For Rails 7+ applications, the Ruby SDK uses ActiveSupport::CurrentAttributes which Rails
automatically serializes into ActiveJob payloads. No code changes required - it just works!

# Controller - just enqueue the job, visitor_id is captured automatically class OrdersController < ApplicationController def create @order = Order.create!(order_params) ProcessOrderJob.perform_later(@order.id) # visitor_id automatically captured from request context end end # Background job - mbuzz just works! class ProcessOrderJob < ApplicationJob def perform(order_id) order = Order.find(order_id) # Mbuzz::Current.visitor_id was restored by Rails automatically Mbuzz.event('order_processed', order_id: order.id) Mbuzz.conversion('purchase', revenue: order.total) end end

How it works:
1. Middleware captures visitor_id from cookie into Mbuzz::Current
2. Controller enqueues job
3. Rails serializes Mbuzz::Current into job payload
4. Job runs → Rails restores Mbuzz::Current
5. Mbuzz.conversion() reads from Current - works!

Solution 2: Store visitor_id on Records (All Platforms)

For non-Rails applications, or when you need more control:

  1. Capture visitor_id in the request context when creating the record
  2. Store it on the record (e.g., order.mbuzz_visitor_id)
  3. Pass it explicitly when tracking from background jobs
# 1. Store visitor_id when order is created (in controller) class OrdersController < ApplicationController def create @order = current_user.orders.build(order_params) @order.mbuzz_visitor_id = Mbuzz.visitor_id # Capture while in request @order.save! end end # 2. Pass visitor_id explicitly in background job class OrderProcessingJob < ApplicationJob def perform(order_id) order = Order.find(order_id) # Pass visitor_id explicitly - required! Mbuzz.event('order_processed', visitor_id: order.mbuzz_visitor_id, order_id: order.id ) Mbuzz.conversion('purchase', visitor_id: order.mbuzz_visitor_id, revenue: order.total ) end end
// 1. Store visitor_id when order is created (in controller) $order = new Order($request->all()); $order->mbuzz_visitor_id = Mbuzz::visitorId(); $order->save(); // 2. Pass visitor_id explicitly in background job class OrderProcessingJob implements ShouldQueue { public function handle(Order $order) { // Pass visitor_id explicitly - required! Mbuzz::event('order_processed', [ 'order_id' => $order->id ], $order->mbuzz_visitor_id); Mbuzz::conversion('purchase', [ 'visitor_id' => $order->mbuzz_visitor_id, 'revenue' => $order->total ]); } }
// 1. Store visitor_id when order is created app.post('/orders', async (req, res) => { const order = await Order.create({ ...req.body, mbuzzVisitorId: mbuzz.visitorId() // Capture while in request }); // ... }); // 2. Pass visitor_id explicitly in background job async function processOrder(orderId) { const order = await Order.findById(orderId); // Pass visitor_id explicitly - required! await mbuzz.event('order_processed', { orderId: order.id }, order.mbuzzVisitorId); await mbuzz.conversion('purchase', { visitorId: order.mbuzzVisitorId, revenue: order.total }); }
# 1. Store visitor_id when order is created @app.route('/orders', methods=['POST']) def create_order(): order = Order(**request.form) order.mbuzz_visitor_id = mbuzz.visitor_id() # Capture while in request order.save() # ... # 2. Pass visitor_id explicitly in background job @celery.task def process_order(order_id): order = Order.get(order_id) # Pass visitor_id explicitly - required! mbuzz.event('order_processed', visitor_id=order.mbuzz_visitor_id, order_id=order.id ) mbuzz.conversion('purchase', visitor_id=order.mbuzz_visitor_id, revenue=order.total )

Migration Example

Add a column to store visitor_id:

ruby
# Rails migration class AddMbuzzVisitorIdToOrders < ActiveRecord::Migration[8.0] def change add_column :orders, :mbuzz_visitor_id, :string add_index :orders, :mbuzz_visitor_id end end

What Happens Without visitor_id?

Scenario Result
Request context (normal web request) ✅ Works - visitor_id from cookie
Background job without explicit visitor_id ❌ Returns false - event not tracked
Background job with explicit visitor_id ✅ Works - event tracked correctly

Troubleshooting: "Visitor not found" Error

If you see this error, it means:
1. The visitor_id passed doesn't exist in our system, OR
2. No visitor_id was provided at all

Solutions:
- Ensure you're storing visitor_id when the record is created (in request context)
- Ensure you're passing visitor_id explicitly in background jobs
- Verify the visitor_id is a valid 64-character hex string


User Identification (identify)

Link visitors to known users and store traits. This enables cross-device attribution.

# On signup or login - links visitor automatically Mbuzz.identify(current_user.id, traits: { email: current_user.email, name: current_user.name, plan: current_user.plan } )
// On signup or login - links visitor automatically mbuzz.identify(user.id, { traits: { email: user.email, name: user.name, plan: user.plan } });
# On signup or login - links visitor automatically mbuzz.identify(user.id, traits={ 'email': user.email, 'name': user.name, 'plan': user.plan })
curl -X POST https://mbuzz.co/api/v1/identify \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "123", "visitor_id": "abc123def456...", "traits": { "email": "user@example.com", "name": "Jane Doe", "plan": "pro" } }'

When to call:
- On signup (links first visitor to new user)
- On every login (links new devices to existing user)
- When user attributes change

What Identify Does

identify performs two actions in one call:

  1. Links visitor to user (if visitor_id provided or available from cookie)
  2. Stores user traits (email, name, plan, etc.)

When you link a visitor:

Backward attribution:
- All past sessions from this visitor are attributed to the user
- Sessions from before signup become part of their journey

Forward attribution:
- All future sessions from this visitor automatically attributed to the user

Retroactive recalculation:
- If the user has existing conversions, and the newly-linked visitor has sessions
within those conversions' lookback windows, attribution is automatically recalculated

Cross-Device Attribution

Users often visit on multiple devices. Each device has a different visitor ID:

ruby
Desktop visitor (abc) ─────┐ ├──→ User (usr_123) Mobile visitor (def) ──────┘

How it works:
1. User visits on desktop → visitor abc created
2. User visits on mobile → visitor def created
3. User signs up on mobile → identify() links mobile visitor
4. User logs in on desktop → identify() links desktop visitor
5. Now both visitors linked → full cross-device attribution

Call identify on every login, not just signup. This ensures visitors from new devices get linked.

Example: Full Journey Attribution

ruby
Day 1: Jane visits via Google Ads (desktop) Session A Day 3: Jane visits via Facebook (mobile) Session B Day 5: Jane signs up (mobile) identify() links mobile visitor Day 6: Jane logs in (desktop) identify() links desktop visitor Day 7: Jane purchases Attribution spans ALL sessions (A, B, etc.)

Without identify on each device, you'd only see mobile sessions.


Conversion Tracking

Conversions are the key metric for attribution. When a user converts (signup, purchase, etc.),
the system automatically calculates attribution across all your configured models.

Creating Conversions

You can create conversions in two ways:

Option A: Event-based (recommended for precise attribution)

# First track the conversion event result = Mbuzz::Client.track( visitor_id: mbuzz_visitor_id, event_type: 'checkout_completed', properties: { order_id: order.id } ) # Then create the conversion linked to that event if result[:success] conversion = Mbuzz::Client.conversion( event_id: result[:event_id], conversion_type: 'purchase', revenue: order.total ) # Access attribution data if conversion[:success] conversion[:attribution][:models].each do |model, credits| puts "#{model}: #{credits.map { |c| c[:channel] }.join(', ')}" end end end
// First track the conversion event const result = await mbuzz.event('checkout_completed', { orderId: order.id }); // Then create the conversion linked to that event if (result.success) { const conversion = await mbuzz.conversion('purchase', { eventId: result.eventId, revenue: order.total }); // Access attribution data if (conversion.success) { for (const [model, credits] of Object.entries(conversion.attribution.models)) { console.log(`${model}: ${credits.map(c => c.channel).join(', ')}`); } } }
# First track the conversion event result = mbuzz.event('checkout_completed', order_id=order.id) # Then create the conversion linked to that event if result.success: conversion = mbuzz.conversion('purchase', event_id=result.event_id, revenue=order.total ) # Access attribution data if conversion.success: for model, credits in conversion.attribution['models'].items(): channels = ', '.join(c['channel'] for c in credits) print(f"{model}: {channels}")
# Create conversion from event curl -X POST https://mbuzz.co/api/v1/conversions \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "conversion": { "event_id": "evt_abc123", "conversion_type": "purchase", "revenue": 99.99 } }'

Option B: Visitor-based (simpler, for direct conversions)

# Create conversion directly from visitor ID # (uses visitor's most recent session) conversion = Mbuzz::Client.conversion( visitor_id: mbuzz_visitor_id, conversion_type: 'purchase', revenue: order.total, funnel: 'purchase', # Optional: group into funnel properties: { plan: 'pro' } )
// Create conversion directly from visitor ID // (uses visitor's most recent session) const conversion = await mbuzz.conversion('purchase', { visitorId: mbuzzVisitorId, revenue: order.total, funnel: 'purchase', // Optional: group into funnel properties: { plan: 'pro' } });
# Create conversion directly from visitor ID # (uses visitor's most recent session) conversion = mbuzz.conversion('purchase', revenue=order.total, funnel='purchase', # Optional: group into funnel properties={'plan': 'pro'} )
# Create conversion from visitor ID curl -X POST https://mbuzz.co/api/v1/conversions \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "conversion": { "visitor_id": "65dabef8d611f332d5bb88f5d6870c733d89f962594575b66f0e1de1ede1ebf0", "conversion_type": "purchase", "funnel": "purchase", "revenue": 99.99 } }'

Conversion Response

Successful conversions return attribution data immediately:

json
{ "id": "conv_xyz789", "conversion_type": "purchase", "revenue": "99.99", "attribution": { "lookback_days": 30, "sessions_analyzed": 3, "models": { "first_touch": [ { "channel": "organic_search", "credit": 1.0, "revenue_credit": "99.99" } ], "last_touch": [ { "channel": "email", "credit": 1.0, "revenue_credit": "99.99" } ], "linear": [ { "channel": "organic_search", "credit": 0.333, "revenue_credit": "33.00" }, { "channel": "paid_social", "credit": 0.333, "revenue_credit": "33.00" }, { "channel": "email", "credit": 0.334, "revenue_credit": "33.99" } ] } } }

When to Use Each Approach

Approach Use Case
Event-based (event_id) Tie conversion to specific action (checkout button click, form submit)
Visitor-based (visitor_id) Direct conversions, offline imports, webhook integrations

Acquisition vs Recurring Revenue

For SaaS and subscription businesses, you need to distinguish between:
- Acquisition: The first conversion (signup, first purchase) - this gets full attribution
- Recurring Revenue: Subsequent payments - these inherit attribution from acquisition

Why this matters: You want to know which channels drive new customers, not just which channels happened to be active when a subscription renewed.

# 1. Mark signup as the acquisition moment Mbuzz.conversion('signup', user_id: user.id, is_acquisition: true ) # 2. Monthly subscription payments inherit acquisition attribution Mbuzz.conversion('payment', user_id: user.id, revenue: 49.00, inherit_acquisition: true )
// 1. Mark signup as the acquisition moment mbuzz.conversion('signup', { userId: user.id, isAcquisition: true }); // 2. Monthly subscription payments inherit acquisition attribution mbuzz.conversion('payment', { userId: user.id, revenue: 49.00, inheritAcquisition: true });
# 1. Mark signup as the acquisition moment mbuzz.conversion('signup', user_id=user.id, is_acquisition=True ) # 2. Monthly subscription payments inherit acquisition attribution mbuzz.conversion('payment', user_id=user.id, revenue=49.00, inherit_acquisition=True )
# 1. Acquisition conversion curl -X POST https://mbuzz.co/api/v1/conversions \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -d '{"conversion": {"conversion_type": "signup", "user_id": "123", "is_acquisition": true}}' # 2. Recurring revenue curl -X POST https://mbuzz.co/api/v1/conversions \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -d '{"conversion": {"conversion_type": "payment", "user_id": "123", "revenue": 49.00, "inherit_acquisition": true}}'

How it works:
1. User signs up → is_acquisition: true stores the attribution (channels that drove signup)
2. User pays monthly → inherit_acquisition: true copies attribution from signup
3. All revenue credited to the channels that acquired the customer

When to use:
- is_acquisition: true - First meaningful conversion (signup, first purchase, trial start)
- inherit_acquisition: true - All subsequent revenue from that customer


Common Use Cases

E-Commerce Tracking

class OrdersController < ApplicationController def create @order = current_user.orders.create!(order_params) # Track the event Mbuzz.event("checkout_completed", order_id: @order.id) # Record the conversion with revenue Mbuzz.conversion("purchase", revenue: @order.total, order_id: @order.id ) redirect_to order_path(@order) end end
app.post('/orders', async (req, res) => { const order = await Order.create(req.body); // Track the event mbuzz.event('checkout_completed', { orderId: order.id }); // Record the conversion with revenue mbuzz.conversion('purchase', { revenue: order.total, orderId: order.id }); res.redirect(`/orders/${order.id}`); });
@app.route('/orders', methods=['POST']) def create_order(): order = Order.create(**request.form) # Track the event mbuzz.event('checkout_completed', order_id=order.id) # Record the conversion with revenue mbuzz.conversion('purchase', revenue=order.total, properties={'order_id': order.id} ) return redirect(url_for('order', id=order.id))
curl -X POST https://mbuzz.co/api/v1/events \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "123", "event_type": "Purchase Completed", "properties": { "order_id": "order_456", "amount": 99.99, "items": 2, "currency": "USD" } }'

SaaS Subscription Tracking

class SubscriptionsController < ApplicationController def create @subscription = current_user.create_subscription!( plan: params[:plan] ) # Record as conversion with MRR Mbuzz.conversion("subscription", revenue: @subscription.monthly_revenue, plan: @subscription.plan, billing_cycle: @subscription.billing_cycle ) redirect_to dashboard_path end end
app.post('/subscriptions', async (req, res) => { const subscription = await user.createSubscription({ plan: req.body.plan }); // Record as conversion with MRR mbuzz.conversion('subscription', { revenue: subscription.monthlyRevenue, plan: subscription.plan, billingCycle: subscription.billingCycle }); res.redirect('/dashboard'); });
@app.route('/subscriptions', methods=['POST']) def create_subscription(): subscription = current_user.create_subscription( plan=request.form['plan'] ) # Record as conversion with MRR mbuzz.conversion('subscription', revenue=subscription.monthly_revenue, properties={ 'plan': subscription.plan, 'billing_cycle': subscription.billing_cycle } ) return redirect(url_for('dashboard'))
curl -X POST https://mbuzz.co/api/v1/events \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "user_id": "123", "event_type": "Subscription Created", "properties": { "plan": "pro", "billing_cycle": "monthly", "mrr": 99.00 } }'

Error Handling

Client libraries never raise exceptions. All errors are:

  • Logged (if debug mode enabled)
  • Returned as false from tracking methods
  • Silently ignored otherwise

Why: Tracking failures should never break your application.

Debugging:

# Enable debug mode in initializer Mbuzz.init(api_key: ENV['MBUZZ_API_KEY'], debug: true) # Check return values result = Mbuzz.event("test_event", foo: "bar") if result puts "Tracking succeeded" else puts "Tracking failed (check logs)" end
// Enable debug mode in initializer mbuzz.init({ apiKey: process.env.MBUZZ_API_KEY, debug: true }); // Check return values const result = await mbuzz.event('test_event', { foo: 'bar' }); if (result) { console.log('Tracking succeeded'); } else { console.log('Tracking failed (check logs)'); }
# Enable debug mode in initializer mbuzz.init(api_key=os.environ['MBUZZ_API_KEY'], debug=True) # Check return values result = mbuzz.event('test_event', foo='bar') if result.success: print('Tracking succeeded') else: print('Tracking failed (check logs)')
# Check HTTP response codes curl -v -X POST https://mbuzz.co/api/v1/events \ -H "Authorization: Bearer $MBUZZ_API_KEY" \ -H "Content-Type: application/json" \ -d '{"events": [{"event_type": "test", "visitor_id": "abc123"}]}' # 2xx = success, 4xx/5xx = failure

Testing

Disable Tracking in Tests

# config/initializers/mbuzz.rb Mbuzz.init( api_key: ENV['MBUZZ_API_KEY'], enabled: !Rails.env.test? )
// app.js or server.js mbuzz.init({ apiKey: process.env.MBUZZ_API_KEY, enabled: process.env.NODE_ENV !== 'test' });
# app.py or settings.py mbuzz.init( api_key=os.environ['MBUZZ_API_KEY'], enabled=os.environ.get('FLASK_ENV') != 'testing' )
# Use test API key for development export MBUZZ_API_KEY=sk_test_your_key_here

Next Steps

Now that you understand the 4-call model:

  1. Initialize - Set up init() in your app
  2. Track events - Call event() for user interactions
  3. Record conversions - Call conversion() for revenue events
  4. Identify users - Call identify() on signup/login (enables cross-device)
  5. View attribution - Check your dashboard for attribution data

Need help? Check out:
- Authentication - API key management