Account & Ops Reads
Change log, A/B studies, account finances, labels, budget schedules, and Business portfolios
Account & Ops Reads
The operational reads an Ads Manager replacement needs around the campaign tree itself: who changed what, what's being tested, how much money is left, and how the account is organized. All Meta-only, all raw passthrough, so Meta's own 400s surface verbatim.
| Endpoint | Returns |
|---|---|
GET /v1/ads/activity | The ad account's change history |
GET /v1/ads/studies | A/B tests and lift studies |
GET /v1/ads/accounts/finance | Balance, spend, spend cap, funding source |
GET /v1/ads/labels | Ad labels |
GET /v1/ads/high-demand-periods | Scheduled budget increases |
GET /v1/ads/businesses | The Business Manager portfolios the connection belongs to |
Two related reads live on their own pages: ad set details + learning phase and pixel firing stats.
Change / audit log
GET /v1/ads/activity returns who changed what and when on the ad account, with Meta's translated_event_type and the structured before/after values in extra_data.
const { data } = await zernio.adaccounts.getAdsActivityLog({
query: {
accountId: 'ACCOUNT_ID',
adAccountId: 'act_1234567890',
since: '2026-07-01',
until: '2026-07-20',
},
});data = client.ad_accounts.get_ads_activity_log(
account_id="ACCOUNT_ID",
ad_account_id="act_1234567890",
since="2026-07-01",
until="2026-07-20",
)curl "https://zernio.com/api/v1/ads/activity?accountId=ACCOUNT_ID&adAccountId=act_1234567890&since=2026-07-01&until=2026-07-20" \
-H "Authorization: Bearer YOUR_API_KEY"objectId filters client-side. Meta's activities edge has no server-side per-object filter, so passing objectId filters the returned page only. To walk one object's full history, combine objectId with paging.after and keep paging.
A/B tests & lift studies
GET /v1/ads/studies returns the account's /ad_studies rows verbatim. The default projection covers id, name, type, timing, and the cells with their split percentages; fields overrides it.
const { data } = await zernio.adaccounts.listAdStudies({
query: { accountId: 'ACCOUNT_ID', adAccountId: 'act_1234567890' },
});data = client.ad_accounts.list_ad_studies(
account_id="ACCOUNT_ID",
ad_account_id="act_1234567890",
)curl "https://zernio.com/api/v1/ads/studies?accountId=ACCOUNT_ID&adAccountId=act_1234567890" \
-H "Authorization: Bearer YOUR_API_KEY"Account finances
GET /v1/ads/accounts/finance returns { currency, balance, amountSpent, spendCap, fundingSource } in whole currency units. spendCap: null means no cap is set.
const { data } = await zernio.adaccounts.getAdAccountFinance({
query: { accountId: 'ACCOUNT_ID', adAccountId: 'act_1234567890' },
});
// { currency: 'USD', balance: 214.5, amountSpent: 7823.11, spendCap: null, fundingSource: '...' }data = client.ad_accounts.get_ad_account_finance(
account_id="ACCOUNT_ID",
ad_account_id="act_1234567890",
)curl "https://zernio.com/api/v1/ads/accounts/finance?accountId=ACCOUNT_ID&adAccountId=act_1234567890" \
-H "Authorization: Bearer YOUR_API_KEY"This is the account-level spend cap (a billing guardrail). The campaign-level spend cap is a delivery setting, editable via platformSpecificData.spendCap.
Ad labels
GET /v1/ads/labels returns the account's /adlabels rows (id, name, timestamps). Labels are how Ads Manager users group campaigns, ad sets, ads and creatives across the tree; reading them lets you mirror those groupings in your own UI.
High demand periods
GET /v1/ads/high-demand-periods returns scheduled budget increases (Meta's budget scheduling feature, e.g. "raise the budget 50% over Black Friday weekend"), rows verbatim.
Pass exactly one of campaignId or adSetId. The Graph edge only exists on campaign and ad-set nodes; asking at the account level is a Meta #100 error, which is why the account-wide shape isn't offered.
const { data } = await zernio.adaccounts.listHighDemandPeriods({
query: { accountId: 'ACCOUNT_ID', campaignId: '120250000000000000' },
});data = client.ad_accounts.list_high_demand_periods(
account_id="ACCOUNT_ID",
campaign_id="120250000000000000",
)curl "https://zernio.com/api/v1/ads/high-demand-periods?accountId=ACCOUNT_ID&campaignId=120250000000000000" \
-H "Authorization: Bearer YOUR_API_KEY"Creating scheduled budget increases isn't exposed yet; reads only.
Business portfolios
GET /v1/ads/businesses lists the Business Manager portfolios the connected Meta user belongs to (Meta's /me/businesses): id, name, verification status, created time, with limit / after paging.
const { data } = await zernio.adaccounts.listMetaBusinesses({
query: { accountId: 'ACCOUNT_ID' },
});data = client.ad_accounts.list_meta_businesses(account_id="ACCOUNT_ID")curl "https://zernio.com/api/v1/ads/businesses?accountId=ACCOUNT_ID" \
-H "Authorization: Bearer YOUR_API_KEY"Token-scoped, so no adAccountId, and it works with plain ads_management (no business_management scope needed). This is Meta-only: the similarly named /v1/ads/business-centers is the TikTok equivalent.