curl --request PATCH \
--url https://openapi.enginy.ai/v1/campaign/{campaignId}/status \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{}'import requests
url = "https://openapi.enginy.ai/v1/campaign/{campaignId}/status"
payload = {}
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({})
};
fetch('https://openapi.enginy.ai/v1/campaign/{campaignId}/status', 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}/status",
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([
]),
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}/status"
payload := strings.NewReader("{}")
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}/status")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openapi.enginy.ai/v1/campaign/{campaignId}/status")
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 = "{}"
response = http.request(request)
puts response.read_body{
"status": "success",
"message": "<string>",
"data": {
"id": 123,
"appUrl": "<string>",
"status": "<string>"
}
}{
"status": "error",
"message": "<string>",
"code": "CAMPAIGN_SCHEDULE_EMPTY",
"identityId": 123,
"identityName": "<string>"
}Update campaign status
Update campaign status to DRAFT, PENDING, ACTIVE, COMPLETED, or DELETED. Setting status to ACTIVE launches the campaign: it assigns identities and emails to conversations and starts sending. To stop a campaign sending, set status to PENDING. GET /v1/campaign/ and GET /v1/campaigns report that campaign as PENDING; only GET /v1/campaign//analytics translates it to the user-facing status PAUSED with isPaused: true. DRAFT is accepted only for campaigns that have never launched: a launched campaign cannot return to DRAFT, because DRAFT does not stop conversations that are already running. Clone the campaign (POST /v1/campaign//clone) to edit it. To stop outreach to a single contact rather than the whole campaign, use pause_a_contact_in_a_campaign. Setting status to COMPLETED or DELETED is terminal: conversations are marked completed or deleted and the campaign cannot move back to DRAFT, PENDING, or ACTIVE afterward (a COMPLETED campaign can only move to DELETED).
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}/status \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{}'import requests
url = "https://openapi.enginy.ai/v1/campaign/{campaignId}/status"
payload = {}
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({})
};
fetch('https://openapi.enginy.ai/v1/campaign/{campaignId}/status', 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}/status",
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([
]),
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}/status"
payload := strings.NewReader("{}")
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}/status")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://openapi.enginy.ai/v1/campaign/{campaignId}/status")
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 = "{}"
response = http.request(request)
puts response.read_body{
"status": "success",
"message": "<string>",
"data": {
"id": 123,
"appUrl": "<string>",
"status": "<string>"
}
}{
"status": "error",
"message": "<string>",
"code": "CAMPAIGN_SCHEDULE_EMPTY",
"identityId": 123,
"identityName": "<string>"
}Authorizations
Path Parameters
The campaign ID to update
Body
Target campaign status. To stop a campaign sending, use PENDING; GET /v1/campaign/{campaignId} and GET /v1/campaigns keep reporting PENDING, while GET /v1/campaign/{campaignId}/analytics reports the user-facing status PAUSED with isPaused: true. DRAFT is accepted only for campaigns that have never launched: a launched campaign cannot return to DRAFT, because DRAFT does not stop conversations that are already running. To stop one contact instead, use pause_a_contact_in_a_campaign. COMPLETED and DELETED are terminal (a COMPLETED campaign can only move to DELETED).
DRAFT, PENDING, ACTIVE, COMPLETED, DELETED