A/B Testing
Run split tests on email campaigns to find the best subject, content, or sender
A/B tests let you attach competing variants to a campaign and, once results are in, promote the winning variant's content back onto the parent campaign. Each variant is created with its own call, tied to an existing campaign that has not started sending.
Auth scope: listing requires read, send, or send:marketing; creating a variant or selecting a winner requires send or send:marketing.
List A/B tests
/mail/v1/ab-testsList A/B tests for the authenticated account. The response combines campaign A/B-test variants and subject-line tests; each entry carries a source field (campaign or subject) identifying which it is.
Query parameters
pagenumberquerydefault: 1Page number (1-based).
limitnumberquerydefault: 20Results per page — max 50.
typestringqueryRestrict to one source: campaign (campaign A/B variants) or subject (subject-line tests). Omit to return both.
Response fields
successbooleantrue when the request succeeded.
dataArray<object>Combined test rows, newest first. Campaign entries include id, campaign_id, variant, test_type, subject, preheader, from_name, send_percent, emails_sent, opens, clicks, winner_selected_at, created_at, and source: "campaign".
paginationobjectpage, limit, total, and totalPages.
curl "https://api.misar.io/mail/v1/ab-tests?page=1&limit=20&type=campaign" \
-H "Authorization: Bearer msk_YOUR_API_KEY"{
"success": true,
"data": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"campaign_id": "9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6",
"variant": "A",
"test_type": "subject",
"subject": "Your exclusive offer inside",
"preheader": null,
"from_name": null,
"send_percent": 50,
"emails_sent": 500,
"opens": 180,
"clicks": 45,
"winner_selected_at": null,
"created_at": "2026-04-01T08:00:00Z",
"source": "campaign"
}
],
"pagination": { "page": 1, "limit": 20, "total": 2, "totalPages": 1 }
}Create an A/B test variant
/mail/v1/ab-testsAdd one variant to a campaign's A/B test. Call this once per variant (e.g. once for A, once for B). The campaign must not be in sending or sent status. Creating the first variant sets ab_test_enabled on the campaign.
Request body
campaign_idUUIDbodyrequiredCampaign to attach the variant to.
variantstringbodyrequiredVariant identifier, 1–5 chars (e.g. A, B). Must be unique per campaign.
test_typestringbodydefault: contentWhat this variant changes — one of content, subject, send_time, from_name, preheader.
subjectstringbodyOverride subject line (max 255) — supports merge tags.
preheaderstringbodyOverride preheader text (max 255).
body_htmlstringbodyOverride HTML body.
from_namestringbodyOverride sender display name (max 100).
send_percentnumberbodydefault: 50Percentage of the list to send this variant to (1–99).
send_time_aISO 8601bodySend time for the first split, used with test_type: "send_time".
send_time_bISO 8601bodySend time for the second split.
auto_select_winnerbooleanbodydefault: falseAutomatically promote a winner once the wait window elapses.
winner_wait_hoursnumberbodydefault: 4Hours to measure before an automatic winner is picked (1–168).
Response fields
successbooleantrue when the variant was created.
dataobjectThe created variant row, including id, campaign_id, variant, test_type, send_percent, winner_selected_at, and created_at.
curl -X POST https://api.misar.io/mail/v1/ab-tests \
-H "Authorization: Bearer msk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": "9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6",
"variant": "B",
"test_type": "subject",
"subject": "{{first_name}}, we have something special for you",
"send_percent": 50
}'{
"success": true,
"data": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"campaign_id": "9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6",
"variant": "B",
"test_type": "subject",
"subject": "{{first_name}}, we have something special for you",
"send_percent": 50,
"winner_selected_at": null,
"created_at": "2026-04-01T08:05:00Z"
}
}Select the winning variant
/mail/v1/ab-tests/:id/winnerPick the winning variant. The winning variant's content is applied to the parent campaign, and winner_selected_at is stamped.
Path parameters
idUUIDpathrequiredID of the A/B test (the campaign's test group).
Request body
winner_variantstringbodyrequiredIdentifier of the winning variant (1–5 chars), matching a variant value on the test.
metricstringbodydefault: opensMetric the winner was chosen on — one of opens, clicks, revenue, conversions.
Response fields
successbooleantrue when the winner was applied.
dataobjectab_test_id, campaign_id, winner_variant, metric, winner_selected_at, and applied_to_campaign (the subject, body_html, and from_name written onto the campaign).
curl -X POST https://api.misar.io/mail/v1/ab-tests/3fa85f64-5717-4562-b3fc-2c963f66afa6/winner \
-H "Authorization: Bearer msk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "winner_variant": "B", "metric": "opens" }'{
"success": true,
"data": {
"ab_test_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"campaign_id": "9c1e2b7a-0d44-4f8a-9b1e-2c963f66afa6",
"winner_variant": "B",
"metric": "opens",
"winner_selected_at": "2026-04-01T12:00:00Z",
"applied_to_campaign": {
"subject": "{{first_name}}, we have something special for you",
"body_html": null,
"from_name": null
}
}
}Status codes
200— Winner selected and applied.201— Variant created.400— Validation failed, missing testid, or invalid JSON body.403— API key lacks the required scope.404— Campaign not found / not owned, or the named variant does not exist for the test.409— Campaign alreadysending/sent, or a variant with that identifier already exists.415—Content-Typeis notapplication/json.