---
title: 'Meta Ads API: Marketing API setup, access and limits'
description: 'Understand Meta Marketing API access, permissions, version limits and curl/Python examples. Learn when to build directly or use a managed Actions API.'
canonical: 'https://plainrouter.com/library/meta-ads-api'
format: Guide
published_at: '2026-10-01'
last_updated: '2026-10-01'
---

The Meta Ads API is usually a name for Meta's **Marketing API**: use it to read advertising performance and manage campaigns, ad sets and ads. Use the Conversions API to send conversion events, or the Ad Library API to search public-ad records instead.

This guide covers direct integration first, then when a managed layer fits. API names, access rules and examples were checked on October 1, 2026.

## Which Meta API do you need?

| API | Use it for | Important boundary |
| --- | --- | --- |
| Marketing API | Read account insights; create and manage advertising objects | Requires permissions and access to the advertiser's assets |
| Ad Library API | Search supported archived/public-ad transparency records | Coverage depends on the archive's rules; it is not private account reporting or campaign control |
| Conversions API | Send website, app or offline conversion signals to Meta | Sending an event does not create an ad or guarantee attribution |
| Graph API | The versioned objects, edges and request system underlying these integrations | It is the foundation, not a separate substitute for advertising permissions |

For event collection, start with [the Meta Conversions API guide](</library/meta-conversions-api>). For public-ad research, use Meta's [Ads Archive reference](<https://developers.facebook.com/docs/graph-api/reference/ads_archive/>).

## How to get Marketing API access

Start with a developer app and an ad account you are authorized to access. Add Marketing API access through the app dashboard, then check permissions, asset assignments and the app's access tier separately.

### Choose permissions for the job

Use ` ads_read ` for reading advertising reports. Use ` ads_management ` when the integration needs to manage ads; it also supports reads on accounts the token can access. Request additional permissions only when the selected endpoints require them. A permission does not grant access to every ad account.

Meta's current authorization documentation distinguishes two systems:

| System | Names | What it controls |
| --- | --- | --- |
| Permission/feature access level | Standard access, Advanced access | Whether an app can use a permission for its own use case or other advertisers |
| Marketing API Access Tier | Limited access, Full access | Marketing API capacity, business-management access and system-user capacity |

For an app managing only your own ad account, Standard permission access can be sufficient. Accessing other people's ad accounts requires the applicable Advanced permission access. Separately, Meta describes Limited Marketing API access as development-only and Full access as the reviewed tier for production advertisers. Development access still operates on production data; it is not a simulated ad account. [Meta authorization](<https://developers.facebook.com/docs/marketing-api/overview/authorization/>)

### Business verification and App Review

Business verification establishes the business's identity. App Review assesses requested permissions and features. Completing one does not automatically complete the other. Follow the dashboard's requirements for your use case, including verification when required, Advanced permissions and the Marketing API tier upgrade. Prepare a working demonstration of the access you request rather than requesting every permission preemptively.

### Choose the right token

For automation acting as your business, review Meta's system-user setup: assign the relevant assets and generate a token for the app with the permissions it needs. For software acting on behalf of customers, use the appropriate Meta authorization flow; a system-user token is not a shortcut around customer authorization. Store credentials on the server, monitor failures and plan revocation/replacement instead of assuming a token will remain valid forever. [System users](<https://developers.facebook.com/docs/marketing-api/system-users/>)

## Read ad insights, then pause one ad

These examples use **v26.0**. Load ` META_ACCESS_TOKEN `, ` META_AD_ACCOUNT_ID ` and ` META_AD_ID ` from your environment. The account ID is the numeric portion without ` act_ `; the ad ID identifies one ad. A reporting token needs ` ads_read ` or suitable management permission. Pausing needs ` ads_management ` and write access to that asset.

### curl: read first

```bash
: "${META_ACCESS_TOKEN:?Load a Meta access token}"
: "${META_AD_ACCOUNT_ID:?Set the numeric ad account ID}"

curl --fail-with-body --get \
  "https://graph.facebook.com/v26.0/act_${META_AD_ACCOUNT_ID}/insights" \
  --header "Authorization: Bearer ${META_ACCESS_TOKEN}" \
  --data-urlencode 'level=ad' \
  --data-urlencode 'fields=ad_id,ad_name,impressions,clicks,spend' \
  --data-urlencode 'date_preset=last_7d' \
  --data-urlencode 'limit=25'
```

