- Every campaign is created paused in the merchant’s own ad account, which bills it. The merchant switches it on in Meta Ads Manager or Google Ads. Fluid never switches a campaign on and never handles ad spend.
- Fluid checks the copy before it sends anything. A line that makes a claim the platforms reject, such as a health claim or a guaranteed result, blocks the whole launch.
- Fluid doesn’t mirror campaigns. It keeps a record of each launch and reads status and results live from Meta or Google when you ask.
Authorization: Bearer <token>) for a company admin. Connecting, choosing an account and launching need the Company settings permission; generating images needs Media. Droplet installation tokens are refused.
1. Connect Meta and Google
One login per platform covers both commerce and ads:- Meta: Start the Meta business-login connect flow returns a sign-in
url. The person who opens it logs in to Facebook and shares the business, catalog, ad account, Page and Instagram account. The business must own at least one product catalog. Connect Meta walks the same flow with the Fluid CLI:fluid channels connect meta --open. - Google: Start the Google Merchant Center connect flow returns a sign-in
url. The same Google sign-in grants Merchant Center and Google Ads access, and it needs a Merchant Center account. Connect Google Merchant Center walks it withfluid channels connect google --open.
url for them, wait for them to say they’re done, then read the connection once: Get the company’s Meta commerce connection or Get the company’s Google Merchant Center connection. A test store can’t connect.
2. Choose the ad account
Fluid launches only into the ad account the company chose. Read the choices live from the platform, then save one of them:
On Meta, the choice is an ad account, the Facebook Page the ads run as and, optionally, the Instagram account linked to that Page. On Google, it’s one Google Ads account that is enabled and isn’t a manager account.
Save only ids that the list returned. Fluid checks each id with the platform again before it saves, so an id typed in by hand or taken from another company fails. When an agent chooses for a merchant, show the merchant the list and let them pick.
3. Get images (Meta only)
Each Meta ad needs an httpsimage_url. Use the product’s own images where one fits the placement. When none does, generate one:
- Generate ad images at an aspect ratio with a
prompt, anaspect_ratioof1:1,4:5,9:16or1.91:1, and, to base the images on a product, itsproduct_id. It returns202with a generation id. - Read an ad image generation until its status is
completedorfailed. Each completed image is saved to the company’s media library, and itsurlis ready to use as animage_url.
4. Launch
Send the approved copy to Launch a paused Meta campaign or Launch a paused Google Search campaign. Both return201 with the launch record and the platform’s ids.
- Meta creates a Traffic campaign, one ad set and one to five link ads, all paused.
- Google creates a budget, a Search campaign, one ad group and one responsive search ad, with the campaign paused. Google applies it all at once, so a refused launch creates nothing.
daily_budget is in the ad account’s minor currency units, such as cents for USD. Fluid adds UTM tags to the link_url, and the utm_campaign names the campaign in Fluid’s own reports.
Retry safely with idempotency_key. Send a key that identifies the approved ads, such as a hash of them. If a request times out and you send it again with the same key, you get the first launch back instead of a second campaign. If that first launch hasn’t finished, you get 409 with launch_in_progress: check the ad account for the campaign before you launch again with a new key.
Never tell a merchant an ad is live after a launch. It’s paused until they switch it on, and the platform may still review it.
5. Read results
List the company’s ads launches and List the company’s Google ads launches return the launch records, newest first. For one launch’s results, call Read a Meta launch’s campaign results or Read a Google launch’s campaign results. Fluid reads them live from the platform: the campaign’s current status, spend, impressions, clicks, click-through rate and cost per click, for the days fromsince to until. Without dates, the range runs from the launch date to today.
Errors
Failures put a machine-readable type inerror.details.type. Branch on the type, not on the message.
When the platform refuses a launch, the response is
502 and error.details.launch_id names the failed launch record. On Meta, any campaign parts created before the failure stay in the ad account, all paused.