curl --request PATCH \
--url https://galinum.com/api/v1/campaigns/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"audience": {
"kind": "all",
"reason": "<string>"
},
"targeting": {
"traits": {
"plan": "free"
},
"events": {
"seen": [
"activated_workspace"
],
"not_seen": [
"used_csv_export"
]
}
},
"pages": [
"/settings/*"
],
"goalId": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": false
}
},
"variants": [
{
"id": "<string>",
"name": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": false
}
},
"weight": 50,
"isControl": true
}
],
"deliverFrom": 123,
"deliverUntil": 123
}
'import requests
url = "https://galinum.com/api/v1/campaigns/{id}"
payload = {
"name": "<string>",
"audience": {
"kind": "all",
"reason": "<string>"
},
"targeting": {
"traits": { "plan": "free" },
"events": {
"seen": ["activated_workspace"],
"not_seen": ["used_csv_export"]
}
},
"pages": ["/settings/*"],
"goalId": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": False
}
},
"variants": [
{
"id": "<string>",
"name": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": False
}
},
"weight": 50,
"isControl": True
}
],
"deliverFrom": 123,
"deliverUntil": 123
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
audience: {kind: 'all', reason: '<string>'},
targeting: {
traits: {plan: 'free'},
events: {seen: ['activated_workspace'], not_seen: ['used_csv_export']}
},
pages: ['/settings/*'],
goalId: '<string>',
message: {
presentation: 'toast',
title: 'CSV export is here 📊',
body: JSON.stringify('Export any table to CSV from the toolbar.'),
media: {
url: 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
alt: 'Screenshot of the new analytics dashboard',
decorative: false
}
},
variants: [
{
id: '<string>',
name: '<string>',
message: {
presentation: 'toast',
title: 'CSV export is here 📊',
body: JSON.stringify('Export any table to CSV from the toolbar.'),
media: {
url: 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
alt: 'Screenshot of the new analytics dashboard',
decorative: false
}
},
weight: 50,
isControl: true
}
],
deliverFrom: 123,
deliverUntil: 123
})
};
fetch('https://galinum.com/api/v1/campaigns/{id}', 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://galinum.com/api/v1/campaigns/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'audience' => [
'kind' => 'all',
'reason' => '<string>'
],
'targeting' => [
'traits' => [
'plan' => 'free'
],
'events' => [
'seen' => [
'activated_workspace'
],
'not_seen' => [
'used_csv_export'
]
]
],
'pages' => [
'/settings/*'
],
'goalId' => '<string>',
'message' => [
'presentation' => 'toast',
'title' => 'CSV export is here 📊',
'body' => 'Export any table to CSV from the toolbar.',
'media' => [
'url' => 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
'alt' => 'Screenshot of the new analytics dashboard',
'decorative' => false
]
],
'variants' => [
[
'id' => '<string>',
'name' => '<string>',
'message' => [
'presentation' => 'toast',
'title' => 'CSV export is here 📊',
'body' => 'Export any table to CSV from the toolbar.',
'media' => [
'url' => 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
'alt' => 'Screenshot of the new analytics dashboard',
'decorative' => false
]
],
'weight' => 50,
'isControl' => true
]
],
'deliverFrom' => 123,
'deliverUntil' => 123
]),
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://galinum.com/api/v1/campaigns/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"audience\": {\n \"kind\": \"all\",\n \"reason\": \"<string>\"\n },\n \"targeting\": {\n \"traits\": {\n \"plan\": \"free\"\n },\n \"events\": {\n \"seen\": [\n \"activated_workspace\"\n ],\n \"not_seen\": [\n \"used_csv_export\"\n ]\n }\n },\n \"pages\": [\n \"/settings/*\"\n ],\n \"goalId\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"variants\": [\n {\n \"id\": \"<string>\",\n \"name\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"weight\": 50,\n \"isControl\": true\n }\n ],\n \"deliverFrom\": 123,\n \"deliverUntil\": 123\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://galinum.com/api/v1/campaigns/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"audience\": {\n \"kind\": \"all\",\n \"reason\": \"<string>\"\n },\n \"targeting\": {\n \"traits\": {\n \"plan\": \"free\"\n },\n \"events\": {\n \"seen\": [\n \"activated_workspace\"\n ],\n \"not_seen\": [\n \"used_csv_export\"\n ]\n }\n },\n \"pages\": [\n \"/settings/*\"\n ],\n \"goalId\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"variants\": [\n {\n \"id\": \"<string>\",\n \"name\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"weight\": 50,\n \"isControl\": true\n }\n ],\n \"deliverFrom\": 123,\n \"deliverUntil\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://galinum.com/api/v1/campaigns/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"audience\": {\n \"kind\": \"all\",\n \"reason\": \"<string>\"\n },\n \"targeting\": {\n \"traits\": {\n \"plan\": \"free\"\n },\n \"events\": {\n \"seen\": [\n \"activated_workspace\"\n ],\n \"not_seen\": [\n \"used_csv_export\"\n ]\n }\n },\n \"pages\": [\n \"/settings/*\"\n ],\n \"goalId\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"variants\": [\n {\n \"id\": \"<string>\",\n \"name\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"weight\": 50,\n \"isControl\": true\n }\n ],\n \"deliverFrom\": 123,\n \"deliverUntil\": 123\n}"
response = http.request(request)
puts response.read_body{
"campaign": {
"id": "cmp_3ce6dba5-7f36-41f5-9327-d5cc3099ab77",
"name": "Launch: CSV export",
"status": "draft",
"effectiveStatus": "draft",
"channel": "web_inapp",
"goalId": "<string>",
"createdBy": "api",
"createdAt": 1784067764978,
"startedAt": 123,
"endedAt": 123,
"deliverFrom": 123,
"deliverUntil": 123,
"audience": {
"kind": "all"
},
"targeting": {
"traits": {
"plan": "free"
},
"events": {
"seen": [
"activated_workspace"
],
"not_seen": [
"used_csv_export"
]
}
},
"pages": [
"/dashboard",
"/settings/*"
],
"stats": {
"sent": 123,
"frequencyCapped": 123,
"delivered": 123,
"shown": 123,
"opened": 123,
"clicked": 123,
"dismissed": 123,
"bounced": 123,
"complained": 123,
"unsubscribed": 123,
"converted": 123
},
"variants": [
{
"id": "var_37705a49-52c6-4577-aeed-665099a1e13d",
"name": "A",
"weight": 1,
"isControl": true,
"content": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"cta": {
"label": "Try it",
"destination": {
"kind": "website",
"url": "https://app.example.com/exports"
}
},
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": false
}
},
"stats": {
"sent": 123,
"frequencyCapped": 123,
"delivered": 123,
"shown": 123,
"opened": 123,
"clicked": 123,
"dismissed": 123,
"bounced": 123,
"complained": 123,
"unsubscribed": 123,
"converted": 123
}
}
],
"sourceChanges": {
"revision": "<string>",
"changes": [
{
"sourceId": "<string>",
"kind": "commit",
"sha": "<string>"
}
]
},
"push": {
"appId": "<string>",
"selection": {
"kind": "last_active"
},
"ttlSeconds": 1209600,
"replacementKey": "<string>"
}
}
}{
"error": "userId is required"
}{
"error": "Unauthorized"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "Invalid request"
}{
"error": "Too many requests"
}{
"error": "Could not identify user"
}{
"error": "<string>"
}Update a campaign
Edits any subset of name, targeting, message content, variants, and the delivery window. message only works on single-variant campaigns; variants entries with an id update that variant, entries without one create a new variant (variants are never deleted — retire one with weight: 0; a campaign keeps at most 10 variants, exactly one control, and at least one positive weight). Extending deliverUntil into the future resumes an expired campaign (a paused one additionally needs the launch status action). Optional sourceChanges declares the changes for deployment-based activation. Content and declaration commit atomically. Declaring changes does not approve the campaign. Approval survives later edits, but launch requires coverage for the current declaration and current channel readiness. Omission preserves the declaration. Replacement requires sourceChanges.expectedRevision from campaign detail. Source-managed preparations cannot replace their associations through this field; the request returns 409 before any copy mutation.
curl --request PATCH \
--url https://galinum.com/api/v1/campaigns/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"audience": {
"kind": "all",
"reason": "<string>"
},
"targeting": {
"traits": {
"plan": "free"
},
"events": {
"seen": [
"activated_workspace"
],
"not_seen": [
"used_csv_export"
]
}
},
"pages": [
"/settings/*"
],
"goalId": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": false
}
},
"variants": [
{
"id": "<string>",
"name": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": false
}
},
"weight": 50,
"isControl": true
}
],
"deliverFrom": 123,
"deliverUntil": 123
}
'import requests
url = "https://galinum.com/api/v1/campaigns/{id}"
payload = {
"name": "<string>",
"audience": {
"kind": "all",
"reason": "<string>"
},
"targeting": {
"traits": { "plan": "free" },
"events": {
"seen": ["activated_workspace"],
"not_seen": ["used_csv_export"]
}
},
"pages": ["/settings/*"],
"goalId": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": False
}
},
"variants": [
{
"id": "<string>",
"name": "<string>",
"message": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": False
}
},
"weight": 50,
"isControl": True
}
],
"deliverFrom": 123,
"deliverUntil": 123
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
audience: {kind: 'all', reason: '<string>'},
targeting: {
traits: {plan: 'free'},
events: {seen: ['activated_workspace'], not_seen: ['used_csv_export']}
},
pages: ['/settings/*'],
goalId: '<string>',
message: {
presentation: 'toast',
title: 'CSV export is here 📊',
body: JSON.stringify('Export any table to CSV from the toolbar.'),
media: {
url: 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
alt: 'Screenshot of the new analytics dashboard',
decorative: false
}
},
variants: [
{
id: '<string>',
name: '<string>',
message: {
presentation: 'toast',
title: 'CSV export is here 📊',
body: JSON.stringify('Export any table to CSV from the toolbar.'),
media: {
url: 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
alt: 'Screenshot of the new analytics dashboard',
decorative: false
}
},
weight: 50,
isControl: true
}
],
deliverFrom: 123,
deliverUntil: 123
})
};
fetch('https://galinum.com/api/v1/campaigns/{id}', 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://galinum.com/api/v1/campaigns/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'audience' => [
'kind' => 'all',
'reason' => '<string>'
],
'targeting' => [
'traits' => [
'plan' => 'free'
],
'events' => [
'seen' => [
'activated_workspace'
],
'not_seen' => [
'used_csv_export'
]
]
],
'pages' => [
'/settings/*'
],
'goalId' => '<string>',
'message' => [
'presentation' => 'toast',
'title' => 'CSV export is here 📊',
'body' => 'Export any table to CSV from the toolbar.',
'media' => [
'url' => 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
'alt' => 'Screenshot of the new analytics dashboard',
'decorative' => false
]
],
'variants' => [
[
'id' => '<string>',
'name' => '<string>',
'message' => [
'presentation' => 'toast',
'title' => 'CSV export is here 📊',
'body' => 'Export any table to CSV from the toolbar.',
'media' => [
'url' => 'https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png',
'alt' => 'Screenshot of the new analytics dashboard',
'decorative' => false
]
],
'weight' => 50,
'isControl' => true
]
],
'deliverFrom' => 123,
'deliverUntil' => 123
]),
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://galinum.com/api/v1/campaigns/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"audience\": {\n \"kind\": \"all\",\n \"reason\": \"<string>\"\n },\n \"targeting\": {\n \"traits\": {\n \"plan\": \"free\"\n },\n \"events\": {\n \"seen\": [\n \"activated_workspace\"\n ],\n \"not_seen\": [\n \"used_csv_export\"\n ]\n }\n },\n \"pages\": [\n \"/settings/*\"\n ],\n \"goalId\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"variants\": [\n {\n \"id\": \"<string>\",\n \"name\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"weight\": 50,\n \"isControl\": true\n }\n ],\n \"deliverFrom\": 123,\n \"deliverUntil\": 123\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://galinum.com/api/v1/campaigns/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"audience\": {\n \"kind\": \"all\",\n \"reason\": \"<string>\"\n },\n \"targeting\": {\n \"traits\": {\n \"plan\": \"free\"\n },\n \"events\": {\n \"seen\": [\n \"activated_workspace\"\n ],\n \"not_seen\": [\n \"used_csv_export\"\n ]\n }\n },\n \"pages\": [\n \"/settings/*\"\n ],\n \"goalId\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"variants\": [\n {\n \"id\": \"<string>\",\n \"name\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"weight\": 50,\n \"isControl\": true\n }\n ],\n \"deliverFrom\": 123,\n \"deliverUntil\": 123\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://galinum.com/api/v1/campaigns/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"audience\": {\n \"kind\": \"all\",\n \"reason\": \"<string>\"\n },\n \"targeting\": {\n \"traits\": {\n \"plan\": \"free\"\n },\n \"events\": {\n \"seen\": [\n \"activated_workspace\"\n ],\n \"not_seen\": [\n \"used_csv_export\"\n ]\n }\n },\n \"pages\": [\n \"/settings/*\"\n ],\n \"goalId\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"variants\": [\n {\n \"id\": \"<string>\",\n \"name\": \"<string>\",\n \"message\": {\n \"presentation\": \"toast\",\n \"title\": \"CSV export is here 📊\",\n \"body\": \"Export any table to CSV from the toolbar.\",\n \"media\": {\n \"url\": \"https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png\",\n \"alt\": \"Screenshot of the new analytics dashboard\",\n \"decorative\": false\n }\n },\n \"weight\": 50,\n \"isControl\": true\n }\n ],\n \"deliverFrom\": 123,\n \"deliverUntil\": 123\n}"
response = http.request(request)
puts response.read_body{
"campaign": {
"id": "cmp_3ce6dba5-7f36-41f5-9327-d5cc3099ab77",
"name": "Launch: CSV export",
"status": "draft",
"effectiveStatus": "draft",
"channel": "web_inapp",
"goalId": "<string>",
"createdBy": "api",
"createdAt": 1784067764978,
"startedAt": 123,
"endedAt": 123,
"deliverFrom": 123,
"deliverUntil": 123,
"audience": {
"kind": "all"
},
"targeting": {
"traits": {
"plan": "free"
},
"events": {
"seen": [
"activated_workspace"
],
"not_seen": [
"used_csv_export"
]
}
},
"pages": [
"/dashboard",
"/settings/*"
],
"stats": {
"sent": 123,
"frequencyCapped": 123,
"delivered": 123,
"shown": 123,
"opened": 123,
"clicked": 123,
"dismissed": 123,
"bounced": 123,
"complained": 123,
"unsubscribed": 123,
"converted": 123
},
"variants": [
{
"id": "var_37705a49-52c6-4577-aeed-665099a1e13d",
"name": "A",
"weight": 1,
"isControl": true,
"content": {
"presentation": "toast",
"title": "CSV export is here 📊",
"body": "Export any table to CSV from the toolbar.",
"cta": {
"label": "Try it",
"destination": {
"kind": "website",
"url": "https://app.example.com/exports"
}
},
"media": {
"url": "https://galinum.example/media/projects/prj_123/media/9c2f0b7e-4d11-4c2a-a3d1-1c9a1a2b3c4d.png",
"alt": "Screenshot of the new analytics dashboard",
"decorative": false
}
},
"stats": {
"sent": 123,
"frequencyCapped": 123,
"delivered": 123,
"shown": 123,
"opened": 123,
"clicked": 123,
"dismissed": 123,
"bounced": 123,
"complained": 123,
"unsubscribed": 123,
"converted": 123
}
}
],
"sourceChanges": {
"revision": "<string>",
"changes": [
{
"sourceId": "<string>",
"kind": "commit",
"sha": "<string>"
}
]
},
"push": {
"appId": "<string>",
"selection": {
"kind": "last_active"
},
"ttlSeconds": 1209600,
"replacementKey": "<string>"
}
}
}{
"error": "userId is required"
}{
"error": "Unauthorized"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "Invalid request"
}{
"error": "Too many requests"
}{
"error": "Could not identify user"
}{
"error": "<string>"
}Authorizations
Your project's secret key (pk_…, without the pub segment). Server-side only — never ship it to a browser. Get it from Settings → Projects in the dashboard.
Path Parameters
128Body
Rename the campaign.
80Canonical audience union. null or { "kind": "all" } targets everyone. { "kind": "expression", "expression": { … }, "reason": "…" } authors an inline audience stored as an immutable audience version. { "kind": "segment", "segment": "id-or-key", "version": n? } pins a saved segment version (omitted version = current, resolved atomically; archived segments are refused). Check expressions first with POST /api/v1/audiences/check. Mutually exclusive with the deprecated targeting field.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
Deprecated shorthand for the same audience semantics (strict trait equality + events seen/not_seen, ANDed). Still accepted; normalized into an immutable audience version. Prefer audience.
Show child attributes
Show child attributes
Web in-app only. Replace path patterns; null or [] clears them. Email campaigns reject this field.
20256Link the campaign to a goal in this project; null unlinks. Linking takes effect for target events tracked from then on — it never rewrites past deliveries.
1Replace the content of a single-variant campaign (400 if the campaign has more than one variant). Mutually exclusive with variants.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
Variant patches: entries with an id update that variant, entries without one create a new variant (message required). Mutually exclusive with message.
1 - 10 elementsShow child attributes
Show child attributes
Replace the delivery-window start (epoch milliseconds or ISO-8601 with an explicit timezone offset); null clears it.
Replace the delivery-window end (must stay after deliverFrom and, when set, be in the future); null clears it.
Show child attributes
Show child attributes
Explicit replacement of prepared sources. Requires the current sourceChanges.revision. Omission preserves the declaration and approval. Content and source replacement commit atomically; approval survives edits, but current source coverage is required. Source-managed preparations reject this field with 409 before any copy mutation.
Show child attributes
Show child attributes
Response
The updated campaign with fresh variants and stats.
Show child attributes
Show child attributes