Publishing and performance
Connect Meta, TikTok and Google Ads accounts or use the sandbox, build and publish campaigns in five steps, and track spend, CTR, CPA and ROAS per creative.
4 min readUpdated Oct 17, 2026Applies to Adcraft 1.0.0
On this page
Adcraft can create campaigns on Meta (Facebook and Instagram), TikTok and Google Ads from finished ads, then read the results back and point you at the next round.
Sandbox or live
Each platform runs in one of two modes:
| Sandbox (default) | Live | |
|---|---|---|
| Switched on by | Nothing: it is used whenever the platform's keys are missing | Your own developer app's keys in the environment |
| Connecting an account | Skips the platform's sign-in and adds a simulated account | The platform's OAuth sign-in; you pick the ad accounts to use |
| Publishing | Simulated inside Adcraft; nothing reaches the platform | Creates real campaigns, ad sets (ad groups) and ads |
| Metrics | Generated for demonstration, including some disapprovals and fatigue | Pulled from the platform's reporting API |
Pages that only show sandbox data say so. Sandbox accounts stay sandboxes even after you add keys.
Live platform setup
| Platform | Environment variables | API version |
|---|---|---|
| Meta | META_APP_ID, META_APP_SECRET; optional META_PAGE_ID |
Marketing API v21.0 |
| TikTok | TIKTOK_APP_ID, TIKTOK_APP_SECRET |
Marketing API v1.3 |
| Google Ads | GOOGLE_ADS_CLIENT_ID, GOOGLE_ADS_CLIENT_SECRET, GOOGLE_ADS_DEVELOPER_TOKEN; optional GOOGLE_ADS_LOGIN_CUSTOMER_ID |
Google Ads API v25 |
Set each app's OAuth redirect URI to:
https://<your-domain>/api/connect/meta/callback
https://<your-domain>/api/connect/tiktok/callback
https://<your-domain>/api/connect/google/callbackThe address comes from AUTH_URL. Access tokens are stored encrypted (AES-256-GCM, with TOKEN_ENCRYPTION_KEY or a key derived from AUTH_SECRET) and refreshed before they expire.
Important
Meta, TikTok and Google each review an app before it can manage other people's ad accounts. Until your app is approved it works only with accounts you control in the platform's developer or test setup. Plan for days to weeks, and apply early. Ad spend is always billed by the platform to the advertiser's own account.
Build a campaign
Owners and editors connect ad accounts under Campaigns and start a campaign with the five-step builder:
- Account and objective: the ad account, campaign name and landing page. For Meta, a Facebook Page (picked from your Pages, or
META_PAGE_ID) and optionally a pixel; for TikTok, optionally a pixel. - Audience: countries (the United States by default), age range, genders and interests.
- Placements and budget: placements, a daily budget (25 by default, in the account's currency) and the schedule.
- Creatives: finished ads whose sizes fit the chosen placements.
- Review and publish: every check below, then Publish as paused (the first choice) or Publish active.
Publishing runs in the background and is safe to retry: a campaign is never published twice, and every platform ID is stored. From the campaign page you can edit the campaign, pause or resume campaigns and ads, retry a failed publish, and sync results.
Checks before publishing
Each ad and size is checked against the placement's rules before it can be added:
- media type, aspect ratio, file size and video length;
- headline, primary text and description length;
- a full
https://landing page; - an AI-disclosure reminder for Meta and TikTok.
A claims review reads the copy for risky wording. Medical cure claims, guaranteed financial returns and wording about a person's attributes block publishing. "Clinically proven", weight-loss and income claims, absolute guarantees, superlatives, false urgency and profanity give warnings. A brief's constraints can turn a warning category into a blocking one.
Two workspace guardrails also apply:
- Spend approval threshold (100 by default): above this daily budget, only owners can publish or resume a campaign as active, or raise its budget.
- Approval before publishing (off by default, under Settings → Guardrails): only approved ads can be added to a campaign.
Platform notes
| Platform | Notes in 1.0.0 |
|---|---|
| Meta | Image and video ads. A Facebook Page is required. Objectives that need a pixel fall back to link clicks without one. Meta's automatic creative enhancements are switched off. |
| TikTok | Video ads. Ad group daily budgets are raised to at least 20, TikTok's minimum. Conversion value is not read back yet, so ROAS is not reported for TikTok. |
| Google Ads | Demand Gen campaigns with image ads only. Video ads need to be hosted on YouTube, which is not supported, so video creatives are refused. A square logo from the brand kit is required. Interests are not applied to targeting. |
The AI-content labels that platforms offer are not set automatically. Add any disclosure your market or platform requires to the ad copy.
Performance
Performance shows results for the current brand over 7, 14 or 30 days, compared with the previous period:
- spend, impressions, CTR, CPA and ROAS, with daily charts;
- a row per creative with its own spend, CTR, CPA, ROAS and CTR trend;
- creative fatigue alerts when a creative's CTR over the last five days has fallen by 25% or more against the five days before (each window needs at least 1,000 impressions);
- disapproved ads with the platform's reason;
- Export CSV: one row per ad per day, up to 90 days.
From any creative, Refresh opens a new brief pre-filled from it, and Pause stops it on the platform.
When results update
| With Inngest | Without Inngest | |
|---|---|---|
| Automatic sync | Every hour | None |
| Manual sync | Sync now on the performance or campaign page | Same |
The first sync reads the last 7 days; later syncs re-read the last two days to catch late conversions.
Not in this version
- Fatigue alerts need 10 days of data, so they appear in the 14 and 30-day views, not in the 7-day view or on the dashboard.
- Without Inngest there is no hourly sync, although the page mentions "the hourly job". Use Sync now.
- Google Ads budget edits after publishing may not reach Google. Change the budget in Google Ads as well.
- Admin → Campaigns is read-only; changes are made in the customer's workspace.