This retrieves one page of results. Follow pagination to collect the full result set; no rows is different from zero spend. Choose reporting windows and attribution settings consistently when comparing this output with Ads Manager. [Insights documentation](<https://developers.facebook.com/docs/marketing-api/insights/>)

### curl: explicitly opt in to pausing

The following request changes a real ad. Set ` CONFIRM_PAUSE ` to the same ad ID only after checking the account and target. The guard prevents a copied read example from immediately becoming a write.

```bash
: "${META_ACCESS_TOKEN:?Load a Meta access token}"
: "${META_AD_ID:?Set the ad ID}"

if [ "${CONFIRM_PAUSE:-}" = "$META_AD_ID" ]; then
  curl --fail-with-body --request POST \
    "https://graph.facebook.com/v26.0/${META_AD_ID}" \
    --header "Authorization: Bearer ${META_ACCESS_TOKEN}" \
    --data-urlencode 'status=PAUSED'
else
  printf '%s\n' 'No change sent: CONFIRM_PAUSE must match META_AD_ID.'
fi
```

After a successful response, read the ad's ` status ` and ` effective_status ` to verify its configuration. Effective status also reflects surrounding delivery conditions. A write response is not proof of a performance outcome. [Ad reference](<https://developers.facebook.com/docs/marketing-api/reference/adgroup/>)

### Python: Meta's official SDK

Install ` facebook-business ` in your project environment and lock the version you validate for deployment. The following uses the same environment variables and explicit pause guard:

```python
import os

from facebook_business.api import FacebookAdsApi
from facebook_business.adobjects.ad import Ad
from facebook_business.adobjects.adaccount import AdAccount

FacebookAdsApi.init(
    access_token=os.environ["META_ACCESS_TOKEN"],
    api_version="v26.0",
)

account = AdAccount("act_" + os.environ["META_AD_ACCOUNT_ID"])
rows = account.get_insights(
    fields=["ad_id", "ad_name", "impressions", "clicks", "spend"],
    params={"level": "ad", "date_preset": "last_7d", "limit": 25},
)
for row in rows:  # The SDK cursor can fetch subsequent pages.
    print(dict(row))

ad_id = os.environ.get("META_AD_ID")
if ad_id and os.environ.get("CONFIRM_PAUSE") == ad_id:
    ad = Ad(ad_id)
    ad.api_update(params={"status": "PAUSED"})
    print(dict(ad.api_get(fields=["status", "effective_status"])))
```

These are small request examples, not a complete production worker. Add secret management, request/error logging without tokens, pagination bounds and recovery handling. If your app requires app-secret proof, configure that too; Meta's SDK supports initializing with your app ID and app secret. See the [official Python SDK](<https://github.com/facebook/facebook-python-business-sdk>).

## Rate limits and API versions: what breaks in production?

**There is no single request allowance for every Marketing API call.** Limits vary by access tier, account, operation and business use case. Reporting can also hit app-level limits; repeated edits to one object have separate throttling. Inspect the usage headers and error details returned by your actual endpoint. [Marketing API rate limits](<https://developers.facebook.com/docs/marketing-api/overview/rate-limiting/>)

Keep reporting jobs bounded, request only needed fields and use asynchronous Insights jobs for large reports. Back off with jitter on transient throttling, serialize conflicting edits and stop retrying permanent permission errors. After a write times out, read the target state before retrying: a lost response does not prove the change failed.

Pin an API version and schedule upgrades. **Marketing API retirement dates differ from general Graph API dates.** As checked on October 1, v26.0 is current; Marketing API v24.0 retires on October 6, 2026, even though the general Graph v24.0 support window is longer. Use the separate Marketing API table and review out-of-cycle changes, not a blanket assumption of two years for every ads endpoint. [Meta changelog and version schedules](<https://developers.facebook.com/docs/graph-api/changelog/>)

## Build directly or use Plainrouter?

Build directly when you need the full Marketing API surface, including custom campaign creation, audiences or specialized reporting. You own Meta app access, tokens, version upgrades, retries and change safeguards.

Plainrouter is a managed option for a narrower set of tasks. For supported workflows, you connect your ad account through **Plainrouter's Meta connection** instead of creating your own Meta app and completing your own app review. You still need the account permissions and asset access required by that connection. [Connect Meta](<https://plainrouter.com/docs/signals/connect-meta>)

The [Actions API](<https://plainrouter.com/docs/api/actions>) supports pause/resume, budget changes and creative proposals through policy checks. Ask mode holds changes for human approval; Full mode can queue policy-allowed changes automatically. New ad copies are created paused. Decision receipts record execution outcomes and available verification evidence, including failures.

Use a **Write Workspace key**, an active ` propose-actions ` grant and the applicable role/abilities. POST ` /actions/dry-run `, relative to the documented workspace API base, previews supported changes without writing to Meta or creating a proposal; it may read provider state. Check each item's availability and decision before submitting a proposal.

Plainrouter is **not a full Marketing API replacement**: it does not offer arbitrary campaign or audience creation. Its [TypeScript, Python, Ruby and Go SDKs](<https://plainrouter.com/docs/sdk/overview>) are Conversion API clients, with a separate CLI; do not assume those SDKs wrap the Actions endpoints. Use the documented REST interface for Actions, or [Plainrouter's hosted Meta Ads MCP server](</solutions/meta-ads-mcp>) for agents. See the [developer workflow](</solutions/developers>) for the broader integration.

## Frequently asked questions

### Is the Meta Ads API free?

The public Marketing API documentation reviewed for this guide does not publish a per-call price. That does not make an integration cost-free: advertising spend, infrastructure, maintenance and any third-party tooling are separate costs. Access tiers and quotas still apply; this guide does not promise unlimited free usage.

### Do I need App Review?

Your own-account prototype and a product serving other advertisers have different requirements. Check both permission access and the Marketing API tier: Meta requires review for Advanced permissions and Full Marketing API access. Business verification is a separate requirement where applicable.

### What is the difference between ads\_read and ads\_management?

` ads_read ` supports ad reporting. ` ads_management ` supports managing ads and relevant reads on accessible accounts. Choose the least access your actual endpoints need; neither permission overrides asset assignments.

### Is Marketing API the same as Ad Library API?

No. Marketing API works with authorized advertisers' accounts and reporting. Ad Library API searches supported public-ad archive records and does not give you private campaign insights or control over another advertiser's ads.

### Can an AI agent use it?

Yes, through code or an MCP server that exposes the needed operations. Check account scope, read/write permissions and approval behavior separately: an agent calling a raw Marketing API write does not automatically get Plainrouter's proposal controls.

### Python or Node?

Both can call the HTTP API, and Meta publishes Business SDKs for both. Choose the language your team operates well; permissions, account access and version limits remain the same. Start with the [Python SDK](<https://github.com/facebook/facebook-python-business-sdk>) or [Node.js SDK](<https://github.com/facebook/facebook-nodejs-business-sdk>).
