Accepted
ActiveHTTP 202 Accepted indicates the request has been accepted for processing, but the processing has not been completed. Defined in RFC 9110 §15.3.3. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
Description
The 202 Accepted status code indicates that the request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place.
There is no facility in HTTP for re-sending a status code from an asynchronous operation. The 202 response is intentionally noncommittal – its purpose is to allow a server to accept a request for some other process without requiring the user agent to wait.
Async job pattern (polling): 1. Client: POST /reports/generate → Server: 202 Accepted + Location: /reports/jobs/abc123 2. Client polls: GET /reports/jobs/abc123 → {status: 'running', progress: 42} 3. Client polls: GET /reports/jobs/abc123 → {status: 'complete', result_url: '/reports/r42'} The Location header (or body job_id) tells the client where to check status. Retry-After can indicate the suggested polling interval.
Webhook alternative: Instead of polling, the server calls back when the job finishes: POST /reports/generate + Webhook-Url: https://client.example.com/hooks/report-done → 202 Accepted When done: POST https://client.example.com/hooks/report-done {"job_id": "abc123", "result_url": "..."} Webhooks eliminate polling overhead but require the client to expose a public endpoint.
202 vs 201 vs 204: 201 Created: synchronous, resource was created NOW, Location points to the new resource. 202 Accepted: asynchronous, resource may be created LATER, Location points to a job status endpoint. 204 No Content: synchronous, operation completed, nothing to return (e.g., DELETE). Never use 202 for synchronous operations that complete before the response is sent.
Idempotency considerations: If the client retries a 202 request (e.g., network error before receiving the response), it may trigger the same async operation twice. Use idempotency keys: POST /reports/generate + Idempotency-Key: client-generated-uuid Server deduplicates by key and returns the same 202 (or 200 if already done).
Examples
POST /api/reports/generate HTTP/1.1
Host: api.example.com
Content-Type: application/json
Idempotency-Key: client-uuid-abc123
{"type": "monthly", "month": "2026-08"}HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /api/reports/jobs/job_abc123
Retry-After: 5
{"job_id": "job_abc123", "status": "queued", "poll_url": "/api/reports/jobs/job_abc123", "estimated_seconds": 30}GET /api/reports/jobs/job_abc123 HTTP/1.1
Host: api.example.com
HTTP/1.1 200 OK
Content-Type: application/json
{"job_id": "job_abc123", "status": "running", "progress": 67}
---
GET /api/reports/jobs/job_abc123 HTTP/1.1
HTTP/1.1 200 OK
{"job_id": "job_abc123", "status": "complete", "result_url": "/api/reports/r42"}POST /api/reports/generate HTTP/1.1
Content-Type: application/json
Webhook-Url: https://myapp.example.com/hooks/report-done
{"type": "monthly"}
HTTP/1.1 202 Accepted
{"job_id": "job_abc123"}
# When complete, server calls:
POST https://myapp.example.com/hooks/report-done
{"job_id": "job_abc123", "status": "complete", "result_url": "/api/reports/r42"}Edge Cases
- •202 does NOT guarantee the request will be fulfilled – the job may fail during async processing. Always provide a way to communicate failure (job status endpoint or webhook with error payload).
- •Always provide a way for the client to check the job status: Location header pointing to a status endpoint, or job_id in the response body. Without it, clients have no way to know if the operation succeeded.
- •Do not use 202 for synchronous operations that complete before the response is sent. If your handler returns in <200ms, use 200 or 201 instead. 202 implies the response is returned BEFORE the work is done.
- •Idempotency: if the client retries on network error (before receiving the 202), they may trigger the operation twice. Accept and honor Idempotency-Key headers to deduplicate. Return the original 202 or the completed result for duplicate requests.
- •The Retry-After header on a 202 can suggest the polling interval. Do not ignore it – exponential polling without guidance is wasteful.
- •202 vs 201 semantics matter at the API contract level: 201 means 'resource exists now at Location', 202 means 'we accepted your request and Location is where to check progress'. Mixing them confuses client code.
When You'll See This
- →Triggering a long-running report generation
- →Submitting a batch processing job
- →Sending a video for transcoding
- →Queuing an email campaign for delivery
Implementation References
| Language | Constant |
|---|---|
| Go | http.StatusAccepted |
| Rust | http::StatusCode::ACCEPTED |
| Python | http.HTTPStatus.ACCEPTED |
| Node.js | http.STATUS_CODES[202] |
| .NET | HttpStatusCode.Accepted |
| Java | HttpURLConnection.HTTP_ACCEPTED |
History
Introduced in HTTP/1.0 (RFC 1945, 1996). Became critical with the rise of async APIs and microservices where operations may take seconds or minutes to complete.
Related Status Codes
Related Headers
FAQ
What is the difference between 200, 201, 202, and 204?
200 OK: request completed synchronously, body contains the result. 201 Created: request completed synchronously, a new resource was created at Location. 202 Accepted: request accepted but processing is asynchronous – the operation has NOT finished yet, check the status endpoint. 204 No Content: request completed synchronously, nothing to return (common for DELETE). The key distinction: 202 is the ONLY one that means 'not done yet'.
How should clients poll after receiving a 202?
Use the URL from the Location header or job_id from the response body. Poll at the interval suggested by Retry-After if present. Use exponential backoff without Retry-After. Stop polling when the status endpoint returns a terminal state (complete, failed, cancelled). Consider setting a maximum polling duration and treating timeout as failure.
Should I use webhooks or polling with 202?
Polling is simpler to implement and works for any client, but wastes requests on long jobs. Webhooks are more efficient (zero polling overhead) but require the client to expose a public HTTPS endpoint and handle delivery failures. For server-to-server APIs, offer both: accept an optional webhook URL in the request; if provided, use webhooks; otherwise rely on polling.
How do I prevent duplicate async operations when the client retries?
Accept an Idempotency-Key header on the initial request (a UUID generated by the client). Store it with the job. If the same key arrives again (client retry), return the existing 202 or the completed result rather than starting a new job. Stripe, Adyen, and most payment APIs use this pattern.