Quickstart

5 min

Go from zero to live analytics in three steps.

1

Create a project

Sign up at app.metrone.io, create a project, and copy your API key from Settings > API Keys.

2

Add the tracking script

Drop one line into your site's <head>:

<script defer src="https://cdn.metrone.io/m.js" data-key="metrone_live_YOUR_KEY"></script>

For production, use a CNAME setup so tracking runs entirely from your own domain and bypasses ad blockers.

3

Track AI interactions (optional)

If you use voice agents or chatbots, paste a webhook URL into your platform's settings:

https://api.metrone.io/v1/webhooks/vapi/main?key=metrone_live_YOUR_KEY

Or use the Server SDK / REST API for full control. Data flows into the same dashboard — web events and AI events side by side.

Why first-party only

Your analytics is about your visitors on your site. It belongs on your domain. When analytics runs as a third-party script from a vendor URL, it introduces unnecessary external requests, raises privacy concerns, and creates a dependency you don't control. Every Metrone integration method — CNAME, NPM, or Edge proxy — serves tracking from your own domain. No third-party requests leave the browser.

For Humans

Browser tracking, React integration, and custom events.

CNAME setup

Recommended

One DNS record. One script tag. Works with any website.

1

Add a DNS record

Go to your domain's DNS settings and add a CNAME record:

TypeNameTarget
CNAMEdataapi.metrone.io

This creates a first-party endpoint on your domain (e.g. data.yoursite.com). All requests stay on your domain.

2

Add the script tag

Add this to your <head>:

<script defer
  src="https://data.yoursite.com/m.js"
  data-key="metrone_live_YOUR_API_KEY"
  data-api="https://data.yoursite.com/v1/events">
</script>

Page views are tracked automatically. Data appears in your dashboard within seconds.

Browser SDK

For React, Vue, Next.js, Nuxt, SvelteKit, or any JavaScript app with a build step.

1

Install

Terminal
npm install @metrone-io/sdk
2

Initialize

JavaScript
import { Metrone } from '@metrone-io/sdk'

const metrone = new Metrone('metrone_live_YOUR_API_KEY')

// Page views are tracked automatically
metrone.track('signup', { plan: 'growth', source: 'landing' })
3

SPA route tracking

JavaScript
const metrone = new Metrone({
  apiKey: 'metrone_live_YOUR_API_KEY',
  autoTrackSPA: true,
})
4

Full config

TypeScript
import { Metrone } from '@metrone-io/sdk'
import type { AnalyticsConfig } from '@metrone-io/sdk'

const config: AnalyticsConfig = {
  apiKey: 'metrone_live_YOUR_API_KEY',
  autoTrackSPA: true,
  batchSize: 10,          // events per batch
  flushInterval: 5000,    // ms between flushes
  debug: false,
  respectDoNotTrack: false,
  anonymizeIP: true,
}

const metrone = new Metrone(config)

Zero-dependency, tree-shakeable. ~2 KB gzipped.

React SDK

Provider, hooks, and HOC for React 18+ apps.

1

Install

Terminal
npm install @metrone-io/react @metrone-io/sdk
2

Add the provider

app.tsx
import { MetroneProvider } from '@metrone-io/react'

function App() {
  return (
    <MetroneProvider
      config={{ apiKey: 'metrone_live_YOUR_API_KEY', autoTrackSPA: true }}
      trackRouteChanges
    >
      <YourApp />
    </MetroneProvider>
  )
}
3

Use the hook

any-component.tsx
import { useMetrone } from '@metrone-io/react'

function CheckoutButton() {
  const { trackEvent, trackConversion } = useMetrone()

  return (
    <button onClick={() => {
      trackConversion('purchase', 69, { plan: 'growth' })
    }}>
      Buy now
    </button>
  )
}

Available hooks: useMetrone() and useAnalytics(options). HOC: withMetrone(Component).

Edge function proxy

Advanced

Cloudflare Workers, Vercel Edge, or Netlify Edge.

Cloudflare Worker
export default {
  async fetch(request) {
    const url = new URL(request.url)

    if (url.pathname === '/m.js')
      return fetch('https://api.metrone.io/m.js')

    if (url.pathname.startsWith('/v1/'))
      return fetch('https://api.metrone.io' + url.pathname, {
        method: request.method,
        headers: request.headers,
        body: request.body,
      })

    return fetch(request)
  },
}
Script tag
<script defer
  src="https://yoursite.com/m.js"
  data-key="metrone_live_YOUR_API_KEY"
  data-api="https://yoursite.com/v1/events">
</script>

Custom events

Track signups, purchases, clicks, form submissions — anything.

