Analytics
Email performance metrics, campaign analytics, and custom event tracking
Analytics endpoints expose send metrics and engagement rates at both account and per-campaign level, and let you track custom conversion and purchase events. The /api/v1/analytics and /api/v1/track/* endpoints use API-key auth; the richer dashboard analytics (/analytics/*) use the logged-in session cookie.
Auth scopes: analytics reads metrics on /api/v1/analytics; tracking endpoints accept track, track:events / track:purchase, or analytics.
Plan gates on analytics features
- Basic metrics (opens, clicks, bounces): all plans
- 90-day history: Pro+
- 365-day history + heatmaps: Max+
- Ecommerce / revenue tracking (
/track/purchase,/analytics/revenue): Max (ecommerce_trackingfeature) - Report export and scheduled reports: Max
Rates returned by /api/v1/analytics are percentages (0–100). The session dashboard endpoints (/analytics/benchmark, etc.) return raw ratios (0–1) unless noted.
Account & campaign metrics
/mail/v1/analyticsOne endpoint serves both aggregate and per-campaign metrics. Omit campaignId for account-level usage over the period; pass campaignId to get a single campaign's stats.
Query parameters
startDatestringqueryStart date, YYYY-MM-DD. Defaults to 30 days ago.
endDatestringqueryEnd date, YYYY-MM-DD. Defaults to today.
campaignIdUUIDqueryWhen set, returns stats for that one campaign instead of the account aggregate.
groupBystringquerydefault: dayBucketing granularity — day, week, or month.
Response — account (no campaignId)
data.periodobjectResolved { start, end } range.
data.emailUsageArray<object>Daily rows: date, emails_sent_today, emails_sent_month.
data.campaignTotalsobjectSummed sent, opened, clicked, bounced, complained across campaigns in range.
data.ratesobjectopenRate, clickRate, bounceRate (percentages, 0–100).
data.warningstringPresent only when more than 1000 campaigns matched and totals were truncated.
Response — campaign (with campaignId)
data.campaignobjectCampaign row: id, name, subject, status, from_email, total_recipients, total_sent, total_delivered, total_opened, total_clicked, total_bounced, total_complained, total_unsubscribed, scheduled_at, created_at, updated_at.
data.ratesobjectopenRate, clickRate, bounceRate, complaintRate, unsubscribeRate (percentages, 0–100).
curl "https://api.misar.io/mail/v1/analytics?startDate=2026-03-07&endDate=2026-04-06" \
-H "Authorization: Bearer msk_YOUR_API_KEY"{
"success": true,
"data": {
"period": { "start": "2026-03-07", "end": "2026-04-06" },
"emailUsage": [
{ "date": "2026-03-07", "emails_sent_today": 420, "emails_sent_month": 420 }
],
"campaignTotals": {
"sent": 12480, "opened": 4884, "clicked": 1221, "bounced": 270, "complained": 12
},
"rates": { "openRate": 39.13, "clickRate": 9.78, "bounceRate": 2.16 }
}
}curl "https://api.misar.io/mail/v1/analytics?campaignId=9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6" \
-H "Authorization: Bearer msk_YOUR_API_KEY"{
"success": true,
"data": {
"campaign": {
"id": "9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6",
"name": "April Newsletter",
"subject": "Spring is here",
"status": "sent",
"from_email": "hello@yourdomain.com",
"total_recipients": 5200,
"total_sent": 5200,
"total_delivered": 5096,
"total_opened": 2038,
"total_clicked": 510,
"total_bounced": 104,
"total_complained": 5,
"total_unsubscribed": 18,
"scheduled_at": "2026-04-01T09:00:00Z",
"created_at": "2026-03-30T09:00:00Z",
"updated_at": "2026-04-01T10:00:00Z"
},
"rates": {
"openRate": 39.19, "clickRate": 9.81, "bounceRate": 2.0,
"complaintRate": 0.1, "unsubscribeRate": 0.35
}
}
}Track a custom event
/mail/v1/track/eventRecord a custom event tied to a contact by email. Useful for measuring downstream conversions from email clicks. Accepts scope track, track:events, or analytics.
Request body
emailstringbodyrequiredEmail of the contact who triggered the event.
event_namestringbodyrequiredEvent name (1–100 chars).
event_dataobjectbodyArbitrary key-value metadata (defaults to {}).
sourcestringbodyWhere the event originated (max 30 chars).
campaign_idUUIDbodyCampaign to associate the event with.
page_urlstringbodyURL where the event happened (valid URL, max 2048).
referrerstringbodyReferrer URL (valid URL, max 2048).
Response fields
successbooleantrue when the event was recorded.
event_idstring | nullIdentifier for the tracked event.
curl -X POST https://api.misar.io/mail/v1/track/event \
-H "Authorization: Bearer msk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"event_name": "trial_started",
"source": "welcome_email",
"event_data": { "plan": "pro" }
}'{ "success": true, "event_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }Track a purchase event
/mail/v1/track/purchaseRecord a purchase with revenue, attributed to the most recent clicked campaign or automation within the attribution window. Accepts scope track, track:purchase, or analytics, and requires the ecommerce_tracking plan feature. Amounts are in cents.
Request body
emailstringbodyrequiredPurchasing contact.
order_idstringbodyrequiredYour system's order ID (1–255). Deduplication key — (user, order_id) is unique.
total_centsnumberbodyrequiredOrder total in cents (positive integer).
currencystringbodydefault: USDISO 4217 currency code (exactly 3 chars).
itemsarraybodyLine items (max 500), each { name, quantity, price_cents } — price_cents in cents.
attribution_window_hoursnumberbodydefault: 72Look-back window for click attribution (1–720 hours).
Response fields
successbooleantrue when the purchase was recorded.
purchase_idstring | nullIdentifier for the purchase row.
attributionobjectsource, campaign_id, automation_id, and click_timestamp (any may be null if no click matched).
curl -X POST https://api.misar.io/mail/v1/track/purchase \
-H "Authorization: Bearer msk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"order_id": "order_12345",
"total_cents": 9999,
"currency": "USD",
"items": [
{ "name": "Pro Plan", "quantity": 1, "price_cents": 9999 }
]
}'{
"success": true,
"purchase_id": "b7c9e667-7425-40de-944b-e07fc1f90ae7",
"attribution": {
"source": "campaign",
"campaign_id": "9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6",
"automation_id": null,
"click_timestamp": "2026-04-01T09:30:00Z"
}
}ecommerce_tracking feature). Blocked accounts receive 403 from enforcePlanLimit.Benchmark against industry
/mail/analytics/benchmarkCompare your last-30-day metrics against industry averages. Cached for 1 hour. Uses session authentication.
Response fields
successbooleantrue when the request succeeded.
cachedbooleanWhether the response came from cache.
dataobjectComparison per metric (openRate, clickRate, bounceRate, unsubscribeRate), each with yours, industry, delta, and better (ratios 0–1). For open/click, better: true means above average; for bounce/unsubscribe it means below average.
curl "https://api.misar.io/mail/analytics/benchmark" \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"success": true,
"cached": false,
"data": {
"openRate": { "yours": 0.31, "industry": 0.251, "delta": 0.059, "better": true },
"clickRate": { "yours": 0.04, "industry": 0.028, "delta": 0.012, "better": true },
"bounceRate": { "yours": 0.015, "industry": 0.02, "delta": -0.005, "better": true },
"unsubscribeRate": { "yours": 0.01, "industry": 0.009, "delta": 0.001, "better": false }
}
}Churn-risk contacts
/mail/analytics/churn-riskRule-based churn scoring for subscribed contacts. Returns the top 50 at-risk contacts, highest score first. Takes no query parameters. Uses session authentication.
Response fields
successbooleantrue when the request succeeded.
cachedbooleantrue when served from cache.
dataobjectA contacts array; each contact has id, email, first_name, last_name, last_engagement_at, emails_sent, emails_opened, churnScore (0–100, higher = more at risk), and daysSinceOpen (or null).
curl "https://api.misar.io/mail/analytics/churn-risk" \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"success": true,
"data": {
"contacts": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"email": "user@example.com",
"first_name": "Alex",
"last_name": "Doe",
"last_engagement_at": "2026-01-10T00:00:00Z",
"emails_sent": 24,
"emails_opened": 2,
"churnScore": 82,
"daysSinceOpen": 47
}
]
}
}Cohort analysis
/mail/analytics/cohortsRetention by subscription month — each cohort is the contacts who subscribed in a given calendar month. Uses session authentication.
Query parameters
monthsnumberquerydefault: 6Number of trailing months to include (1–24).
Response fields
successbooleantrue when the request succeeded.
dataobjectA cohorts array; each cohort has cohortMonth, label, totalContacts, and periods — an array of { monthOffset, activeCount, retentionPct } (offsets 0, 1, 2, 3 → month / +30d / +60d / +90d).
curl "https://api.misar.io/mail/analytics/cohorts?months=6" \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"success": true,
"data": {
"cohorts": [
{
"cohortMonth": "2026-01",
"label": "Jan 2026",
"totalContacts": 420,
"periods": [
{ "monthOffset": 0, "activeCount": 420, "retentionPct": 100 },
{ "monthOffset": 1, "activeCount": 189, "retentionPct": 45 },
{ "monthOffset": 2, "activeCount": 160, "retentionPct": 38 },
{ "monthOffset": 3, "activeCount": 130, "retentionPct": 31 }
]
}
]
}
}Export analytics data
/mail/analytics/exportExport a report as a CSV download (Content-Disposition: attachment). Provide either a saved report_id or a report_type. Uses session authentication.
Query parameters
report_idUUIDqueryA saved report to export. Its stored report_type and filters are used.
report_typestringqueryOne of campaign_performance, cohort_analysis, send_time_heatmap, engagement_funnel. Required if report_id is omitted.
date_fromstringqueryStart date, YYYY-MM-DD.
date_tostringqueryEnd date, YYYY-MM-DD.
curl "https://api.misar.io/mail/analytics/export?report_type=campaign_performance&date_from=2026-01-01&date_to=2026-03-31" \
-H "Cookie: sb-access-token=YOUR_SESSION" \
-o report.csvPerformance insights
/mail/analytics/insightsRule-based insights about your email performance over the last 30 days. Takes no query parameters. Uses session authentication.
Response fields
successbooleantrue when the request succeeded.
cachedbooleantrue when served from cache.
dataobjectAn insights array — each { type, title, description, value? } where type is positive, warning, or tip — plus bestDayByOpenRate (per-weekday open-rate breakdown).
curl "https://api.misar.io/mail/analytics/insights" \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"success": true,
"data": {
"insights": [
{
"type": "positive",
"title": "Tuesday sends perform best",
"description": "Emails sent on Tuesday get ~40% higher open rates than other days. Schedule more campaigns on Tuesday."
},
{
"type": "warning",
"title": "Inactive contacts detected",
"description": "1,240 subscribed contacts haven't opened an email in 90 days. Consider a win-back campaign or list cleanup.",
"value": "1,240 contacts"
}
],
"bestDayByOpenRate": []
}
}Saved reports
/mail/analytics/reportsList saved report definitions. Uses session authentication. A POST to the same path creates a report (name, report_type, optional filters, schedule, is_public).
Response fields
successbooleantrue when the request succeeded.
dataobjectA reports array; each report has id, name, report_type, filters, schedule, last_generated_at, is_public, public_token, created_at, and updated_at.
curl "https://api.misar.io/mail/analytics/reports" \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"success": true,
"data": {
"reports": [
{
"id": "rpt_abc123",
"name": "Monthly Campaign Summary",
"report_type": "campaign_performance",
"filters": { "dateFrom": "2026-05-01", "dateTo": "2026-05-31" },
"schedule": "monthly",
"last_generated_at": "2026-05-01T09:00:00Z",
"is_public": false,
"public_token": null,
"created_at": "2026-04-01T09:00:00Z",
"updated_at": "2026-05-01T09:00:00Z"
}
]
}
}report_type accepts campaign_performance, engagement_funnel, cohort_analysis, send_time_heatmap, growth, revenue, or deliverability. schedule is one of daily, weekly, monthly. Scheduled reports require the Max plan.
Revenue attribution
/mail/analytics/revenueWhich campaigns drove revenue. Requires the Max plan with ecommerce tracking. Uses session authentication. Revenue values are in cents.
Response fields
successbooleantrue when the request succeeded.
cachedbooleantrue when served from cache.
dataobjecttotalRevenue (cents), revenueBySource (source → cents), topCampaigns (each { campaign_id, campaign_name, revenue, conversions }), and revenueTimeline (last 30 days as { date, revenue }).
curl "https://api.misar.io/mail/analytics/revenue" \
-H "Cookie: sb-access-token=YOUR_SESSION"{
"success": true,
"data": {
"totalRevenue": 1542050,
"revenueBySource": { "campaign": 1200000, "automation": 342050 },
"topCampaigns": [
{
"campaign_id": "camp_abc123",
"campaign_name": "Spring Sale",
"revenue": 620000,
"conversions": 31
}
],
"revenueTimeline": [
{ "date": "2026-04-01", "revenue": 82000 }
]
}
}Status codes
200— Metrics or report returned.400— Validation failed or invalid JSON body.401— Missing/invalid API key, or (session endpoints) not logged in.403— API key lacks the required scope, or the plan does not include the feature.404— Campaign or saved report not found.415—Content-Typeis notapplication/json(tracking POSTs).