Glossary

Why 429 Retry-After Is Missing From Most Social Media APIs

Taras Shynkarenko
Taras Shynkarenko
•Updated: •8 min read
An HTTP 429 response with a Retry-After header next to the rate limit signals of five social platformsAn HTTP 429 response with a Retry-After header next to the rate limit signals of five social platforms

TL;DR, Quick Answer

8 min read

RFC 6585 defines 429 Too Many Requests and says the response MAY include a Retry-After header, which RFC 9110 defines as either a number of seconds or an HTTP date. None of the five big social APIs documents sending it. X points you to x-rate-limit-reset, a Unix timestamp. Meta signals limits with error codes 4, 17, 32, 613 and 80001 and never states the HTTP status. LinkedIn returns 429 with no documented headers and resets at midnight UTC. TikTok returns 429 with rate_limit_exceeded. YouTube reports an exhausted quota as a 403, not a 429.

What does 429 Retry-After mean?

A 429 Retry-After response is a server telling a client it sent too many requests and, optionally, how long to wait before the next one. The two halves come from two different specifications.

RFC 6585 defines the status code: "The 429 status code indicates that the user has sent too many requests in a given amount of time ("rate limiting")." It then makes the header optional: "The response representations SHOULD include details explaining the condition, and MAY include a Retry-After header indicating how long to wait before making a new request."

RFC 9110 defines the header itself, in section 10.2.3: "Servers send the "Retry-After" header field to indicate how long the user agent ought to wait before making a follow-up request." The section goes on to describe what the header means on a 503 and on a 3xx redirect. It never mentions 429. The link between the status code and the header lives entirely in RFC 6585, and there it is a MAY.

RFC 6585 also leaves the counting to the server: "Note that this specification does not define how the origin server identifies the user, nor how it counts requests." That one sentence explains why every platform below behaves differently. The standard gives them a status code and an optional header, and nothing else.

If a cache sits in front of your API client, RFC 6585 has one more rule for it: "Responses with the 429 status code MUST NOT be stored by a cache."

How do you parse a Retry-After value?

RFC 9110 allows two forms: "The Retry-After field value can be either an HTTP-date or a number of seconds to delay after receiving the response."

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120

The seconds form is "a non-negative decimal integer, representing time in seconds", and the RFC spells out that the second example means a delay of 2 minutes. A parser has to handle both. Try the integer first, then fall back to a date:

from email.utils import parsedate_to_datetime
from datetime import datetime, timezone
 
def retry_after_seconds(value):
    if value.strip().isdigit():
        return int(value)
    when = parsedate_to_datetime(value)
    return max(0, (when - datetime.now(timezone.utc)).total_seconds())

Rows of cars stuck in a traffic jam on a highway, a picture of a server turning away requests once too many arrive at once.

Which social media APIs send a Retry-After header?

None of the five, going by their own documentation. Each one signals a rate limit its own way, and two of them do not always use 429.

PlatformStatus on a rate limitBody signalTiming signal in the docsRetry-After documented
X429code: 88, "Rate limit exceeded"x-rate-limit-reset, a Unix timestampNo
Meta Graph APINot statederror.code of 4, 17, 32, 613 or 80001estimated_time_to_regain_access in minutes, business use case onlyNo
LinkedIn429"Resource level throttle limit for calls to this resource is reached."None, daily limits reset at midnight UTCNo
TikTok429rate_limit_exceededNone, one minute sliding windowNo
YouTube403 for quota, 429 for thumbnails onlyquotaExceeded, uploadRateLimitExceededNoneNo

Bluesky and Pinterest have their own header schemes, covered in the Bluesky API rate limit breakdown and the Pinterest API rate limit reference.

How does the X API signal a rate limit?

With a 429 and three headers on every response. The X rate limits page: "Exceeding limits results in a 429 error until the window resets." It documents x-rate-limit-limit as "Maximum requests allowed", x-rate-limit-remaining as "Requests remaining in window" and x-rate-limit-reset as "Unix timestamp when window resets."

x-rate-limit-reset is the field to use, and it is an absolute time, not a delay. X's sample value is 1705420800. Pass that to a sleep call as seconds and the worker sleeps for about 54 years, so subtract the current Unix time first. X's own recovery strategy is three steps: "Check x-rate-limit-reset for when the window resets", "Wait until that time before retrying", "Use exponential backoff if needed." Its sample code waits max(reset_time - time.time(), 60), so never less than a minute.

