curl --request GET \
--url https://api.privy.com/v1/campaigns/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.privy.com/v1/campaigns/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.privy.com/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://api.privy.com/v1/campaigns/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.privy.com/v1/campaigns/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.privy.com/v1/campaigns/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.privy.com/v1/campaigns/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"id": "Nw8K2rT5xY",
"type": "newsletter",
"title": "June Restock Announcement",
"channel": "email",
"status": "sent",
"subject": "The restock you asked for is here",
"send_date": "2026-06-18T15:00:00Z",
"audience": {
"included_segments": [
{
"id": "aBc1234",
"name": "Engaged 90d",
"prebuilt": false
},
{
"id": "potential_customers",
"name": "Potential Customers",
"prebuilt": true
}
],
"excluded_segments": [
{
"id": "dEf5678",
"name": "Recent purchasers",
"prebuilt": false
}
]
},
"coupon": null,
"ab_test": {
"winning_metric": "click_rate",
"test_duration_seconds": 86400,
"versions": [
{
"id": "cpv_dkyYZmk",
"name": "Version A",
"is_control": true,
"is_winner": false,
"audience_share": 0.125,
"subject": "The restock you asked for is here",
"preheader": "Back in stock and going fast",
"coupon": null
},
{
"id": "cpv_YJGOjpJ",
"name": "Version B",
"is_control": false,
"is_winner": true,
"audience_share": 0.125,
"subject": "Your size is back, but not for long",
"preheader": "We saved you a look",
"coupon": {
"id": "7k2dG6Y",
"title": "RESTOCK20",
"kind": "master",
"platform": "manual"
}
}
]
},
"created_at": "2026-06-10T09:00:00Z",
"updated_at": "2026-06-18T15:05:00Z"
}
}Get a campaign
Retrieve a single message campaign by its identifier. Resolves both
newsletters and flow campaigns — no type parameter needed. A flow
campaign names the flow that sends it in flow; newsletters omit
that field.
A /v1/campaigns row already carries this exact shape, so following up
per campaign adds nothing — reach for this when the id came from
somewhere else, such as a flow node’s data.campaign_id or a report
row’s campaign_id. Performance is
/v1/reports/campaigns/{campaign_id}.
Required scope: campaigns_read
curl --request GET \
--url https://api.privy.com/v1/campaigns/{id} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.privy.com/v1/campaigns/{id}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.privy.com/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://api.privy.com/v1/campaigns/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.privy.com/v1/campaigns/{id}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.privy.com/v1/campaigns/{id}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.privy.com/v1/campaigns/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"id": "Nw8K2rT5xY",
"type": "newsletter",
"title": "June Restock Announcement",
"channel": "email",
"status": "sent",
"subject": "The restock you asked for is here",
"send_date": "2026-06-18T15:00:00Z",
"audience": {
"included_segments": [
{
"id": "aBc1234",
"name": "Engaged 90d",
"prebuilt": false
},
{
"id": "potential_customers",
"name": "Potential Customers",
"prebuilt": true
}
],
"excluded_segments": [
{
"id": "dEf5678",
"name": "Recent purchasers",
"prebuilt": false
}
]
},
"coupon": null,
"ab_test": {
"winning_metric": "click_rate",
"test_duration_seconds": 86400,
"versions": [
{
"id": "cpv_dkyYZmk",
"name": "Version A",
"is_control": true,
"is_winner": false,
"audience_share": 0.125,
"subject": "The restock you asked for is here",
"preheader": "Back in stock and going fast",
"coupon": null
},
{
"id": "cpv_YJGOjpJ",
"name": "Version B",
"is_control": false,
"is_winner": true,
"audience_share": 0.125,
"subject": "Your size is back, but not for long",
"preheader": "We saved you a look",
"coupon": {
"id": "7k2dG6Y",
"title": "RESTOCK20",
"kind": "master",
"platform": "manual"
}
}
]
},
"created_at": "2026-06-10T09:00:00Z",
"updated_at": "2026-06-18T15:05:00Z"
}
}Authorizations
Send either an API token or an OAuth access token as
Authorization: Bearer <token>. See the Authentication page for details.
Headers
Target a subaccount instead of the main connected account.
Pass a subaccount id from get_account's subaccounts list. Only direct subaccounts
of the connected account are reachable — omit this for the main account itself.
Path Parameters
The campaign's unique identifier (returned as id in campaign responses). Ids are opaque public strings — a numeric id from a Privy dashboard URL is not a valid API id and will 404; list campaigns and match by title instead.
Response
The message campaign.
A message campaign — configuration only; send statistics belong to the
reporting surface. type discriminates the two families: newsletter
(email + SMS broadcasts) and flow (the email/SMS messages a flow sends).
Newsletter-only fields (status, send_date, audience) are null
for flow campaigns — the flow's trigger decides who receives them and when.
Show child attributes
Show child attributes
Was this page helpful?