The Reddit Ads API through MCP

For anyone wiring the Reddit Ads API to an assistant, whether ours or their own.

Everything below is relative to https://ads-api.reddit.com/api/v3. Every write sends { "data": { ... } } and every read returns { "data": ..., "pagination": { ... } }. This is the short version of what a connector has to handle before an assistant can be trusted with an ad account.

Auth and scopes

OAuth 2 bearer tokens. adsread covers every GET and the read only POSTs, which includes reports, history, forecasting, and targeting validation. adsedit covers creates, PATCH, and DELETE. adsconversions is only for conversion events. Keep the tokens server side: the model should see tool results, never a credential.

Set a real User-Agent in the format {platform}:{app id}:{version} (by /u/{username}). Default library agents are throttled hard.

Money is microcurrency

Bid values, budgets, spend caps, and every cost metric are integers where 1,000,000 equals one unit of account currency. Convert on the way in and out, or the assistant will confidently report a $3 CPC as three million.

The create order

  1. Campaign, with an objective and configured_status: "PAUSED".
  2. Ad group, with a bid strategy, a bid type, a goal type and value, a conversion pixel id, a start time, and a targeting object.
  3. A structured post job, which returns a job rather than a post.
  4. Poll the job until SUCCESS, then take its post_id.
  5. Ad, pointing at the post, with a click URL.

Creative lives on the post, not the ad, which is why the order cannot be rearranged. Lists and creates are account scoped, single entities live on bare paths, and updates are always PATCH. Reddit answers 404 for an unsupported verb as well as a missing resource.

The details that cost a day

  • Start times are exact. 2026-09-20T09:00:00-04:00. Milliseconds are rejected with a message that does not mention milliseconds.
  • Every ad group needs a pixel id. In practice it equals the ad account id.
  • Targeting is an object and never null. Array keys must be arrays, devices are objects rather than strings, placements are locations with FEED and COMMENTS_PAGE, and an unknown key fails the whole request. A PATCH replaces the object, so read, merge, write back.
  • Click URL macros must stay literal. URLSearchParams percent encodes the braces and the macro quietly stops working.
  • Post jobs are asynchronous and one way. Reddit downloads your media at job time, so the URL must be public and stable, and posts cannot be deleted.
  • Rate limits are per endpoint group. Campaign reads 400 a minute, writes 200, targeting taxonomy 100, audience estimates 10. The last one is the one you hit first.

What MCP adds on top

A tool list is a boundary. The useful design choices are the ones that decide what the assistant cannot do: read only until a human types a phrase, a second phrase before anything can start spend, every created entity paused, and an audit row for every write. Without those, handing a model adsedit is handing it your budget.

Sources worth avoiding

Several community SDKs vendor an OpenAPI file with /accounts/... paths and invented bid strategy enums such as LOWEST_COST and COST_CAP. They do not work against the live API. Reddit's own document at https://ads-api.reddit.com/api/v3/openapi.json is the thing to trust.

Reddit Ads MCP connects your Reddit Ads account to Claude or ChatGPT, so the work in this post becomes a question you ask instead of a report you build. Start a 7-day free trial on your own ad account, then pay $12 a month. See what it does.

All guides and notes