GET /v1/projects/:projectId/ads/adsets
List ad sets (ad groups on TikTok) across Meta, TikTok, and Apple. Read-only.
GET
/v1/projects/{projectId}/ads/adsetsPhase 1stable
- Auth
- Bearer
- Scope
- ads:read
Lists every ad set under the project's connected ad accounts, across platforms. TikTok and Apple call these "ad groups"; Layers normalizes them to "adsets" so you can render one shape without per-platform branches. Each item carries its parent campaign, current status, optimization goal, targeting summary, and budget.
Adset writes (PATCH …/adsets/:id/budget, …/adsets/:id/targeting, …/adsets/:id/schedule, plus …/{pause,resume}, DELETE) are partner-callable with ads:write:budgets / :lifecycle / :creative. All writes route through the bucket-mode authority gate.
Path
projectIdstring (UUID)requiredProject to list within.
Query
campaignIdstring (UUID)optionalRestrict to ad sets on one campaign.platformsstring[]optionalRestrict to one or more platforms.One of:meta_ads,tiktok_ads,apple_adsadAccountIdstring (UUID)optionalRestrict to ad sets on one ad account.statusstring[]optionalFilter by platform-native status.One of:active,paused,archived,deleted,in_review,rejectedcursorstringoptionalOpaque 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_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39/ads/adsets?campaignId=cmp_01HXG9&status=active" \
-H "Authorization: Bearer lp_..."const res = await fetch(
`https://api.layers.com/v1/projects/${projectId}/ads/adsets?campaignId=${campaignId}&status=active`,
{ 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/adsets",
params={"campaignId": campaign_id, "status": "active"},
headers={"Authorization": f"Bearer {api_key}"},
)
items = r.json()["items"]Response
200OK
{
"items": [
{
"adsetId": "adg_01HXG9...",
"campaignId": "cmp_01HXG9...",
"adAccountId": "aa_01HXF1...",
"platform": "meta_ads",
"externalId": "23852014...",
"name": "Q2 Mobile Ordering - Prospecting - Lookalike 1%",
"status": "active",
"optimizationGoal": "offsite_conversions",
"billingEvent": "impressions",
"dailyBudget": { "amount": 75.00, "currency": "USD" },
"lifetimeBudget": null,
"startTime": "2026-04-01T00:00:00Z",
"endTime": null,
"targetingSummary": {
"geo": ["US"],
"age": { "min": 25, "max": 45 },
"customAudiences": ["aud_lookalike_1pct_purchasers"],
"placements": ["facebook_feed", "instagram_feed", "instagram_reels"]
},
"createdAt": "2026-03-29T15:04:00Z",
"metricsSnapshot7d": {}
},
{
"adsetId": "adg_01HXGB...",
"campaignId": "cmp_01HXGB...",
"adAccountId": "aa_01HXF2...",
"platform": "tiktok_ads",
"externalId": "1785502...",
"name": "Q2 Retargeting - 30d Site Visitors",
"status": "paused",
"optimizationGoal": "conversion",
"billingEvent": "oCPM",
"dailyBudget": null,
"lifetimeBudget": { "amount": 1500.00, "currency": "USD" },
"startTime": "2026-04-10T00:00:00Z",
"endTime": "2026-05-10T00:00:00Z",
"targetingSummary": {
"geo": ["US"],
"age": { "min": 18, "max": 54 },
"customAudiences": ["aud_site_visitors_30d"],
"placements": ["tiktok_feed"]
},
"createdAt": "2026-04-08T21:18:00Z",
"metricsSnapshot7d": {}
}
],
"nextCursor": null
}Notes
optimizationGoalandbillingEventare platform-native strings. Meta and TikTok use different vocabularies; do not assumeconversionon TikTok means the same thing asoffsite_conversionson Meta.targetingSummaryis a summary, not the full targeting spec. Platforms encode targeting in very different JSON shapes; Layers surfaces the pieces almost every agent cares about (geo, age, custom audiences, placements) and skips the rest. For the raw spec, fall through to the platform's own API.metricsSnapshot7dis reserved for a future inline rollup. It is always{}today; callGET /v1/projects/:projectId/ads-metricswithscope=adsetand an explicit window for paid performance.endTimeofnullmeans the ad set runs indefinitely (on platforms that allow it). TikTok lifetime-budget adsets always have anendTime.- Soft-deleted ad sets are included by default. Filter them out with
statusif you only want live work.
See also
GET /v1/projects/:projectId/ads/campaigns- parent campaignsGET /v1/projects/:projectId/ads/ads- ads one level deeperGET /v1/projects/:projectId/ads-metrics- paid performance at any scope