curl --request PATCH \
--url https://fandom-api-preview.vercel.app/api/v1/campaigns/{campaignId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Spring launch (US and Canada)",
"budget": 75,
"locations": [
"US",
"CA"
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Spring launch (US and Canada)', budget: 75, locations: ['US', 'CA']})
};
fetch('https://fandom-api-preview.vercel.app/api/v1/campaigns/{campaignId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://fandom-api-preview.vercel.app/api/v1/campaigns/{campaignId}"
payload = {
"name": "Spring launch (US and Canada)",
"budget": 75,
"locations": ["US", "CA"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"id": "<string>",
"name": "<string>",
"status": "<string>",
"objective": "<string>",
"brandId": "<string>",
"brand": {
"name": "<string>",
"website": "<string>",
"description": "<string>"
},
"industry": "<string>",
"language": "<string>",
"locations": [
"<string>"
],
"successMetrics": [
"<string>"
],
"campaignType": "<string>",
"budget": 123,
"budgetType": "daily",
"endDate": "<string>",
"biddingStrategy": "<string>",
"targetCpa": 123,
"targetRoas": 123,
"audiences": [
{
"id": "<string>",
"name": "<string>",
"audienceId": "<string>",
"dataStoreIds": [
"<string>"
]
}
],
"googleAds": {
"customerId": "<string>",
"accountName": "<string>",
"campaignId": "<string>",
"status": "<string>"
},
"url": "<string>",
"createdAt": "<string>",
"updatedAt": "<string>"
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}Update a campaign
Send only the fields to change. Google Ads settings are saved in Fandom; a campaign already in Google Ads picks them up on its next sync from the app.
Scope: campaigns:write.
Send an Idempotency-Key header to make retries safe.
curl --request PATCH \
--url https://fandom-api-preview.vercel.app/api/v1/campaigns/{campaignId} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Spring launch (US and Canada)",
"budget": 75,
"locations": [
"US",
"CA"
]
}
'const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: 'Spring launch (US and Canada)', budget: 75, locations: ['US', 'CA']})
};
fetch('https://fandom-api-preview.vercel.app/api/v1/campaigns/{campaignId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://fandom-api-preview.vercel.app/api/v1/campaigns/{campaignId}"
payload = {
"name": "Spring launch (US and Canada)",
"budget": 75,
"locations": ["US", "CA"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text){
"id": "<string>",
"name": "<string>",
"status": "<string>",
"objective": "<string>",
"brandId": "<string>",
"brand": {
"name": "<string>",
"website": "<string>",
"description": "<string>"
},
"industry": "<string>",
"language": "<string>",
"locations": [
"<string>"
],
"successMetrics": [
"<string>"
],
"campaignType": "<string>",
"budget": 123,
"budgetType": "daily",
"endDate": "<string>",
"biddingStrategy": "<string>",
"targetCpa": 123,
"targetRoas": 123,
"audiences": [
{
"id": "<string>",
"name": "<string>",
"audienceId": "<string>",
"dataStoreIds": [
"<string>"
]
}
],
"googleAds": {
"customerId": "<string>",
"accountName": "<string>",
"campaignId": "<string>",
"status": "<string>"
},
"url": "<string>",
"createdAt": "<string>",
"updatedAt": "<string>"
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "not_found",
"message": "<string>",
"requestId": "<string>"
}
}Authorizations
An API key from Settings → API access, starting with fnd_.
Headers
Any unique string. Repeating a request with the same key returns the first result instead of doing it twice.
200Path Parameters
Campaign id.
^[a-f0-9]{24}$Body
1 - 160What the campaign should achieve and for whom. Drives targeting.
4000Null removes the brand.
^[a-f0-9]{24}$120Language code. Default en.
20Country or region codes, e.g. ["US"]. Default ["US"].
208020200Google Ads campaign type.
SEARCH, DEMAND_GEN, VIDEO, DISPLAY 0 < x <= 10000000daily, total YYYY-MM-DD. Required for a total budget.
^\d{4}-\d{2}-\d{2}$Google Ads bidding strategy.
MAXIMIZE_CONVERSIONS, MAXIMIZE_CONVERSION_VALUE, TARGET_CPA, TARGET_ROAS, TARGET_CPC, TARGET_SPEND, MANUAL_CPC 0 < x <= 10000000 < x <= 1000Response
Success
draft, loading (collecting data), ready or error.
Show child attributes
Show child attributes
In the account's currency.
daily, total Show child attributes
Show child attributes
Show child attributes
Show child attributes
Opens the campaign in Fandom.

