GET /v1/projects/:projectId/ads/campaigns
List ad campaigns across Meta, TikTok, and Apple. Read-only today — campaign CRUD is planned.
GET
/v1/projects/{projectId}/ads/campaignsPhase 1stable
- Auth
- Bearer
- Scope
- ads:read
Lists every ad campaign across the project's connected ad accounts, on every supported platform. Result includes the platform-native id, current status, objective, budget, and spend window. The metricsSnapshot7d field is reserved (always {} in Phase 1) — call GET /v1/projects/:projectId/ads-metrics for paid performance.
Ads endpoints are currently read-only, plus CAPI config and ads-content overrides. Creating, updating, pausing, or deleting campaigns, ad sets, and ads is planned. For now, mutate in the platform's own ad manager — the next call to this endpoint picks up the changes.
Path
projectIdstring (UUID)requiredProject to list within.
Query
platformsstring[]optionalRestrict to one or more platforms.One of:meta_ads,tiktok_ads,apple_adsadAccountIdstring (UUID)optionalRestrict to campaigns on one ad account.statusstring[]optionalFilter by platform-native status.One of:active,paused,archived,deleted,in_review,rejectedsincestring (ISO-8601)optionalReturn campaigns created on or after this time.cursorstringoptionalOpaque pagination cursor. Forged or malformed cursors are rejected and treated as no cursor (first page).limitnumberoptionaldefault: 100Page size, 1–200.
Example request
curl "https://api.layers.com/v1/projects/prj_01HX9Y7K8M2P4RSTUV56789AB/ads/campaigns?platforms=meta_ads&status=active&limit=25" \
-H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..."const res = await fetch(
`https://api.layers.com/v1/projects/${projectId}/ads/campaigns?platforms=meta_ads&status=active&limit=25`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
const { items, nextCursor } = await res.json();import httpx
r = httpx.get(
f"https://api.layers.com/v1/projects/{project_id}/ads/campaigns",
params={"platforms": "meta_ads", "status": "active", "limit": 25},
headers={"Authorization": f"Bearer {api_key}"},
)Response
200OK
{
"items": [
{
"campaignId": "cmp_01HXG9...",
"adAccountId": "aa_01HXF1...",
"platform": "meta_ads",
"externalId": "23852014...",
"name": "Q2 Mobile Ordering — Prospecting",
"objective": "conversions",
"status": "active",
"dailyBudget": { "amount": 150.00, "currency": "USD" },
"lifetimeBudget": null,
"startTime": "2026-04-01T00:00:00Z",
"endTime": null,
"createdAt": "2026-03-29T15:04:00Z",
"metricsSnapshot7d": {}
},
{
"campaignId": "cmp_01HXGB...",
"adAccountId": "aa_01HXF2...",
"platform": "tiktok_ads",
"externalId": "1785502...",
"name": "Q2 Mobile Ordering — TT Retargeting",
"objective": "conversions",
"status": "paused",
"dailyBudget": null,
"lifetimeBudget": { "amount": 3000.00, "currency": "USD" },
"startTime": "2026-04-10T00:00:00Z",
"endTime": "2026-05-10T00:00:00Z",
"createdAt": "2026-04-08T21:18:00Z",
"metricsSnapshot7d": {}
}
],
"nextCursor": null
}Notes
statusis the platform-native value. Mapping varies subtly between Meta, TikTok, and Apple — do not assumeactivemeans the same thing everywhere. When the distinction matters (for instancein_reviewon Meta pre-launch), use the platform's own ad manager as the source of truth.metricsSnapshot7dis reserved for a future inline rollup. It is always{}today; callGET /v1/projects/:projectId/ads-metricswithscope=campaignand an explicit window for paid performance.- Soft-deleted campaigns (
status: "deleted"on Meta, "archived" on TikTok) are included by default. Filter them out withstatusif you only want live work.
See also
GET /v1/projects/:projectId/ads/adsets— one level deeperGET /v1/projects/:projectId/ads-metrics— paid performance at any scopeGET /v1/projects/:projectId/ads/ad-accounts— which accounts are connected