OwnMyAds

Developer docs

Everything you need to build on OwnMyAds without putting an ad account at risk. OwnMyAds is a client for the official Meta Marketing API, so anything you build talks to Meta the same way the app does.

How it works

Your deviceApp, CLI or MCP
→
Meta Marketing APIgraph.facebook.com v23.0

Ad data never passes through OwnMyAds servers. The app, the CLI and the MCP server call graph.facebook.com directly from your device with your business key. Our server only handles your login, billing, the optional encrypted key sync and the AI agent, which receives the rows you send it and returns a plan.

Business key

A business key is a Meta system user access token. It belongs to your Business portfolio instead of a personal profile, so a restricted or banned profile can’t lock you out.

  1. Business Settings → Users → System users → Add. Pick Employee, not Admin, unless you need to manage the business itself.
  2. Assign assets: only the ad accounts (and Pages, pixels) the key should touch. Give Manage for ad accounts you want to edit, View for read only.
  3. Click Generate token, set expiration to Never and tick every permission in the list (ads_management, ads_read, business_management, catalog_management, pages_manage_ads, pages_read_engagement, pages_show_list and the rest). That gives OwnMyAds everything Ads Manager can do.

Building your own read only integration? Make a separate key with only ads_read and View access.

Open System users ↗Ad account access ↗

CLI

npm i -g https://ownmyads.app/cli.tgz

Zero dependencies, Node 18+. ownmyads login saves your key to ~/.ownmyads/config.json on your computer only. In CI, skip the file and set an environment variable.

OWNMYADS_TOKENBusiness key. Takes priority over the saved one. META_TOKEN also works.
ownmyads campaigns --range last_7dAlso adsets, ads. Ranges: today, yesterday, last_7d, last_14d, last_30d, this_month, last_month, maximum
ownmyads off|on <id>on asks before it spends
ownmyads budget <id> 120Daily or lifetime, whichever the object uses
ownmyads dup <id>The copy starts off
ownmyads ask "…"AI agent plan, you confirm each run. Needs ownmyads signin and an active plan

Animated walkthrough

MCP server

claude mcp add ownmyads -- ownmyads mcp

Stdio JSON-RPC, works in Claude Code, Cursor and any MCP client. Config for clients that use JSON:

{ "mcpServers": { "ownmyads": { "command": "ownmyads", "args": ["mcp"], "env": { "OWNMYADS_TOKEN": "…" } } } }
ToolDoesRisk
list_ad_accountsAd accounts the key can reachRead
list_campaignsCampaigns, ad sets or ads with spend, purchases, ROAS, CPA. Args: level, account, rangeRead
set_statusACTIVE or PAUSED. Turning on spends moneySpends
set_budgetBudget in account currency, major unitsSpends
duplicateCopy starts pausedWrite
renameRename an objectWrite

Keep your MCP client’s approval prompt on for the tools marked Spends. The server tells the model to ask before turning anything on or raising budgets, but your client is the real gate.

Agent API

The same planner the app uses. It never touches Meta: you send rows, it returns a reply and a list of actions, and you apply them yourself.

POST https://ownmyads.app/api/ai
Cookie: session from /api/login   (or use ownmyads ask)

{ "instruction": "Pause every ad under 1.5 ROAS",
  "level": "ad", "currency": "USD",
  "rows": [{ "id": "1202…", "level": "ad", "name": "Static v2", "status": "ACTIVE",
             "spend": 61.2, "purchases": 0, "roas": 0, "cpa": null }] }

→ { "reply": "1 ad matches…",
    "actions": [{ "type": "pause", "id": "1202…", "reason": "ROAS 0.00" }] }

Action types: pause, activate, set_budget, scale_budget (percent), rename, duplicate. Matching runs as code on our side, so counts and thresholds are exact. Requests must come from ownmyads.app or a non-browser client; browsers on other origins are refused.

Graph API directly

Anything the app does is a plain Marketing API call. Pause an ad:

curl -X POST "https://graph.facebook.com/v23.0/<AD_ID>" \
  -d status=PAUSED -d access_token="$OWNMYADS_TOKEN"

Budgets are in cents (daily_budget=12000 is $120). Insights: GET /act_<ID>/insights?level=ad&date_preset=last_7d&fields=spend,actions,purchase_roas.

Safety rules

Limits

Meta Marketing APIMeta’s own per account rate limits apply. On error code 17 or 80004, back off and retry later.
Agent200 requests a day per account on a paid plan. Demo: 15 a day.
Login links4 an hour per email

OwnMyAds is not affiliated with Meta. Questions: email [email protected].

OwnMyAds · CLI · Privacy · Terms · Acceptable use