The /ad_account/ads endpoint has a rate limit of 200 requests per hour per ad account, with a maximum of 25,000 ads returned per single request

Facebook's Graph API enforces two separate limits on the /ad_account/ads endpoint. The first is a rate limit—how many times you can call the endpoint in a given period. The second is a response limit—how many ad objects the API will return in one call. Understanding which limit you're hitting matters because the fix is different for each one.

The rate limit of 200 requests per hour applies to each ad account individually. If you manage multiple ad accounts, each one gets its own 200-request bucket. The response limit of 25,000 ads per request is a hard cap on the number of ad objects returned, regardless of how many ads actually exist in your account. If your account has 50,000 active ads, a single request returns only the first 25,000.

Key Takeaways

  • The /ad_account/ads endpoint allows 200 requests per hour per ad account, measured from the time of your first request in that hour.
  • Each single request returns a maximum of 25,000 ad objects; if you need more, you must paginate using the cursor provided in the response.
  • Rate limits reset on a rolling hourly window, not at fixed times, so the exact reset moment depends on when you made your first call.
  • Pagination cursors let you fetch the next batch of ads without counting against your hourly request limit as heavily as making unrelated calls would.
  • Different API access levels (standard, business, premium) may have different limits; check your app's current status in the Facebook Developers dashboard.

How the hourly rate limit works in practice

The 200 requests per hour limit is a rolling window, not a fixed schedule. This means the limit resets 60 minutes after your first request in that hour, not at the top of the clock. If you make your first call at 2:15 p.m., your window closes at 3:15 p.m. A second ad account you manage has its own separate 200-request window.

When you hit the rate limit, the API returns an error response with HTTP status 429 (Too Many Requests) and a message indicating you have exceeded the rate limit. The response includes a retry-after header that tells you how many seconds to wait before trying again. Most implementations wait for that duration and then retry the request automatically.

The 200-request limit counts all calls to the endpoint, including failed requests. A request that returns an error still consumes one of your 200 slots. This matters if you're debugging or testing—each test call counts.

Understanding the 25,000 ad response cap

The 25,000-ad maximum per request is separate from the hourly rate limit. Even if you have 100 requests left in your hourly budget, a single request will never return more than 25,000 ad objects. This limit exists to prevent the API from returning responses so large they time out or consume excessive bandwidth.

When your account has more than 25,000 ads, the API response includes a paging cursor (called after in the response). You use this cursor in your next request to fetch the next batch of ads. The second request counts as one of your 200 hourly requests, but it retrieves the next 25,000 ads without duplicating the first batch.

To retrieve all ads in an account with 50,000 ads, you need at least two requests: one for the first 25,000, and one for the remaining 25,000. If you have 100,000 ads, you need four requests. Plan your hourly budget accordingly if you're doing a full account export.

Pagination and cursor-based fetching

Facebook's Graph API uses cursor-based pagination rather than offset-based pagination. After your first request, the response body includes a paging object with an after cursor. You pass this cursor as a parameter in your next request to continue where you left off.

The cursor itself is opaque—you don't decode it or modify it. You straightforward include it as-is in the next request. Each cursor is valid for a limited time (typically a few hours), so if you're paginating through a large account, do it in one continuous session rather than pausing for days between requests.

Pagination requests still count against your 200-per-hour limit. If you need to fetch all ads from a 100,000-ad account, you'll use four requests and consume four of your 200 hourly slots, leaving 196 for other work.

What happens when you exceed the limits

If you exceed the hourly rate limit, the API returns HTTP 429 with a message like "Please reduce your request rate." The retry-after header tells you the number of seconds to wait. Most SDKs and client libraries handle this automatically by waiting and retrying, but if you're making raw HTTP calls, you need to implement the wait yourself.

If you request more than 25,000 ads in a single call, the API does not return an error. Instead, it returns exactly 25,000 ads and includes a paging cursor. This is not an error state—it's the expected behavior. Your code should check for the presence of the after cursor and make another request if you need the remaining ads.

Repeated violations of rate limits (making requests when ready after receiving a 429 response, without waiting) can result in temporary or permanent throttling of your app's access. The API may start rejecting requests from your app entirely if it detects a pattern of ignoring rate-limit signals.

How access level affects your limits

Your app's access level in the Facebook Developers dashboard determines your baseline rate limits. Standard access has the lowest limits. Business access (which requires business verification) typically allows higher rates. Premium access, available to select partners, has even higher limits.

To check your current access level and limits, log into the Facebook Developers dashboard, navigate to your app, and view the Settings > Basic page. The access level is listed under "App Roles" or "App Status." If you need higher limits, you can request a rate limit increase through the dashboard, though approval is not may provide and depends on your use case and app history.

Rate limits can also vary by endpoint. The /ad_account/ads endpoint may have different limits than other ad-related endpoints like /ad_account/adsets or /ad_account/campaigns. Always check the official Graph API documentation for the specific endpoint you're using.

Strategies for staying within limits

If you're regularly hitting the 200-request-per-hour limit, consider batching your requests. Instead of making one request per ad account, fetch data from multiple accounts in a single session and cache the results locally. This reduces the number of API calls you need to make.

For large accounts with many ads, use the fields parameter to request only the fields you need. Requesting fewer fields does not change the response limit (you still get 25,000 ads maximum), but it reduces bandwidth and processing time on both ends.

If you're building a tool that needs to sync all ads from an account regularly, do the full sync once and then use the updated_time field to fetch only ads that have changed since your last sync. This approach uses far fewer requests than re-fetching the entire account each time.

Frequently Asked Questions

Does the 200-request limit reset at midnight or on a rolling basis?

It resets on a rolling 60-minute window. If you make your first request at 3:45 p.m., your limit resets at 4:45 p.m., not at midnight. Each ad account has its own separate window.

If I have 10 ad accounts, do I get 200 requests per account or 200 total?

You get 200 requests per account. Each ad account has its own rate-limit bucket. Managing 10 accounts gives you 2,000 total requests per hour across all of them, as long as you distribute the calls evenly.

Can I request fewer than 25,000 ads to reduce response size?

Yes. Use the limit parameter in your request to specify a smaller number, such as limit=1000. This returns fewer ads per request but still counts as one request against your hourly limit. It's useful if you're processing ads one batch at a time and want smaller responses.

What if the paging cursor expires while I'm fetching a large account?

Cursors typically remain valid for a few hours. If a cursor expires, the API returns an error. Start a new pagination from the beginning using the first request (without a cursor). To avoid this, fetch all pages in one continuous session rather than pausing between requests.

Does making a request that returns zero ads still count against my limit?

Yes. Any request to the endpoint, regardless of the response size or whether it returns an error, counts as one of your 200 hourly requests.