Create ad account
Creates a new Meta ad account in the user's own business portfolio, or a Google Ads client account under a manager (MCC) account the connection reaches. Billing must then be set up on the platform.
Meta (omit platform or send meta).
Creates a durable Meta ad account in the end user's own business portfolio using their connected Meta Ads token. Requires an active metaads accountId, Ads access, business_management permission and business admin access. Discover portfolios with GET /v1/ads/businesses. System-user tokens may return an empty businesses list; supply the known business ID in that case.
The self-serve account starts without a payment method. The user must add a payment method in Ads Manager before ads can deliver. Zernio cannot add payment methods. Meta may require business verification and limits how many accounts a business can create. Closing an account does not guarantee more capacity. An ad account cannot truly be deleted, even after closing it and removing it from a business.
timezoneId is Meta's numeric ID, not an IANA timezone name. Select it from https://developers.facebook.com/docs/marketing-api/reference/ad-account/timezone-ids/. For example, 1 is America/Los_Angeles. Meta validates supported currencies and IDs. endAdvertiser, mediaAgency and partner default to NONE for the self-serve flow.
The new account is added atomically to an existing scoped ad-account allowlist. Unrestricted connections stay unrestricted. Reconnecting the same Meta identity preserves this scope unless a caller explicitly replaces it. Discovery is nudged immediately. Use the returned adAccountId with the existing ads endpoints.
This operation is not idempotent and Zernio never automatically retries it. Unknown body fields are rejected. The Meta flow has no validateOnly or dry-run option. After a timeout or a 502 with details.creationStatus=unknown, check the business in Ads Manager before attempting another creation. A 201 with connectionUpdated=false means the account exists but needs reconnecting with adAccountIds containing the returned ID and the previous scoped IDs via GET /v1/connect/facebook/ads. Do not repeat the create call.
Google (send platform: google).
Google only creates accounts through a manager account, so the new client account
is created under managerCustomerId, which must be a manager the Google user behind
the googleads accountId reaches (directly or as a sub-manager). List them with
GET /v1/ads/accounts/hierarchy. Whose manager it is (the integrator's or the end
user's) is the caller's choice: pass the connection that reaches it.
currency (ISO 4217) and timeZone (IANA name, for example Europe/Madrid) cannot be
changed after creation. The account starts without billing: set it up in Google Ads
before ads can serve. Google caps how many accounts a manager can create and how
many active client accounts it can hold.
The new customer is added to the connection (and to a scoped connection's allowlist),
discovery is nudged immediately, and the returned adAccountId works with every other
ads endpoint. validateOnly: true asks Google to validate the request without creating
anything and returns 200. A real create is not idempotent: after a 502 with
details.creationStatus=unknown, check the manager in Google Ads before trying again.
Authorization
bearerAuth API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
import Zernio from '@zernio/node';const zernio = new Zernio({ apiKey: process.env.ZERNIO_API_KEY });const { data } = await zernio.adaccounts.createAdAccount({ body: { accountId: 'account_abc123', businessId: 'business_abc123', name: 'Example', currency: 'string', timezoneId: 0, },});console.log(data);{ "platform": "google", "managerCustomerId": "string", "validateOnly": true}List ad accounts
Lists the ad accounts a connection can manage, such as Meta ad accounts, TikTok advertisers or Google Ads customers. Returns the platform ad accounts available for the given account (e.g. Meta ad accounts, TikTok advertiser IDs, Google Ads customer IDs). Meta business-login accounts use their own system-user token. Fresh Meta discovery includes businessId and businessName from the owning Business Manager when available; cached entries gain these fields after the next discovery refresh. For TikTok agencies: enumerates every advertiser under every Business Center the token can read (paginated server-side), then chunks the lookup against TikTok's `/advertiser/info/` endpoint (which has a per-call cap of ≤100 IDs). Solo advertisers without a BC fall back to the OAuth-time `advertiser_ids` list. Cached for 1h on the SocialAccount; lazy-refreshed on first call after expiry. For Google Ads: responds `429` when Google's API quota is temporarily exhausted (instead of an empty list). Retry after a delay. For Reddit Ads (`redditads`): every Reddit ad account the connected Reddit user can reach, with `businessId`, `approvalStatus` (Reddit's `admin_approval`), `timezone` and `type`. Every listed ad account carries `selected`: whether it is in the connection's ad-account selection (the ad accounts picked at connect time or in the dashboard picker, the ones Zernio syncs). On a connection without a selection every ad account is `selected: true`. Writes through /v1/ads endpoints to an ad account with `selected: false` answer `403 ad_account_not_selected`; add it to the selection first (dashboard picker, or `GET /v1/connect/{platform}/ads` with `adAccountIds`). The list includes unselected ad accounts by default; pass `inScopeOnly=true` to get only the ones this connection can use.
Update ad account settings
Changes a Meta ad account's name, spend cap or default EU DSA beneficiary and payor. Pass any combination of fields. **Spend cap.** `spendCap` is the total the account may spend before Meta pauses every campaign in it, in whole units of the account currency. `spendCap: null` removes the cap and `resetAmountSpent: true` restarts the amount counted against it from zero. When `name`, `spendCap` or `resetAmountSpent` is passed, the response carries `settings`, the account's finances re-read after the write (same shape as `GET /v1/ads/accounts/finance`), so the effective cap can be confirmed in one call. **DSA defaults.** Sets the default DSA beneficiary and payor on the ad account (EU DSA, Article 26). Set them once and every EU-targeted call to `/v1/ads/create`, `/v1/ads/boost` and `/v1/ads/ctwa` on that ad account can omit `dsaBeneficiary`/`dsaPayor`: Meta applies the defaults automatically. The values are written to the ad account on Meta, the same setting Ads Manager edits. Nothing is stored in Zernio, and defaults already set in Ads Manager work identically. Zernio never guesses these values for you. Beneficiary and payor are legal disclosures shown to EU users, so you must provide the entity names explicitly. Use `GET /v1/ads/dsa-recommendations` to offer suggestions in your UI. If `defaultDsaPayor` is omitted, the beneficiary is also set as the payor, which covers the common case where the same entity benefits from and pays for the ads. Read the current values back with `GET /v1/ads/dsa-defaults`. **Google: account-level URL tracking.** On a Google Ads connection, `adAccountId` is the customer id and only `trackingUrlTemplate` / `finalUrlSuffix` are accepted (the Meta fields return 400). They write `customer.tracking_url_template` and `customer.final_url_suffix`, one update mask leaf per field sent; an empty string clears the field. The response carries `urlTracking` with the values written. For one campaign, send the same fields to PUT /v1/ads/campaigns/{campaignId}. Other platforms return 400.