Browser SDK
metrone.track('purchase', {
  plan: 'growth',
  value: 69,
  currency: 'USD',
})

metrone.conversion('signup', 1, { source: 'landing' })
metrone.interaction('click', 'cta_hero')
curl
curl -X POST https://api.metrone.io/v1/events \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "metrone_live_YOUR_API_KEY",
    "event_type": "custom",
    "event_name": "purchase",
    "source": "web",
    "page_url": "https://yoursite.com/checkout",
    "properties": { "plan": "growth", "value": 69 }
  }'

For AI Agents

Server SDK, MCP protocol, webhooks, real-time streaming, and the full REST API.

Server SDK

New

For Node.js, Deno, Bun, or any server-side JavaScript runtime.

1

Install

Terminal
npm install @metrone-io/server
2

Initialize and track

Node.js
import { MetroneServer } from '@metrone-io/server'

const metrone = new MetroneServer({
  apiKey: 'metrone_live_YOUR_API_KEY',
})

// Track events
metrone.pageview('https://yoursite.com/pricing', 'Pricing')
metrone.track('api_request', { endpoint: '/users', method: 'GET' })

// Track AI interactions
metrone.trackAICall({
  callId: 'call_abc123',
  provider: 'vapi',
  duration: 47,
  intent: 'book_appointment',
  outcome: 'completed',
})

// Graceful shutdown (flushes pending events)
await metrone.shutdown()
3

Read analytics

Node.js
// Read aggregated stats
const stats = await metrone.getStats({ days: 30 })
console.log(stats.pageviews, stats.unique_visitors)

// Read events with pagination
const events = await metrone.getEvents({ limit: 50, event_type: 'conversion' })

// Get live visitor count
const live = await metrone.getLive()
console.log(live.active_visitors)
4

Error handling

Node.js
import { MetroneServer, MetroneAuthError, MetroneRateLimitError } from '@metrone-io/server'

try {
  await metrone.flush()
} catch (err) {
  if (err instanceof MetroneAuthError) { /* invalid API key */ }
  if (err instanceof MetroneRateLimitError) { /* back off */ }
}

Auto-batching, retry with exponential backoff, offline queue. Events are flushed every 5 seconds or when the batch reaches 10 events.

MCP Server

New

Model Context Protocol — let AI assistants query and track analytics.

1

Install

Terminal
npm install -g @metrone-io/mcp
2

Configure Claude Desktop

claude_desktop_config.json
{
  "mcpServers": {
    "metrone": {
      "command": "npx",
      "args": ["@metrone-io/mcp"],
      "env": {
        "METRONE_API_KEY": "metrone_live_YOUR_API_KEY"
      }
    }
  }
}

Available tools:

metrone_get_statsAggregated stats (pageviews, visitors, bounce rate, conversions)
metrone_get_eventsQuery events with filtering by type and source
metrone_get_pagesTop pages with visitor counts
metrone_get_sourcesTraffic source breakdown
metrone_get_liveReal-time active visitor count
metrone_track_eventTrack a custom event
metrone_track_ai_callTrack an AI voice/chat interaction

Works with any MCP-compatible client: Claude Desktop, Cursor, or custom agents.

Webhooks

Paste a URL into your AI platform. Zero code required.

Get your webhook URL from Dashboard > Settings > Integrations, or construct it:

Webhook URL format
https://api.metrone.io/v1/webhooks/{platform}/{endpointId}?key=metrone_live_YOUR_API_KEY

# Examples
https://api.metrone.io/v1/webhooks/twilio/main?key=metrone_live_...
https://api.metrone.io/v1/webhooks/vapi/support-agent?key=metrone_live_...
https://api.metrone.io/v1/webhooks/retell/sales?key=metrone_live_...
https://api.metrone.io/v1/webhooks/telnyx?key=metrone_live_...
https://api.metrone.io/v1/webhooks/intercom?key=metrone_live_...
https://api.metrone.io/v1/webhooks/zendesk?key=metrone_live_...

Labeled endpoints let you organize by location or purpose:

# One restaurant, multiple locations
.../v1/webhooks/twilio/falls-church?key=...
.../v1/webhooks/twilio/rockville?key=...
.../v1/webhooks/twilio/main-line?key=...

Paste the URL into your platform's webhook settings. Voice calls, chat sessions, and assistant queries appear in your dashboard automatically. Metrone classifies call intents (scheduling, pricing, support, etc.) from the call data.

Webhook verification

Verify that incoming webhooks are authentic.

Metrone verifies webhook signatures for platforms that support it. Add your platform's signing secret in Settings > Integrations.

