Campaigns
Create Campaign Variation
Save a version of a campaign email as a variation
POST
/
api
/
v1
/
campaigns
/
{campaignId}
/
variations
Create Campaign Variation
curl --request POST \
--url https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"blocks": [
{}
],
"html": "<string>",
"summary": {},
"subject": {},
"previewText": {},
"parentVariationId": {},
"emailTheme": {},
"fontFamily": {}
}
'import requests
url = "https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations"
payload = {
"name": "<string>",
"blocks": [{}],
"html": "<string>",
"summary": {},
"subject": {},
"previewText": {},
"parentVariationId": {},
"emailTheme": {},
"fontFamily": {}
}
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({
name: '<string>',
blocks: [{}],
html: '<string>',
summary: {},
subject: {},
previewText: {},
parentVariationId: {},
emailTheme: {},
fontFamily: {}
})
};
fetch('https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations', 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/campaigns/{campaignId}/variations",
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([
'name' => '<string>',
'blocks' => [
[
]
],
'html' => '<string>',
'summary' => [
],
'subject' => [
],
'previewText' => [
],
'parentVariationId' => [
],
'emailTheme' => [
],
'fontFamily' => [
]
]),
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/campaigns/{campaignId}/variations"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"blocks\": [\n {}\n ],\n \"html\": \"<string>\",\n \"summary\": {},\n \"subject\": {},\n \"previewText\": {},\n \"parentVariationId\": {},\n \"emailTheme\": {},\n \"fontFamily\": {}\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/campaigns/{campaignId}/variations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"blocks\": [\n {}\n ],\n \"html\": \"<string>\",\n \"summary\": {},\n \"subject\": {},\n \"previewText\": {},\n \"parentVariationId\": {},\n \"emailTheme\": {},\n \"fontFamily\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations")
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 \"name\": \"<string>\",\n \"blocks\": [\n {}\n ],\n \"html\": \"<string>\",\n \"summary\": {},\n \"subject\": {},\n \"previewText\": {},\n \"parentVariationId\": {},\n \"emailTheme\": {},\n \"fontFamily\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"variation": {
"id": "var_9xk2",
"emailId": "email_abc123",
"parentId": null,
"label": "V2",
"name": "Warm and personal",
"summary": "Rewrote the opening in a friendlier voice and shortened the body.",
"prompt": "Three warmer, shorter versions",
"style": "fresh",
"status": "ready",
"error": null,
"subject": "A quick note about our pricing",
"previewText": null,
"blocks": [
{ "id": "h1", "type": "heading", "content": "A quick note about pricing", "level": 1 }
],
"emailTheme": null,
"fontFamily": null,
"position": null,
"inUse": false,
"usedAt": null,
"createdAt": "2026-10-14T09:12:00.000Z",
"updatedAt": "2026-10-14T09:12:41.000Z"
}
}
{
"error": "Provide the variation's blocks or html."
}
{
"error": "Invalid API key"
}
{
"error": "Variation not found"
}
Saves content as a new
ready variation, for example a copy of a version you want to take in another direction. Provide blocks or html, not both. Blocks without a footer get the company’s default footer, as with Update Campaign. The campaign email does not change.
Request
string
required
Campaign ID. Email campaigns only.
string
required
Name shown on the canvas. 1 to 120 characters.
array
Email blocks, validated like campaign
content. Required unless you send
html.string
HTML converted to blocks. Use instead of
blocks.string | null
What this version changes, up to 500 characters.
string | null
The subject this variation uses. Omit or send
null to keep the email’s
subject when it is used.string | null
The preview text this variation uses. Omit or send
null to keep the email’s.string | null
The variation this one is derived from. It is labeled as a branch of it
(
V2.1, V2.2, …). Omit for a version of the email (V1, V2, …).object | null
The variation’s own email theme (
presetId, colors, typography,
layout). A partial theme is completed with defaults. null uses the
email’s theme. Using the variation puts its theme on the email.string | null
The variation’s own body font stack, up to 500 characters.
null uses the
email’s font.curl -X POST "https://api.sequenzy.com/api/v1/campaigns/camp_abc123/variations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Shorter intro",
"blocks": [
{ "id": "h1", "type": "heading", "content": "A quick note about pricing", "level": 1 }
]
}'
Response
object
The new variation. See List
Variations.
string[]
Block fields that were accepted but had no effect. Omitted when there are
none.
{
"success": true,
"variation": {
"id": "var_9xk2",
"emailId": "email_abc123",
"parentId": null,
"label": "V2",
"name": "Warm and personal",
"summary": "Rewrote the opening in a friendlier voice and shortened the body.",
"prompt": "Three warmer, shorter versions",
"style": "fresh",
"status": "ready",
"error": null,
"subject": "A quick note about our pricing",
"previewText": null,
"blocks": [
{ "id": "h1", "type": "heading", "content": "A quick note about pricing", "level": 1 }
],
"emailTheme": null,
"fontFamily": null,
"position": null,
"inUse": false,
"usedAt": null,
"createdAt": "2026-10-14T09:12:00.000Z",
"updatedAt": "2026-10-14T09:12:41.000Z"
}
}
{
"error": "Provide the variation's blocks or html."
}
{
"error": "Invalid API key"
}
{
"error": "Variation not found"
}
⌘I
Create Campaign Variation
curl --request POST \
--url https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"blocks": [
{}
],
"html": "<string>",
"summary": {},
"subject": {},
"previewText": {},
"parentVariationId": {},
"emailTheme": {},
"fontFamily": {}
}
'import requests
url = "https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations"
payload = {
"name": "<string>",
"blocks": [{}],
"html": "<string>",
"summary": {},
"subject": {},
"previewText": {},
"parentVariationId": {},
"emailTheme": {},
"fontFamily": {}
}
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({
name: '<string>',
blocks: [{}],
html: '<string>',
summary: {},
subject: {},
previewText: {},
parentVariationId: {},
emailTheme: {},
fontFamily: {}
})
};
fetch('https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations', 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/campaigns/{campaignId}/variations",
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([
'name' => '<string>',
'blocks' => [
[
]
],
'html' => '<string>',
'summary' => [
],
'subject' => [
],
'previewText' => [
],
'parentVariationId' => [
],
'emailTheme' => [
],
'fontFamily' => [
]
]),
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/campaigns/{campaignId}/variations"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"blocks\": [\n {}\n ],\n \"html\": \"<string>\",\n \"summary\": {},\n \"subject\": {},\n \"previewText\": {},\n \"parentVariationId\": {},\n \"emailTheme\": {},\n \"fontFamily\": {}\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/campaigns/{campaignId}/variations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"blocks\": [\n {}\n ],\n \"html\": \"<string>\",\n \"summary\": {},\n \"subject\": {},\n \"previewText\": {},\n \"parentVariationId\": {},\n \"emailTheme\": {},\n \"fontFamily\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sequenzy.com/api/v1/campaigns/{campaignId}/variations")
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 \"name\": \"<string>\",\n \"blocks\": [\n {}\n ],\n \"html\": \"<string>\",\n \"summary\": {},\n \"subject\": {},\n \"previewText\": {},\n \"parentVariationId\": {},\n \"emailTheme\": {},\n \"fontFamily\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"variation": {
"id": "var_9xk2",
"emailId": "email_abc123",
"parentId": null,
"label": "V2",
"name": "Warm and personal",
"summary": "Rewrote the opening in a friendlier voice and shortened the body.",
"prompt": "Three warmer, shorter versions",
"style": "fresh",
"status": "ready",
"error": null,
"subject": "A quick note about our pricing",
"previewText": null,
"blocks": [
{ "id": "h1", "type": "heading", "content": "A quick note about pricing", "level": 1 }
],
"emailTheme": null,
"fontFamily": null,
"position": null,
"inUse": false,
"usedAt": null,
"createdAt": "2026-10-14T09:12:00.000Z",
"updatedAt": "2026-10-14T09:12:41.000Z"
}
}
{
"error": "Provide the variation's blocks or html."
}
{
"error": "Invalid API key"
}
{
"error": "Variation not found"
}