X documents two different bodies for the same condition. The rate limits page shows a 429 returning {"errors": [{"code": 88, "message": "Rate limit exceeded"}]}. The response codes page describes errors as objects with type, title and detail, and lists a .../rate-limit-exceeded type. Match on the HTTP status, and treat either body shape as a rate limit.

The same page adds a catch. X defines 429 as "Rate limit or usage cap exceeded", and it lists a separate .../usage-capped error type. A 429 caused by a usage cap does not clear when x-rate-limit-reset passes. Check the error type before you schedule a retry at the reset time.

How does Meta signal a rate limit?

With error codes in the JSON body. Meta's rate limiting reference and error handling guide list them, and neither page states which HTTP status comes with them.

AdaptlyPost
AdaptlyPost

Start Your 7-Day Free Trial

All-platform analytics

Social Inbox

AI-powered assistant

CodeWhat Meta says
4"Indicates that the app whose token is being used in the request has reached its rate limit."
17"Indicates that the User whose token is being used in the request has reached their rate limit."
32"Indicates that the User or app whose token is being used in the Pages API request has reached its rate limit."
613"Indicates that a custom rate limit has been reached."
80001"There have been too many calls to this Page account. Wait a bit and try again."

Meta contradicts itself on what to do next. The error handling guide says, for both 4 and 17: "Temporary issue due to throttling. Wait and retry the operation, or examine your API request volume." The rate limiting reference says: "When the limit has been reached, stop making API calls. Continuing to make calls will continue to increase your call count, which will increase the time before calls will be successful again." Go with the stricter one, because retrying under Meta's rules makes the block longer.

Meta's timing signal depends on which of its two rate limit systems caught you. The business use case header carries estimated_time_to_regain_access, defined as "Time, in minutes, until calls will not longer be throttled." Note the unit: Retry-After counts in seconds, and this field counts in minutes. The app-level header has no time field at all, which the x-app-usage header breakdown covers in detail.

Close-up of an analog wall clock, standing in for limits that reset on a fixed daily schedule such as midnight UTC.

How do LinkedIn and TikTok signal a rate limit?

Both return a plain 429 and document no timing headers.

LinkedIn's rate limiting page: "Rate limited requests will receive a 429 response." Its error handling page gives the message: "Resource level throttle limit for calls to this resource is reached." LinkedIn does not publish the limits themselves either: "Standard rate limits are not published in documentation." You find them in the Developer Portal's Analytics tab, and only for endpoints you have called at least once that UTC day.

The timing comes from the calendar instead of a header. LinkedIn states that limits cover "a 24 hour period" and "reset at midnight UTC every day." After a LinkedIn 429 caused by your own volume, the earliest useful retry is the next 00:00 UTC. LinkedIn also sends 429 for a reason that is not yours: "In rare cases, LinkedIn may also return a 429 response as part of infrastructure protection. API service will return to normal automatically." Nothing in the response tells the two cases apart.

TikTok's rate limits page: "Request rate calculation is based on a one minute sliding window. If the number of requests exceeds the threshold, new requests will be throttled and a response will be returned with HTTP status 429 and error code rate_limit_exceeded." The page lists 600 requests for each of /v2/user/info/, /v2/video/query/ and /v2/video/list/. The publishing endpoint is much tighter. The Content Posting API reference says of /v2/post/publish/video/init/: "Each user access_token is limited to 6 requests per minute."

TikTok's daily posting cap is not a 429. It is a 403 with spam_risk_too_many_posts, described as "The daily post cap from the API is reached for the current user." A retry loop keyed on 429 will never see it, and a retry loop that retries every 4xx will hammer it for nothing.

How does YouTube signal a quota error?

Mostly with a 403. YouTube's error reference lists quotaExceeded (403): "The request cannot be completed because you have exceeded your quota." That is the error an exhausted daily quota produces, and it is not a 429.

YouTube's overview states the default budget: "Projects that enable the YouTube Data API have a default quota allocation of 100 search.list calls, 100 videos.insert calls, and 10,000 units per day combined for all other endpoints." It also notes that "All API requests, including invalid requests, incur at least a one-point quota cost", so failed retries still spend quota.

The only 429 in YouTube's error reference belongs to thumbnails: tooManyRequests (429) uploadRateLimitExceeded, "The channel has uploaded too many thumbnails recently. Please try the request again later." The daily upload cap is a third status again, badRequest (400) uploadLimitExceeded, with a pointed description: "This is a YouTube platform restriction and is entirely separate from your Google Cloud project's API quota." A quotaExceeded is not retryable the same day. Raising the ceiling is a paperwork process, covered in what a YouTube API quota extension involves.