TwilioHMAC-SHA256X-Twilio-SignatureAuth token from Twilio console
TelnyxEd25519telnyx-signature-ed25519Public key from Telnyx portal
IntercomHMAC-SHA1X-Hub-SignatureClient secret from Intercom app
ZendeskHMAC-SHA256X-Zendesk-Webhook-SignatureSigning secret from Zendesk webhooks

VAPI, Retell, Bland, OpenAI, and Anthropic don't sign webhooks — Metrone validates their payloads structurally. Signature verification is optional; if no secret is configured, webhooks are accepted without verification.

REST API

Full read/write access to your analytics data from any language.

Write events:

Single event
curl -X POST https://api.metrone.io/v1/events \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "metrone_live_YOUR_API_KEY",
    "event_type": "ai_call",
    "source": "voice",
    "ai_provider": "vapi",
    "ai_call_id": "call_abc123",
    "ai_intent": "book_appointment",
    "ai_duration_sec": 47
  }'
Batch (up to 100)
curl -X POST https://api.metrone.io/v1/events/batch \
  -H "Content-Type: application/json" \
  -d '[
    { "api_key": "metrone_live_...", "event_type": "pageview", "page_url": "https://..." },
    { "api_key": "metrone_live_...", "event_type": "conversion", "properties": { "value": 99 } }
  ]'

Read analytics:

Aggregated stats
curl https://api.metrone.io/v1/api/stats?days=30 \
  -H "X-Api-Key: metrone_live_YOUR_API_KEY"
Batch query (multiple in one request)
curl -X POST https://api.metrone.io/v1/api/query \
  -H "X-Api-Key: metrone_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "queries": [
      { "type": "stats", "params": { "days": 7 } },
      { "type": "pages", "params": { "limit": 10 } },
      { "type": "live" }
    ]
  }'

Real-time SSE

Server-Sent Events stream for live dashboards and monitoring.

curl
curl -N https://api.metrone.io/v1/api/stream \
  -H "X-Api-Key: metrone_live_YOUR_API_KEY"

# Events arrive as they happen:
# data: {"event_type":"pageview","page_path":"/pricing","timestamp":"..."}
# data: {"event_type":"conversion","source":"voice","ai_provider":"twilio",...}
JavaScript
const es = new EventSource(
  'https://api.metrone.io/v1/api/stream?api_key=metrone_live_YOUR_API_KEY'
)

es.onmessage = (e) => {
  const event = JSON.parse(e.data)
  console.log(event.event_type, event.page_path)
}

Streams last up to 5 minutes. Max 5 concurrent connections per API key.

Features

Deep-dive into Metrone's core capabilities.

Funnels & AI attribution

Growth+

Multi-step conversion funnels with source attribution and AI-assisted conversion tracking.

Funnels let you define a sequence of conversion goals and measure how users progress through them — with a twist no other analytics tool offers: AI attribution.

Conversion Goals

A goal matches events by one or more criteria:

Event typepageview, conversion, click, custom, ai_call, ai_chat
Event nameExact match (e.g. signup_completed, call_resolved)
Page pathExact URL path (e.g. /thank-you)
Page patternRegex match (e.g. ^/checkout/.*)

Source Attribution

Each funnel step shows which channel drove completions. Sources are classified into five categories:

WebVoice AIChat AIAPIWebhook

AI-Assisted Conversions

A conversion is AI-assisted when the session that completed the final funnel step also contained at least one AI interaction (voice call, chat session, or assistant query). This metric answers: "How many conversions involved AI?"

Example

A user visits your landing page (Web), then calls your VAPI voice agent to ask about pricing (Voice AI), then returns and completes checkout (Web). The funnel shows each step's source breakdown, and the final conversion is flagged as AI-assisted because the session included a voice call.

Available on the Growth plan and above. Navigate to Dashboard > Goals & Funnels to create goals and build funnels.

AI Assistant

All plans

Ask questions about your data in natural language.

Every Metrone project includes a built-in AI assistant powered by Claude Sonnet 4.6 (with Llama 3.3 70B fallback). Open it from the sidebar in any dashboard.

What it knows

The assistant receives your project's last 30 days of analytics data as structured context. It can answer questions about:

Web analytics

Pageviews, visitors, top pages, referrers, UTM campaigns, geo breakdown

Voice AI calls

Total/completed/failed calls, duration, resolution rate, cost, by provider, top intents

Chat AI sessions

Total sessions, messages, avg messages, by provider and model

Conversion funnels

Goal completions, funnel drop-off, source attribution, AI-assisted rate

Traffic sources

Direct, organic, social, referral, campaign — with session counts

