Add split variant
Add one more variant to an active split test, cloned from an active variant. sourceAgentId chooses it, and the Primary Variant is the default. A split holds up to five variants, counting excluded ones. Traffic is then shared equally between the live variants, the new one included, which replaces earlier weights. Excluded variants stay at 0.
This creates a real agent and is not idempotent on its own. Send an Idempotency-Key header to make a retry safe: a repeat answers 200 with idempotentReplay: true and adds nothing.
Required API key scope: agents:write.
curl --request POST \
--url https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"sourceAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45"
}'import requests
url = "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants"
payload = { "sourceAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45" }
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({sourceAgentId: 'agent_8a488fcfa8fdbf8ce8ad5ccc45'})
};
fetch('https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants', 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.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants",
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([
'sourceAgentId' => 'agent_8a488fcfa8fdbf8ce8ad5ccc45'
]),
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.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants"
payload := strings.NewReader("{\n \"sourceAgentId\": \"agent_8a488fcfa8fdbf8ce8ad5ccc45\"\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.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sourceAgentId\": \"agent_8a488fcfa8fdbf8ce8ad5ccc45\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants")
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 \"sourceAgentId\": \"agent_8a488fcfa8fdbf8ce8ad5ccc45\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"idempotentReplay": true,
"splitTest": {
"locationId": "loc_9f7a123",
"campaignId": "campaign_speed_to_lead_123",
"primaryAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"status": "active",
"revision": 4,
"sync": {
"status": "healthy",
"failedAt": null
},
"variants": [
{
"agentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"name": "Speed to Lead",
"sequence": 1,
"weight": 50,
"status": "active",
"addedAt": "2026-08-14T09:12:44.318Z",
"removedAt": null,
"isPrimary": true
},
{
"agentId": "agent_7c4e1b28f0a94d6591cc2fd340",
"name": "Speed to Lead II",
"sequence": 2,
"weight": 50,
"status": "active",
"addedAt": "2026-08-20T16:04:02.771Z",
"removedAt": null,
"isPrimary": false
}
]
}
}{
"success": true,
"splitTest": {
"locationId": "loc_9f7a123",
"campaignId": "campaign_speed_to_lead_123",
"primaryAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"status": "active",
"revision": 4,
"sync": {
"status": "healthy",
"failedAt": null
},
"variants": [
{
"agentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"name": "Speed to Lead",
"sequence": 1,
"weight": 50,
"status": "active",
"addedAt": "2026-08-14T09:12:44.318Z",
"removedAt": null,
"isPrimary": true
},
{
"agentId": "agent_7c4e1b28f0a94d6591cc2fd340",
"name": "Speed to Lead II",
"sequence": 2,
"weight": 50,
"status": "active",
"addedAt": "2026-08-20T16:04:02.771Z",
"removedAt": null,
"isPrimary": false
}
]
}
}{
"success": false,
"error": "VALIDATION",
"message": "Something here doesn't look right. Please check it and try again."
}{
"success": false,
"error": "Unauthorized",
"message": "Please sign in to continue."
}{
"success": false,
"error": "FORBIDDEN",
"message": "You don't have access to this. Ask your account admin if you need it."
}{
"success": false,
"error": "NOT_FOUND",
"message": "We couldn't find that. It may have been moved or deleted."
}{
"success": false,
"error": "CONFLICT",
"message": "This changed while you were working on it. Please refresh and try again."
}{
"success": false,
"error": "TooManyRequests",
"message": "That's a lot at once. Please wait a moment and try again."
}{
"success": false,
"error": "Internal",
"message": "Something went wrong on our side. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}Authorizations
Headers
Path Parameters
Body
Optional clone source.
Body is optional. Adding a variant shares traffic equally between the live variants, the new one included. Excluded variants stay at 0. Send the retry key as the Idempotency-Key header.
Response
An earlier request with this idempotency key already added the variant.
curl --request POST \
--url https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"sourceAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45"
}'import requests
url = "https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants"
payload = { "sourceAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45" }
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({sourceAgentId: 'agent_8a488fcfa8fdbf8ce8ad5ccc45'})
};
fetch('https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants', 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.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants",
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([
'sourceAgentId' => 'agent_8a488fcfa8fdbf8ce8ad5ccc45'
]),
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.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants"
payload := strings.NewReader("{\n \"sourceAgentId\": \"agent_8a488fcfa8fdbf8ce8ad5ccc45\"\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.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sourceAgentId\": \"agent_8a488fcfa8fdbf8ce8ad5ccc45\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.teamfollowup.ai/api/agent-builder/agents/{id}/split-test/variants")
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 \"sourceAgentId\": \"agent_8a488fcfa8fdbf8ce8ad5ccc45\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"idempotentReplay": true,
"splitTest": {
"locationId": "loc_9f7a123",
"campaignId": "campaign_speed_to_lead_123",
"primaryAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"status": "active",
"revision": 4,
"sync": {
"status": "healthy",
"failedAt": null
},
"variants": [
{
"agentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"name": "Speed to Lead",
"sequence": 1,
"weight": 50,
"status": "active",
"addedAt": "2026-08-14T09:12:44.318Z",
"removedAt": null,
"isPrimary": true
},
{
"agentId": "agent_7c4e1b28f0a94d6591cc2fd340",
"name": "Speed to Lead II",
"sequence": 2,
"weight": 50,
"status": "active",
"addedAt": "2026-08-20T16:04:02.771Z",
"removedAt": null,
"isPrimary": false
}
]
}
}{
"success": true,
"splitTest": {
"locationId": "loc_9f7a123",
"campaignId": "campaign_speed_to_lead_123",
"primaryAgentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"status": "active",
"revision": 4,
"sync": {
"status": "healthy",
"failedAt": null
},
"variants": [
{
"agentId": "agent_8a488fcfa8fdbf8ce8ad5ccc45",
"name": "Speed to Lead",
"sequence": 1,
"weight": 50,
"status": "active",
"addedAt": "2026-08-14T09:12:44.318Z",
"removedAt": null,
"isPrimary": true
},
{
"agentId": "agent_7c4e1b28f0a94d6591cc2fd340",
"name": "Speed to Lead II",
"sequence": 2,
"weight": 50,
"status": "active",
"addedAt": "2026-08-20T16:04:02.771Z",
"removedAt": null,
"isPrimary": false
}
]
}
}{
"success": false,
"error": "VALIDATION",
"message": "Something here doesn't look right. Please check it and try again."
}{
"success": false,
"error": "Unauthorized",
"message": "Please sign in to continue."
}{
"success": false,
"error": "FORBIDDEN",
"message": "You don't have access to this. Ask your account admin if you need it."
}{
"success": false,
"error": "NOT_FOUND",
"message": "We couldn't find that. It may have been moved or deleted."
}{
"success": false,
"error": "CONFLICT",
"message": "This changed while you were working on it. Please refresh and try again."
}{
"success": false,
"error": "TooManyRequests",
"message": "That's a lot at once. Please wait a moment and try again."
}{
"success": false,
"error": "Internal",
"message": "Something went wrong on our side. Please try again in a moment.",
"ref": "3f2b8c1e-7d4a-4f8e-9b6a-2c1d0e5f7a9b"
}