curl --request PATCH \
--url https://openapi.enginy.ai/v1/campaign/{campaignId} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"description": "<string>",
"identityId": 123,
"shouldAutomaticallySend": true,
"shouldSendTrackingPixel": true,
"shouldTrackEmailLinks": true,
"excludeContactedLeads": true,
"allowedEmails": [
"<string>"
],
"steps": [
{
"type": "email",
"subject": "<string>",
"content": "<string>",
"aiMessageId": "<string>"
}
]
}
'import requests
url = "https://openapi.enginy.ai/v1/campaign/{campaignId}"
payload = {
"name": "<string>",
"description": "<string>",
"identityId": 123,
"shouldAutomaticallySend": True,
"shouldSendTrackingPixel": True,
"shouldTrackEmailLinks": True,
"excludeContactedLeads": True,
"allowedEmails": ["<string>"],
"steps": [
{
"type": "email",
"subject": "<string>",
"content": "<string>",
"aiMessageId": "<string>"
}
]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
identityId: 123,
shouldAutomaticallySend: true,
shouldSendTrackingPixel: true,
shouldTrackEmailLinks: true,
excludeContactedLeads: true,
allowedEmails: ['<string>'],
steps: [
{
type: 'email',
subject: '<string>',
content: '<string>',
aiMessageId: '<string>'
}
]
})
};
fetch('https://openapi.enginy.ai/v1/campaign/{campaignId}', 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://openapi.enginy.ai/v1/campaign/{campaignId}",
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>',
'description' => '<string>',
'identityId' => 123,
'shouldAutomaticallySend' => true,
'shouldSendTrackingPixel' => true,
'shouldTrackEmailLinks' => true,
'excludeContactedLeads' => true,
'allowedEmails' => [
'<string>'
],
'steps' => [
[
'type' => 'email',
'subject' => '<string>',
'content' => '<string>',
'aiMessageId' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://openapi.enginy.ai/v1/campaign/{campaignId}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"identityId\": 123,\n \"shouldAutomaticallySend\": true,\n \"shouldSendTrackingPixel\": true,\n \"shouldTrackEmailLinks\": true,\n \"excludeContactedLeads\": true,\n \"allowedEmails\": [\n \"<string>\"\n ],\n \"steps\": [\n {\n \"type\": \"email\",\n \"subject\": \"<string>\",\n \"content\": \"<string>\",\n \"aiMessageId\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://openapi.enginy.ai/v1/campaign/{campaignId}")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"identityId\": 123,\n \"shouldAutomaticallySend\": true,\n \"shouldSendTrackingPixel\": true,\n \"shouldTrackEmailLinks\": true,\n \"excludeContactedLeads\": true,\n \"allowedEmails\": [\n \"<string>\"\n ],\n \"steps\": [\n {\n \"type\": \"email\",\n \"subject\": \"<string>\",\n \"content\": \"<string>\",\n \"aiMessageId\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openapi.enginy.ai/v1/campaign/{campaignId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"identityId\": 123,\n \"shouldAutomaticallySend\": true,\n \"shouldSendTrackingPixel\": true,\n \"shouldTrackEmailLinks\": true,\n \"excludeContactedLeads\": true,\n \"allowedEmails\": [\n \"<string>\"\n ],\n \"steps\": [\n {\n \"type\": \"email\",\n \"subject\": \"<string>\",\n \"content\": \"<string>\",\n \"aiMessageId\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"message": "<string>",
"data": {
"id": 123,
"appUrl": "<string>",
"name": "<string>",
"status": "DRAFT",
"identityId": 123,
"warnings": [
"<string>"
]
}
}Update a draft campaign
Update a DRAFT campaign in place: campaign settings and/or the full step sequence. steps uses the same simplified step model as POST /v1/campaigns and, when provided, replaces the whole stored sequence — fetch the current steps with GET /v1/campaign/{campaignId}, modify them, and resubmit. Rich-text formatting of steps whose text you did not change is preserved automatically. Campaigns that are not in DRAFT status cannot be updated; clone them instead.
Responses include direct Enginy app URLs when available. Responses include an appUrl that opens the updated campaign in Enginy. MCP agents should return those URLs to users whenever they are present in the response.
Required scope:
CAMPAIGNS_WRITERate limit: 30 requests per minute
curl --request PATCH \
--url https://openapi.enginy.ai/v1/campaign/{campaignId} \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"name": "<string>",
"description": "<string>",
"identityId": 123,
"shouldAutomaticallySend": true,
"shouldSendTrackingPixel": true,
"shouldTrackEmailLinks": true,
"excludeContactedLeads": true,
"allowedEmails": [
"<string>"
],
"steps": [
{
"type": "email",
"subject": "<string>",
"content": "<string>",
"aiMessageId": "<string>"
}
]
}
'import requests
url = "https://openapi.enginy.ai/v1/campaign/{campaignId}"
payload = {
"name": "<string>",
"description": "<string>",
"identityId": 123,
"shouldAutomaticallySend": True,
"shouldSendTrackingPixel": True,
"shouldTrackEmailLinks": True,
"excludeContactedLeads": True,
"allowedEmails": ["<string>"],
"steps": [
{
"type": "email",
"subject": "<string>",
"content": "<string>",
"aiMessageId": "<string>"
}
]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
identityId: 123,
shouldAutomaticallySend: true,
shouldSendTrackingPixel: true,
shouldTrackEmailLinks: true,
excludeContactedLeads: true,
allowedEmails: ['<string>'],
steps: [
{
type: 'email',
subject: '<string>',
content: '<string>',
aiMessageId: '<string>'
}
]
})
};
fetch('https://openapi.enginy.ai/v1/campaign/{campaignId}', 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://openapi.enginy.ai/v1/campaign/{campaignId}",
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>',
'description' => '<string>',
'identityId' => 123,
'shouldAutomaticallySend' => true,
'shouldSendTrackingPixel' => true,
'shouldTrackEmailLinks' => true,
'excludeContactedLeads' => true,
'allowedEmails' => [
'<string>'
],
'steps' => [
[
'type' => 'email',
'subject' => '<string>',
'content' => '<string>',
'aiMessageId' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://openapi.enginy.ai/v1/campaign/{campaignId}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"identityId\": 123,\n \"shouldAutomaticallySend\": true,\n \"shouldSendTrackingPixel\": true,\n \"shouldTrackEmailLinks\": true,\n \"excludeContactedLeads\": true,\n \"allowedEmails\": [\n \"<string>\"\n ],\n \"steps\": [\n {\n \"type\": \"email\",\n \"subject\": \"<string>\",\n \"content\": \"<string>\",\n \"aiMessageId\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://openapi.enginy.ai/v1/campaign/{campaignId}")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"identityId\": 123,\n \"shouldAutomaticallySend\": true,\n \"shouldSendTrackingPixel\": true,\n \"shouldTrackEmailLinks\": true,\n \"excludeContactedLeads\": true,\n \"allowedEmails\": [\n \"<string>\"\n ],\n \"steps\": [\n {\n \"type\": \"email\",\n \"subject\": \"<string>\",\n \"content\": \"<string>\",\n \"aiMessageId\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openapi.enginy.ai/v1/campaign/{campaignId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"identityId\": 123,\n \"shouldAutomaticallySend\": true,\n \"shouldSendTrackingPixel\": true,\n \"shouldTrackEmailLinks\": true,\n \"excludeContactedLeads\": true,\n \"allowedEmails\": [\n \"<string>\"\n ],\n \"steps\": [\n {\n \"type\": \"email\",\n \"subject\": \"<string>\",\n \"content\": \"<string>\",\n \"aiMessageId\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"message": "<string>",
"data": {
"id": 123,
"appUrl": "<string>",
"name": "<string>",
"status": "DRAFT",
"identityId": 123,
"warnings": [
"<string>"
]
}
}Authorizations
Path Parameters
The campaign ID to update
Body
Campaign name.
1Optional campaign description.
Allowed sender email addresses for this campaign.
Ordered campaign steps. Use branch arrays like onTrue, onFalse, onAccepted, and onNotAccepted for branching. Steps returned by GET /v1/campaign/{campaignId} can be resubmitted: the read-only stepId, connectionId, nextConnectionId, and advanced fields are accepted and ignored.
1- email
- linkedin_message
- linkedin_message_bundle
- linkedin_voice_message
- linkedin_inmail
- linkedin_visit_profile
- linkedin_like_last_post
- whatsapp_message
- condition
- linkedin_connection
- task
- add_to_another_campaign
- end
Show child attributes
Show child attributes