Product knowledge

Any question about Metrone features, pricing, SDKs, integrations, philosophy

Example questions

"What was my top traffic source this month?"

"How many voice calls were resolved vs failed?"

"Which funnel has the highest drop-off rate?"

"What percentage of conversions involved AI interactions?"

"Compare my desktop vs mobile traffic."

"Which AI provider has the best resolution rate?"

Rate limit: 60 messages per hour per project. Context window: last 20 messages in the current conversation.

Reference

API endpoints

All available endpoints on api.metrone.io (or your CNAME domain).

Want to try these endpoints live?Open API Playground →

Ingestion — write events

POST/v1/eventsIngest a single event
POST/v1/events/batchIngest up to 100 events
POST/v1/webhooks/:platform/:endpointIdWebhook ingestion

Read API — query analytics (requires API key)

GET/v1/api/statsAggregated stats (pageviews, visitors, bounce, conversions)
GET/v1/api/eventsEvents with cursor pagination
GET/v1/api/pagesTop pages by pageviews
GET/v1/api/sourcesTraffic sources and referrers
GET/v1/api/liveLive active visitor count
GET/v1/api/streamReal-time SSE event stream
POST/v1/api/queryBatch query (multiple reads in one request)

System

GET/m.jsLightweight tracking script (~2 KB)
GET/v1/healthLiveness check

Authentication

Three ways to authenticate API requests.

HeaderX-Api-Key: metrone_live_...Recommended
BearerAuthorization: Bearer metrone_live_...Standard OAuth style
Query?api_key=metrone_live_...SSE and browser use

Idempotency: Include an Idempotency-Key header on POST requests to prevent duplicate events. The key is cached for 24 hours.

Request tracing: Every response includes an X-Request-Id header. Include your own in the request to correlate with your logs.

Error codes

Structured JSON errors with machine-readable codes.

Error response format
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Try again in 60 seconds.",
    "status": 429,
    "request_id": "req_abc123_xyz789"
  }
}
400INVALID_PAYLOADMissing or malformed fields
400INVALID_JSONRequest body is not valid JSON
400BATCH_EMPTYBatch array is empty
400BATCH_TOO_LARGEBatch exceeds 100 events
400BATCH_MIXED_KEYSBatch contains different API keys
401MISSING_API_KEYNo API key provided
401INVALID_API_KEYAPI key not found or inactive
403FORBIDDENAPI key lacks required scope
404NOT_FOUNDEndpoint does not exist
409DUPLICATE_EVENTIdempotency key already used
413BODY_TOO_LARGERequest body exceeds 512 KB
429RATE_LIMITEDToo many requests
429QUOTA_EXCEEDEDMonthly event quota reached
500WRITE_FAILEDDatabase write error
500INTERNAL_ERRORUnexpected server error

SDK configuration

All config options for browser and server SDKs.

Browser SDK@metrone-io/sdk

apiKeystringrequiredYour Metrone API key
autoTrackSPAbooleanfalseTrack route changes automatically
batchSizenumber10Events per batch
flushIntervalnumber5000Ms between flushes
debugbooleanfalseLog to console
respectDoNotTrackbooleanfalseHonor browser DNT setting
anonymizeIPbooleantrueHash visitor IPs server-side
offlineQueuebooleantrueQueue events when offline
maxQueueSizenumber100Max offline queue size

Server SDK@metrone-io/server

apiKeystringrequiredYour Metrone API key
endpointstringhttps://api.metrone.ioAPI base URL
batchSizenumber10Events per batch
flushIntervalMsnumber5000Ms between flushes
maxRetriesnumber3Retry attempts on failure
timeoutMsnumber10000Request timeout
debugbooleanfalseLog to console

Supported platforms

Webhook integrations for voice, chat, and AI assistant platforms.

Twilio

Voice & SMS

/v1/webhooks/twilio/{<id>}

Telnyx

Voice & SMS

/v1/webhooks/telnyx/{<id>}

VAPI

Voice AI agents

/v1/webhooks/vapi/{<id>}

Retell

Voice AI agents

/v1/webhooks/retell/{<id>}

Bland

Voice AI agents

/v1/webhooks/bland/{<id>}

OpenAI

Chat & assistants

/v1/webhooks/openai/{<id>}

Anthropic

Chat & assistants

/v1/webhooks/anthropic/{<id>}

Intercom

Conversations & tickets

/v1/webhooks/intercom/{<id>}

Zendesk

Tickets & chat

/v1/webhooks/zendesk/{<id>}

Any platform with outgoing webhooks works with Metrone. Contact us if you need help with a specific integration.