A/B Tests
Create A/B Test
Create a campaign A/B test
POST
/
api
/
v1
/
ab-tests
Create A/B Test
curl --request POST \
--url https://api.sequenzy.com/api/v1/ab-tests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"campaignId": "<string>",
"automationNodeId": "<string>",
"confirmLiveChange": true,
"name": "<string>",
"testPercentage": 123,
"testDurationMinutes": 123,
"winnerCriteria": "<string>",
"testType": "<string>",
"winnerThreshold": 123,
"variants": [
{}
]
}
'import requests
url = "https://api.sequenzy.com/api/v1/ab-tests"
payload = {
"campaignId": "<string>",
"automationNodeId": "<string>",
"confirmLiveChange": True,
"name": "<string>",
"testPercentage": 123,
"testDurationMinutes": 123,
"winnerCriteria": "<string>",
"testType": "<string>",
"winnerThreshold": 123,
"variants": [{}]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
campaignId: '<string>',
automationNodeId: '<string>',
confirmLiveChange: true,
name: '<string>',
testPercentage: 123,
testDurationMinutes: 123,
winnerCriteria: '<string>',
testType: '<string>',
winnerThreshold: 123,
variants: [{}]
})
};
fetch('https://api.sequenzy.com/api/v1/ab-tests', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sequenzy.com/api/v1/ab-tests",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'campaignId' => '<string>',
'automationNodeId' => '<string>',
'confirmLiveChange' => true,
'name' => '<string>',
'testPercentage' => 123,
'testDurationMinutes' => 123,
'winnerCriteria' => '<string>',
'testType' => '<string>',
'winnerThreshold' => 123,
'variants' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sequenzy.com/api/v1/ab-tests"
payload := strings.NewReader("{\n \"campaignId\": \"<string>\",\n \"automationNodeId\": \"<string>\",\n \"confirmLiveChange\": true,\n \"name\": \"<string>\",\n \"testPercentage\": 123,\n \"testDurationMinutes\": 123,\n \"winnerCriteria\": \"<string>\",\n \"testType\": \"<string>\",\n \"winnerThreshold\": 123,\n \"variants\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sequenzy.com/api/v1/ab-tests")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"campaignId\": \"<string>\",\n \"automationNodeId\": \"<string>\",\n \"confirmLiveChange\": true,\n \"name\": \"<string>\",\n \"testPercentage\": 123,\n \"testDurationMinutes\": 123,\n \"winnerCriteria\": \"<string>\",\n \"testType\": \"<string>\",\n \"winnerThreshold\": 123,\n \"variants\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sequenzy.com/api/v1/ab-tests")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"campaignId\": \"<string>\",\n \"automationNodeId\": \"<string>\",\n \"confirmLiveChange\": true,\n \"name\": \"<string>\",\n \"testPercentage\": 123,\n \"testDurationMinutes\": 123,\n \"winnerCriteria\": \"<string>\",\n \"testType\": \"<string>\",\n \"winnerThreshold\": 123,\n \"variants\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"abTest": {
"id": "ab_abc123",
"campaignId": "camp_abc123",
"name": "A/B Test for April Launch",
"status": "draft",
"testPercentage": 20,
"testDurationMinutes": 240,
"winnerCriteria": "open_rate",
"variants": [
{ "id": "var_a", "label": "A", "subject": "A quick update" },
{ "id": "var_b", "label": "B", "subject": "Alternative subject line" }
]
}
}
{
"success": false,
"error": "testPercentage must be between 5 and 50"
}
{
"success": false,
"error": "Campaign structure can only be changed in draft or rejected status."
}
{
"success": false,
"error": "Maximum of 5 variants allowed"
}
{
"success": false,
"error": "Unauthorized"
}
{
"success": false,
"error": "Campaign not found"
}
{
"success": false,
"error": "A/B test already exists for this campaign"
}
{
"success": false,
"error": "Failed to create A/B test"
}
Create a draft A/B test for a campaign in
draft or rejected status, or convert a sequence email node into an A/B test step. Provide exactly one of campaignId or automationNodeId. Variant A (the control) is copied from the current email. A campaign or sequence node can have only one A/B test.
Request
Campaign to attach the test to. Must be in
draft or rejected status.
Mutually exclusive with automationNodeId.Sequence
action_email node to convert into an action_ab_test step.
Mutually exclusive with campaignId. Requires at least one variants entry.Required as
true when automationNodeId belongs to an active sequence. This
acknowledges that the live sequence graph will change immediately.Test name. Defaults to
A/B Test for <campaign name>.Share of the audience that receives test sends. Must be from 5 to 50. Defaults
to 20.
How long the test phase runs before a winner is selected. Must be from 15 to
1440. Defaults to 240.
Metric used to pick the winner:
open_rate or click_rate. Defaults to
open_rate.Sequence test type:
subject or content. Subject tests use open_rate;
content tests use click_rate. Defaults to content. Sequence tests only.Number of sequence recipients in the test sample, from 10 to 1000. Defaults to
100. Sequence tests only.
Extra variants beyond the control. Each item takes
subject (required),
previewText, and blocks. Total variants cannot exceed 5. Variants without
blocks reuse the current email body. Optional for campaign tests; sequence
conversions require at least one entry.curl -X POST "https://api.sequenzy.com/api/v1/ab-tests" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaignId": "camp_abc123",
"testPercentage": 20,
"winnerCriteria": "open_rate",
"variants": [{ "subject": "Alternative subject line" }]
}'
Responses
{
"success": true,
"abTest": {
"id": "ab_abc123",
"campaignId": "camp_abc123",
"name": "A/B Test for April Launch",
"status": "draft",
"testPercentage": 20,
"testDurationMinutes": 240,
"winnerCriteria": "open_rate",
"variants": [
{ "id": "var_a", "label": "A", "subject": "A quick update" },
{ "id": "var_b", "label": "B", "subject": "Alternative subject line" }
]
}
}
{
"success": false,
"error": "testPercentage must be between 5 and 50"
}
{
"success": false,
"error": "Campaign structure can only be changed in draft or rejected status."
}
{
"success": false,
"error": "Maximum of 5 variants allowed"
}
{
"success": false,
"error": "Unauthorized"
}
{
"success": false,
"error": "Campaign not found"
}
{
"success": false,
"error": "A/B test already exists for this campaign"
}
{
"success": false,
"error": "Failed to create A/B test"
}
⌘I
Create A/B Test
curl --request POST \
--url https://api.sequenzy.com/api/v1/ab-tests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"campaignId": "<string>",
"automationNodeId": "<string>",
"confirmLiveChange": true,
"name": "<string>",
"testPercentage": 123,
"testDurationMinutes": 123,
"winnerCriteria": "<string>",
"testType": "<string>",
"winnerThreshold": 123,
"variants": [
{}
]
}
'import requests
url = "https://api.sequenzy.com/api/v1/ab-tests"
payload = {
"campaignId": "<string>",
"automationNodeId": "<string>",
"confirmLiveChange": True,
"name": "<string>",
"testPercentage": 123,
"testDurationMinutes": 123,
"winnerCriteria": "<string>",
"testType": "<string>",
"winnerThreshold": 123,
"variants": [{}]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
campaignId: '<string>',
automationNodeId: '<string>',
confirmLiveChange: true,
name: '<string>',
testPercentage: 123,
testDurationMinutes: 123,
winnerCriteria: '<string>',
testType: '<string>',
winnerThreshold: 123,
variants: [{}]
})
};
fetch('https://api.sequenzy.com/api/v1/ab-tests', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sequenzy.com/api/v1/ab-tests",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'campaignId' => '<string>',
'automationNodeId' => '<string>',
'confirmLiveChange' => true,
'name' => '<string>',
'testPercentage' => 123,
'testDurationMinutes' => 123,
'winnerCriteria' => '<string>',
'testType' => '<string>',
'winnerThreshold' => 123,
'variants' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sequenzy.com/api/v1/ab-tests"
payload := strings.NewReader("{\n \"campaignId\": \"<string>\",\n \"automationNodeId\": \"<string>\",\n \"confirmLiveChange\": true,\n \"name\": \"<string>\",\n \"testPercentage\": 123,\n \"testDurationMinutes\": 123,\n \"winnerCriteria\": \"<string>\",\n \"testType\": \"<string>\",\n \"winnerThreshold\": 123,\n \"variants\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sequenzy.com/api/v1/ab-tests")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"campaignId\": \"<string>\",\n \"automationNodeId\": \"<string>\",\n \"confirmLiveChange\": true,\n \"name\": \"<string>\",\n \"testPercentage\": 123,\n \"testDurationMinutes\": 123,\n \"winnerCriteria\": \"<string>\",\n \"testType\": \"<string>\",\n \"winnerThreshold\": 123,\n \"variants\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sequenzy.com/api/v1/ab-tests")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"campaignId\": \"<string>\",\n \"automationNodeId\": \"<string>\",\n \"confirmLiveChange\": true,\n \"name\": \"<string>\",\n \"testPercentage\": 123,\n \"testDurationMinutes\": 123,\n \"winnerCriteria\": \"<string>\",\n \"testType\": \"<string>\",\n \"winnerThreshold\": 123,\n \"variants\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"abTest": {
"id": "ab_abc123",
"campaignId": "camp_abc123",
"name": "A/B Test for April Launch",
"status": "draft",
"testPercentage": 20,
"testDurationMinutes": 240,
"winnerCriteria": "open_rate",
"variants": [
{ "id": "var_a", "label": "A", "subject": "A quick update" },
{ "id": "var_b", "label": "B", "subject": "Alternative subject line" }
]
}
}
{
"success": false,
"error": "testPercentage must be between 5 and 50"
}
{
"success": false,
"error": "Campaign structure can only be changed in draft or rejected status."
}
{
"success": false,
"error": "Maximum of 5 variants allowed"
}
{
"success": false,
"error": "Unauthorized"
}
{
"success": false,
"error": "Campaign not found"
}
{
"success": false,
"error": "A/B test already exists for this campaign"
}
{
"success": false,
"error": "Failed to create A/B test"
}