How to send an A/B test campaign

Intro

Send an A/B test campaign to compare two email variants — different subject lines, content, or senders — and automatically route the winning version to the rest of your audience. The test phase sends both variants to a percentage of your subscribers, measures performance over a configurable decision window, then delivers the winner to the remaining audience.

See API reference: Campaigns | Email Templates

Prerequisites

  • An API key with campaigns.write and email-templates.write (or email-templates.read if reusing existing templates) scopes, or an OAuth token with the same scopes
  • Sufficient email sends remaining on your current plan (check pricing plans) — both the test phase and the winner send consume emails from your monthly allowance
  • Two email templates — one for each variant (can be the same template if you only want to test subject lines)

Step 1: Prepare email templates

Each A/B test variant requires its own template ID. You can create two templates, or reuse one template for both variants if you only want to test subject lines or sender names.

Create templates using the approach described in How to send an email campaign — Step 1. The simplest option is importing from HTML.

See endpoint: Import email template from HTML

curl -X POST 'https://api.omnisend.com/api/email-templates/import' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "A/B Test - Variant A Template",
    "html": "<html><body><h1>Summer Sale</h1><p>Up to 50% off all items!</p><p><a href=\"https://example.com/shop\">Shop now</a></p><p><a href=\"[[unsubscribe_link]]\">Unsubscribe</a></p></body></html>"
  }'

Repeat for the second variant template (or skip if using the same template for both). Save the returned id values for the next step.

Step 2: Create the A/B test campaign

Create a campaign with type: "abTest". Instead of top-level content, A/B test campaigns carry per-variant content under abTest.variants. Each variant specifies its own subject, template, and optional sender settings.

Configure abTest.settings to control the test:

  • testSizePercent — percentage of audience that receives the test variants (10–100). When set to 100, all recipients receive a variant and no winner is selected ("send-all" mode).
  • winningMetricopenRate or clickRate. Required unless testSizePercent is 100.
  • decisionTime — how long to wait before picking the winner. Maximum 168 hours or 7 days. Required unless testSizePercent is 100.

See endpoint: Create campaign

curl -X POST 'https://api.omnisend.com/api/campaigns' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Summer Sale A/B Test",
    "type": "abTest",
    "channel": "email",
    "abTest": {
      "variants": {
        "a": {
          "content": {
            "email": {
              "subject": "Summer Sale — 50% Off Everything!",
              "templateID": "000000000000000000000001"
            }
          }
        },
        "b": {
          "content": {
            "email": {
              "subject": "Your exclusive summer deal is here",
              "templateID": "000000000000000000000002"
            }
          }
        }
      },
      "settings": {
        "testSizePercent": 30,
        "winningMetric": "openRate",
        "decisionTime": {
          "unit": "h",
          "amount": 4
        }
      }
    },
    "audience": {
      "includedSegmentIDs": ["111111111111111111111111"]
    },
    "sendingSettings": {
      "strategy": "scheduled",
      "scheduledAt": "2026-07-01T10:00:00Z"
    }
  }'

The response returns a campaign in draft status with an id and the populated abTest.variants.a.id / abTest.variants.b.id (variant campaign IDs used for reporting and winner selection).

Note: subject and templateID are required for each variant. senderName, senderEmail, preheader, and replyToEmail are optional — if omitted, the brand defaults are used.

Note: Do not include top-level content or language fields for A/B test campaigns — variants carry their own content. audience and sendingSettings are optional (same defaults as regular campaigns).

Step 3: Send the campaign

Trigger the campaign send. The test phase begins: both variants are sent to the configured percentage of your audience. After the decision time elapses, the winner is automatically selected and sent to the remaining audience.

See endpoint: Send campaign

curl -X POST 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID/send' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview'

A 204 response confirms the send was initiated. If sendingSettings.strategy is scheduled, the campaign moves to scheduled status and the test begins at the scheduled time.

Warning: The send endpoint returns 402 Payment Required when the campaign audience exceeds your current billing tier limits. A plan upgrade is required to proceed.

Step 4: Select a winner manually (optional)

If you want to override automatic winner selection, you can manually pick the winning variant once the test variants have finished sending to the test audience. The campaign must be in started status, and the test audience delivery must be complete. Use the variant ID returned in Step 2 (from abTest.variants.a.id or abTest.variants.b.id).

See endpoint: Select A/B test winner

curl -X POST 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID/ab-test/winner' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview' \
  -H 'Content-Type: application/json' \
  -d '{
    "variantID": "000000000000000000000010"
  }'

A 204 response confirms the winner was selected. The winning variant is immediately routed to the remaining audience.

Step 5: Stop or resume the test (optional)

While the campaign is in the test phase (started status), you can pause automatic winner selection. This is useful if you need more time to evaluate results before a winner is picked.

Stop the test — halts automatic winner selection:

See endpoint: Stop A/B test

curl -X POST 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID/ab-test/stop' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview'

Resume the test — re-enables automatic winner selection (campaign must be in stopped status):

See endpoint: Resume A/B test

curl -X POST 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID/ab-test/resume' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview'

Verify results

Retrieve the campaign to check its status and see the A/B test result once a winner has been selected.

See endpoint: Get campaign

curl -X GET 'https://api.omnisend.com/api/campaigns/CAMPAIGN_ID' \
  -H 'Authorization: Omnisend-API-Key YOUR-API-KEY' \
  -H 'Omnisend-Version: 2026-preview'

Once the winner is selected, the response includes abTest.result:

{
  "abTest": {
    "result": {
      "winnerVariantID": "000000000000000000000010",
      "selectedAt": "2026-07-01T14:00:00Z",
      "isManuallySelected": false
    }
  }
}
StatusMeaning
draftCampaign is being prepared
scheduledCampaign is queued to send at the scheduled time
startedTest phase is active — variants are being sent to test audience
stoppedAutomatic winner selection is paused
sentWinner has been selected and sent to remaining audience
canceledCampaign was canceled

Troubleshooting

  • 409 Conflict on send: Only campaigns in draft status can be sent. If already sent or scheduled, copy the campaign to create a new draft.
  • 402 Payment Required on send: The campaign audience exceeds your plan's email send allowance. Upgrade your plan or reduce the audience size.
  • Campaign ends in error status: A campaign can fail during sending due to insufficient plan allowance or internal issues. The API does not always include error details in the campaign response — check your plan usage if the cause is unclear.
  • 409 on winner selection — not started: The campaign must be in started status to select a winner. If the winner was already selected automatically, the test is complete.
  • 409 on winner selection — test still sending: Returned when the campaign is in started status but the test variants have not finished sending to the test audience. Wait for test delivery to complete before selecting a winner.
  • 422 on stop/resume/winner: Returned when the campaign is not an A/B test type (e.g., attempting these operations on a regular campaign).
  • Validation error on create: Ensure both variants have subject and templateID. If testSizePercent is less than 100, winningMetric and decisionTime are also required.

Related resources