HTTP 402 Payment Required: What It Means and How to Fix It
HTTP 402 Payment Required is a status code that RFC 9110 reserves for future use, so no standard defines how clients should handle it. In practice, some APIs and SaaS products return 402 when an account has run out of credits, a subscription has lapsed, or a payment failed, and some newer machine-to-machine payment schemes use it to ask for payment.
- Code
- 402
- Name
- Payment Required
- Class
- 4xx client error
- Retry?
- No, fix the cause first
What causes a 402 error?
- →The account behind the API key has no credits or quota left for the billing period.
- →A card on file was declined or the subscription was cancelled.
- →The endpoint or feature needs a higher plan than the account has.
- →A paywalled site or API that asks clients to pay per request before it serves content.
How do you fix a 402 error when web scraping?
- →Read the response body. Because the spec does not define 402, each service explains its own meaning there.
- →Check the billing page or usage dashboard of the API you are calling before changing code.
- →Stop retrying. A 402 does not clear until someone pays, upgrades, or the quota resets.
- →Alert on 402 separately from other 4xx errors, since it needs a human with billing access, not a code fix.
How do you fix a 402 error on your own server?
- →If you return 402, document exactly what it means for your API and include a link to the billing page in the body.
- →Prefer a clear error code in the body (for example
USAGE_EXCEEDED) so clients can branch on it, since 402 has no standard semantics.
How do you handle a 402 error in a retry loop?
402 is not in RETRYABLE, so raise_for_status() raises on the first response instead of spending retries on a request that will fail the same way. Fix the cause, then send the request again.
import random
import time
import requests
RETRYABLE = {408, 429, 500, 502, 503, 504, 520, 521, 522, 523, 524}
def fetch(url: str, max_attempts: int = 5) -> requests.Response:
for attempt in range(max_attempts):
try:
response = requests.get(url, timeout=(10, 60))
except requests.Timeout:
time.sleep(2**attempt + random.uniform(0, 1))
continue
if response.status_code not in RETRYABLE:
response.raise_for_status()
return response
retry_after = response.headers.get("Retry-After", "")
backoff = 2**attempt + random.uniform(0, 1)
time.sleep(min(int(retry_after) if retry_after.isdigit() else backoff, 60))
raise RuntimeError(f"Gave up on {url} after {max_attempts} attempts")
How does Context.dev handle a 402 error?
Context.dev does not use 402. When an organization does not have enough credits, the API returns 401 with a message saying so. The free plan includes 1,000 credits a month, a standard scrape costs 1 credit, and the pricing page lists the credits on each plan.
See what the web scraping API does on every request, or read how to fix HTTP errors in web scraping for a longer walkthrough.
Frequently asked questions about a 402 error
Is 402 Payment Required an official status code?
It is registered, but RFC 9110 only says it is reserved for future use. There is no standard behavior, which is why each API that uses it defines its own meaning.
Why does an API return 402 instead of 403?
It separates billing problems from permission problems. A 402 tells the client that paying or upgrading will unlock the request, while a 403 says the request is refused regardless.
How do I fix a 402 error?
Check the account’s billing: credits, quota, card status, and plan. Once the account is in good standing the same request succeeds without any code change.
Which status codes are related to 402?
Sources
Last reviewed