What should a retry policy do when Retry-After is missing?

Read the platform's own signal, and separate caps from rate limits before you retry anything.

If a response does carry Retry-After, honour it. Otherwise, take the wait from the platform: x-rate-limit-reset minus now for X, estimated_time_to_regain_access in minutes for Meta's business use case limits, the next midnight UTC for LinkedIn, and at least a minute for TikTok's sliding window. For Meta's app-level errors, stop the queue and check X-App-Usage before resuming.

Then route the errors that look like rate limits but are not: TikTok's spam_risk_too_many_posts, YouTube's quotaExceeded and uploadLimitExceeded, and X's usage cap. Those are daily ceilings, and backoff measured in seconds will not clear any of them.

Retry decision order
1
Sort the error. Daily caps such as TikTok's spam_risk_too_many_posts, YouTube's quotaExceeded and uploadLimitExceeded, and X's usage cap do not clear with backoff. Stop retrying them.
2
Look for Retry-After. If the response carries it, honour it.
3
Read the platform signal. x-rate-limit-reset minus now for X, estimated_time_to_regain_access in minutes for Meta, the next midnight UTC for LinkedIn, at least a minute for TikTok.
4
Check Meta app-level errors. Stop the queue and check X-App-Usage before resuming.
Sorting caps from rate limits comes first, because backoff measured in seconds clears only rate limits.

Frequently asked questions

Is the Retry-After header required on a 429 response?

No. RFC 6585 says a 429 response "MAY include a Retry-After header indicating how long to wait before making a new request." Only the explanation of the condition is a SHOULD.

AdaptlyPost
AdaptlyPost

Start Your 7-Day Free Trial

All-platform analytics

Social Inbox

AI-powered assistant

What formats can a Retry-After header use?

RFC 9110 allows an HTTP date, such as Fri, 31 Dec 1999 23:59:59 GMT, or a non-negative integer number of seconds, such as 120. Parsers must handle both.

Does the X API send Retry-After on a 429?

X's rate limit and error pages do not document it. They direct you to x-rate-limit-reset, a Unix timestamp marking when the window resets, and X's sample code waits at least 60 seconds.

What HTTP status does the Facebook Graph API return for a rate limit?

Meta does not state it on the rate limiting reference or the error handling guide. Both identify rate limits by the code field in the JSON error body: 4, 17, 32, 613, or 80001 for Pages business use case limits.

Does the YouTube Data API return 429 when the quota runs out?

No. An exhausted quota returns 403 with the reason quotaExceeded. The only 429 in YouTube's error reference is uploadRateLimitExceeded on thumbnail uploads.

When does a LinkedIn API rate limit reset?

At midnight UTC. LinkedIn's rate limiting page says limits cover a 24 hour period and "reset at midnight UTC every day." LinkedIn documents no reset header, so compute the wait from the clock.

How do I turn x-rate-limit-reset into a wait time?

Subtract the current Unix time from it, because it is an absolute timestamp and not a delay. X's sample value is 1705420800, and passing that to a sleep call as seconds makes the worker sleep for about 54 years. X's own sample code waits max(reset_time - time.time(), 60), so never less than a minute.

Should I retry a YouTube quotaExceeded error?

Not on the same day. A quotaExceeded (403) means the daily quota is used up, and every request, including invalid ones, costs at least one point, so retries only spend more quota. Raising the ceiling is a paperwork process.

What does TikTok return when the daily posting cap is reached?

A 403 with the error code spam_risk_too_many_posts, described as "The daily post cap from the API is reached for the current user." It is not a 429, so a retry loop keyed on 429 never sees it. A loop that retries every 4xx will hammer it for nothing.

Should I keep retrying when Meta returns error code 4 or 17?

Stop making calls. Meta's rate limiting reference warns that continuing to make calls increases your call count, which increases the time before calls will be successful again. The error handling guide says to wait and retry, so the two pages disagree, and the stricter rule is the safer one.

Was This Article Helpful?

Let us know what you think!

See us more often in Google

One click marks AdaptlyPost as a preferred source, so our articles sit higher in your Top Stories, AI Mode, and AI Overviews.

Before you go...

AdaptlyPost

AdaptlyPost

Schedule your content across all platforms

Manage all your social media accounts in one place with AdaptlyPost.

All-platform analytics

Social Inbox

AI-powered assistant

Related Glossary Terms

Related Articles