Cofounder CLI
Ads
Run paid ads: connect or set up an ad account, research keywords, draft and fund campaigns, launch them, and track spend and results.
There are two ways to advertise. Connect an ad account the company already has (Google, Meta, LinkedIn, TikTok, and others), or use the managed Meta ad account that company setup creates, which you fund from the company balance. Setup, drafting, and anything that spends money need a company admin; any member can read accounts, campaigns, and results.
What spends money or needs the founder:
- Spends money:
ads billing fund,ads campaigns launch,ads campaigns resume, andads billing payment retry. - Needs the founder: signing in to connect an account, and answering business verification requests.
When the company has more than one ad account, choose one with --resource
(its name or id), or with --key or --resource-id on commands that take
those. cofounder ads accounts list shows each account's key and id.
Get an ad account
| MCP | CLI | API |
|---|---|---|
ads_accounts_connect | cofounder ads accounts connect --platform <platform> | POST /cofounder-cli/v1/company/ads/accounts/connect |
ads_accounts_provision | cofounder ads accounts provision --platform metaads | POST /cofounder-cli/v1/company/ads/accounts/provision |
ads_agreement_sign | cofounder ads agreement sign | POST /cofounder-cli/v1/company/ads/agreement/sign |
ads_verifications_list | cofounder ads verifications list | GET /cofounder-cli/v1/company/ads/verifications |
ads_accounts_list | cofounder ads accounts list | GET /cofounder-cli/v1/company/ads/accounts |
ads_accounts_get | cofounder ads accounts get --resource <account> | GET /cofounder-cli/v1/company/ads/accounts/get |
connect works with googleads, linkedinads, metaads, openaiads,
pinterestads, tiktokads, and xads. If the platform needs the founder to
sign in, it returns a link and opens the browser (--no-browser only prints
it).
Managed setup already gives the company a managed Meta ads account that Cofounder runs for it. Setup:
- creates the company's managed ad account, which then shows in
ads accounts list; - sets the account's ad spend to come from the allowance you fund with
ads billing fund; - signs the managed ads agreement, in your verified name (or the company's name when an agent runs setup with a company API key);
- creates the Facebook page the ads run from, generating a logo and banner
if the company has none (replace them with
ads page branding update).
It doesn't add the Meta pixel to your site or put any money in. Run
provision yourself only if the account is missing from ads accounts list
— for example if setup skipped that step or couldn't finish it. It does the
same thing, costs nothing, and returns the existing account if there is one.
Its response lists anything still missing, such as the agreement or the page,
and what to run next; agreement sign retries the agreement on its own. verifications list shows business details Meta still needs,
and accounts get shows whether an account is ready to run ads.
Upload images
| MCP | CLI | API |
|---|---|---|
ads_assets_create | cofounder ads assets create <file> | POST /cofounder-cli/v1/company/ads/assets |
ads_assets_get | cofounder ads assets get --file-id <id> | GET /cofounder-cli/v1/company/ads/assets/{file_id} |
upload sends a PNG, JPEG, or WebP image (up to 10 MB) to the managed Meta
account and returns a file_id to use as ad creative or as the page's logo or
banner. Over MCP or the API, ads_assets_create returns an upload address;
send the image there, then check assets get until it is ready.
Set up the page and pixel
Managed Meta ads run from a Facebook page and must send people to a site with the Meta pixel, so results can be tracked.
| MCP | CLI | API |
|---|---|---|
ads_page_ensure | cofounder ads page ensure --input <json> | POST /cofounder-cli/v1/company/ads/page |
ads_page_get | cofounder ads page get | GET /cofounder-cli/v1/company/ads/page |
ads_page_branding_update | cofounder ads page branding update --input <json> | PATCH /cofounder-cli/v1/company/ads/page/branding |
ads_pixel_get | cofounder ads pixel check --input '{"url":"https://acme.com"}' | POST /cofounder-cli/v1/company/ads/pixel-check |
Provisioning already creates the page; page ensure creates it if it's
missing. Both page ensure and page branding update take an optional
description (up to 155 characters) and logo_file_id / banner_file_id
from your uploads.
pixel check confirms a landing page has the pixel. Launch refuses any ad
whose landing page can't be tracked.
Research keywords
With a connected Google Ads account, look up search terms before you write ads:
| MCP | CLI | API |
|---|---|---|
ads_keywords_ideas_list | cofounder ads keywords ideas list --seed-keyword <word> --seed-url <url> | POST /cofounder-cli/v1/company/ads/keywords/ideas |
ads_keywords_historical_metrics_get | cofounder ads keywords historical-metrics get --keyword <word> | POST /cofounder-cli/v1/company/ads/keywords/historical-metrics |
ideas list suggests keywords from seed words, a web page, or both.
historical-metrics get returns search volume and competition for up to
1,000 exact keywords. Bid and cost-per-click figures come straight from
Google in millionths of the account currency (1,000,000 is one dollar on a
USD account).
Draft a campaign
Drafts on the managed Meta account don't run or spend anything.
| MCP | CLI | API |
|---|---|---|
ads_drafts_create | cofounder ads drafts create --input <json> | POST /cofounder-cli/v1/company/ads/drafts |
ads_drafts_get | cofounder ads drafts get --caller-key <key> | GET /cofounder-cli/v1/company/ads/drafts/create_status |
ads_drafts_campaign_update | cofounder ads drafts campaign update --campaign-id <id> --input <json> | PATCH /cofounder-cli/v1/company/ads/drafts/{campaign_id}/campaign |
ads_drafts_ad_group_update | cofounder ads drafts ad-group update --campaign-id <id> --input <json> | PATCH /cofounder-cli/v1/company/ads/drafts/{campaign_id}/ad-group |
ads_drafts_ad_update | cofounder ads drafts ad update --campaign-id <id> --input <json> | PATCH /cofounder-cli/v1/company/ads/drafts/{campaign_id}/ad |
The drafts create input holds a spec — campaign, ad group, and ad titles,
countries, start and end times, a lifetime budget in USD, the uploaded
creative_file_id, a landing URL, headline, and primary text — plus an
idempotency_key you choose. If the call times out,
drafts get --caller-key <key> tells you whether the draft was made; send
the same request with the same key to finish it rather than starting over.
The update commands change the campaign title; the ad group's countries,
dates, and budget (at least $5 per scheduled day); or the ad's image, text,
landing URL, and button. Landing URLs can't set utm_source, utm_medium,
or the other parameters reserved for click tracking.
On a connected Meta account, cofounder ads campaigns create --input <json>
creates the campaign, ad set, and ad in one step. It starts paused and spends
nothing until you run ads campaigns resume.
Fund and cap spending
Managed campaigns spend from an allowance you buy ahead of time.
| MCP | CLI | API |
|---|---|---|
ads_billing_fund | cofounder ads billing fund --input '{"amount_cents":5000}' | POST /cofounder-cli/v1/company/ads/billing/fund |
ads_billing_allowance_get | cofounder ads billing allowance get | GET /cofounder-cli/v1/company/ads/billing/allowance |
ads_billing_get | cofounder ads billing get | GET /cofounder-cli/v1/company/ads/billing |
ads_spend_ceiling_set | cofounder ads spend-ceiling set --daily-ceiling-usd 50 | PUT /cofounder-cli/v1/company/ads/spend-ceiling |
ads_spend_get | cofounder ads spend get | GET /cofounder-cli/v1/company/ads/spend |
billing fund charges the company balance: amount_cents of ad
allowance plus a 10% fee. allowance get shows how much is funded and used;
billing get shows the account's payment settings.
spend-ceiling set adds a company-wide daily limit across every ad account,
checked whenever a campaign launches or resumes. Each campaign's own budget
still applies, and platforms pace delivery, so one day's actual charges can
differ from the limit. spend get shows today's committed spend, the limit,
and the campaigns behind the total.
Launch
| MCP | CLI | API |
|---|---|---|
ads_campaigns_launch_status_get | cofounder ads campaigns launch-status get --campaign-id <id> | GET /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/launch-check |
ads_campaigns_launch | cofounder ads campaigns launch --campaign-id <id> | POST /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/launch |
Run launch-status get first: it runs the same checks as launch without
starting anything. Its missing list names what's left (for example
payment_method or pixel) and next_action says what to do. launch
starts spending, within the campaign budget, your funded allowance, and
any daily limit. It applies to managed Meta drafts; campaigns on connected
accounts start with resume.
To retry billing fund, campaigns launch, or billing payment retry
safely after an unclear result, pass your own --idempotency-key the first
time and reuse it on the retry. Without it, each run counts as a new
request and can charge twice.
Manage campaigns
| MCP | CLI | API |
|---|---|---|
ads_campaigns_list | cofounder ads campaigns list --key <account-key> --status active | GET /cofounder-cli/v1/company/ads/campaigns |
ads_campaigns_get | cofounder ads campaigns get --campaign-id <id> | GET /cofounder-cli/v1/company/ads/campaigns/{campaign_id} |
ads_campaigns_managed_get | cofounder ads campaigns managed get --campaign-id <id> | GET /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/managed |
ads_campaigns_pause | cofounder ads campaigns pause --campaign-id <id> | POST /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/pause |
ads_campaigns_resume | cofounder ads campaigns resume --campaign-id <id> | POST /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/resume |
ads_campaigns_budget_set | cofounder ads campaigns budget set --campaign-id <id> --amount 20 --budget-type daily | PUT /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/budget |
campaigns list returns one page; pass page.next_cursor as --cursor for
the next. managed get returns every detail of a managed Meta campaign.
Pausing always works. Resuming checks the daily limit again and, on managed
accounts, everything launch checks. budget set works only on connected
accounts: Google allows only daily budgets, and Meta campaigns that set
budgets per ad set reject a campaign-level change.
Results and failed payments
| MCP | CLI | API |
|---|---|---|
ads_campaigns_performance_get | cofounder ads campaigns performance get --campaign-id <id> --key <account-key> --from-date 2026-09-01 --to-date 2026-09-28 | GET /cofounder-cli/v1/company/ads/campaigns/{campaign_id}/performance |
ads_billing_payment_retry | cofounder ads billing payment retry | POST /cofounder-cli/v1/company/ads/billing/retry-payment |
Performance covers both dates, inclusive, and shows only the numbers the
platform reports; add --ad-id for one ad on a connected account. If a
managed account's payment fails, payment retry queues one retry. It is
pending until the payment goes through, so check ads campaigns get to
confirm the campaign is delivering again.