How HTTP Works
2xx · Success
< HTTP/1.1 202 Accepted

202 Accepted

The request was accepted for processing but not completed yet. Learn when to use 202 for asynchronous operations.

Reviewed 6 min readintermediate2 sourcesTry itMarkdown
Cacheable
Only with explicit freshness
Client action
Poll for the outcome
Usually sent by
Origin app (queued or async work)
Spec
RFC 9110 §15.3.3
Often confused with
201, 200
On this page

TL;DR: 202 Accepted means the server accepted your request, but processing is not finished. Follow the supplied job-status URL; if progress stalls, check the job ID in the queue and worker logs before submitting the request again.

What is 202 Accepted?

A 202 Accepted response acknowledges unfinished work: an export, import or notification has been accepted for processing. The original HTTP response ends here. The eventual result belongs in a separate status resource or notification; the server cannot later replace that 202 with a 200 on the same exchange. RFC 9110 section 15.3.3 recommends describing the current state and pointing to a status monitor.

A job can subsequently fail validation or fail during execution. Show “queued” or “processing” in the client until the job’s own state reaches completion. A successful HTTP acceptance is the start of this workflow, not the completion screen.

The exchanges below are illustrative; job IDs, progress counts and timestamps describe an application contract rather than fields required by HTTP.

What you see in your client

202 is in the success range. If your application calls it an “error 202,” inspect its success test and the endpoint’s asynchronous contract.

  • Axios: the default 200–299 predicate resolves with response.status === 202. A custom validateStatus: status => status === 200 produces AxiosError: Request failed with status code 202. Check the default predicate and message construction.
  • fetch: resolves with response.ok === true; it leaves job completion to your code. The Fetch success range includes 202.
  • Python requests: raise_for_status() returns normally and response.ok is True. Its source reserves HTTPError for 4xx/5xx.
  • curl -f: accepts 202. Use curl -i to read the job URL; -f fails on HTTP codes of 400 or greater.
  • .NET: EnsureSuccessStatusCode() accepts 202 and returns the response.
  • Spring: WebClient.retrieve() and RestTemplate’s default handler treat 202 as a normal response. Handle the job state separately from HTTP exceptions.

A Location header on 202 gives your application a URL to inspect. It is not a redirect status: the client needs to start a new request to that URL. Save the job identifier before closing the screen so a reload can resume polling the same operation.

When Does This Happen?

You’ll see a 202 Accepted response in these common situations:

1. File Processing

POST /videos/upload with large video file
Server starts encoding in the background

2. Batch Operations

POST /users/bulk-import with CSV file
Server queues processing of thousands of records

3. Email Sending

POST /emails/send with newsletter to 10,000 subscribers
Server queues emails for gradual delivery

4. Report Generation

POST /reports/sales with complex parameters
Server starts generating large PDF report

5. Data Analysis

POST /analytics/process with large dataset
Server begins machine learning analysis

Example Responses

Video Upload Processing:

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /jobs/video-123

{
  "jobId": "video-123",
  "status": "processing",
  "message": "Video upload accepted for processing",
  "estimatedCompletion": "2026-01-18T12:15:00Z",
  "statusUrl": "/jobs/video-123/status"
}

Bulk Data Import:

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "batchId": "import-456",
  "status": "queued",
  "totalRecords": 5000,
  "message": "Import job queued successfully",
  "checkStatusAt": "/imports/456/status"
}

Email Campaign:

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "campaignId": "newsletter-789",
  "status": "sending",
  "recipients": 10000,
  "sent": 0,
  "progressUrl": "/campaigns/789/progress"
}

Real-World Example

For a photo-resizing endpoint, accepting the upload and producing the resized images are separate steps:

Request:

POST /photos HTTP/1.1
Host: api.example.com
Content-Type: application/octet-stream
Content-Length: 5

photo

Response:

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /jobs/photo-resize-abc123

{
  "jobId": "photo-resize-abc123",
  "status": "processing",
  "originalSize": "4032x3024",
  "targetSizes": ["1920x1440", "800x600", "200x150"],
  "estimatedCompletion": "2026-01-18T12:05:00Z",
  "statusEndpoint": "/jobs/photo-resize-abc123"
}

202 vs Other Success Codes

CodeMeaningWhen to Use
202Accepted, processing laterLong-running operations, async processing
200Success, completed nowImmediate operations with results
201Created successfullyResource creation that completes immediately
204Success, no contentOperations that complete with no response data

Status Checking Pattern

After receiving 202, clients typically check status:

Initial Request:

POST /reports/generate
→ 202 Accepted with jobId

Status Check:

GET /jobs/report-123
→ 200 OK with current status

Completion Check:

GET /jobs/report-123
→ 303 See Other, Location: /reports/final-report.pdf

Common Mistakes

Using 202 for completed operations

POST /users/login  ← Fast operation
HTTP/1.1 202 Accepted  ← Should be 200 OK immediately

Omitting status tracking

HTTP/1.1 202 Accepted
{"message": "Processing"}  ← No way to check progress!

Keeping slow work on the request path

A server can wait for completion and return 200, but that holds the connection open. When the API queues the work and replies before completion, use 202 and give the client a monitoring URL.

POST /videos/process  ← Takes 10 minutes
HTTP/1.1 200 OK  ← Client waits 10 minutes for response

Return a job URL

POST /videos/process
HTTP/1.1 202 Accepted
Location: /jobs/video-123

{
  "jobId": "video-123",
  "statusUrl": "/jobs/video-123"
}

Common causes by stack

Express: res.status(202).location('/jobs/123').json({ jobId: '123' }) emits 202 explicitly. Check the response call and the enqueue result together: publish the job successfully before acknowledging it, and use a completed-operation code when the work already finished.

FastAPI: @app.post('/exports', status_code=202) selects acceptance; background_tasks.add_task(...) schedules work after the response. BackgroundTasks runs application background work; adding a task alone does not select 202. Use the path-operation status setting and record a status that the client can query.

Spring MVC / Spring Boot: ResponseEntity.accepted().location(jobUri).body(job) creates the response through the accepted builder. Trace the job identifier into your executor or queue logs when the request succeeds but the status never advances.

ASP.NET Core: Accepted("/jobs/123", job) creates a 202 with a monitoring location and response value. The controller source documents that URI as the location for monitoring requested content. Pair it with a GET action that reports the stored job state.

AWS Lambda / API Gateway: Lambda’s InvocationType: Event returns 202 for asynchronous invocation. API Gateway’s non-proxy asynchronous Lambda integration sets X-Amz-Invocation-Type to 'Event'; inspect the method’s response mapping to see what your caller receives. Check the function’s invocation logs rather than expecting its return payload in the acceptance response.

Handling a job that stays pending

Poll the status URL supplied by the API, with its documented delay, and stop when the body reports a terminal state such as completed or failed. Those names are application fields, so implement the actual values your API publishes. A 200 OK from the status endpoint means the status lookup succeeded; its body can report that the background operation failed.

Keep a record linking the incoming request, job ID and queue message ID. If polling stays at queued, inspect whether a worker consumed that message. If it stays at processing, inspect that worker’s last recorded step. Re-submit only after checking the original job: another POST can enqueue another export or email campaign. A client-side timeout on polling should preserve the job URL for a later check.

Getting 202 Accepted right

Provide Job Tracking:

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /jobs/unique-job-id

{
  "jobId": "unique-job-id",
  "statusUrl": "/jobs/unique-job-id",
  "estimatedDuration": "5 minutes"
}

Include Progress Information:

GET /jobs/unique-job-id
HTTP/1.1 200 OK

{
  "status": "processing",
  "progress": 65,
  "message": "Processing item 650 of 1000"
}

Handle Completion:

GET /jobs/unique-job-id
HTTP/1.1 303 See Other
Location: /results/final-output

Try It Yourself

Use the request builder to inspect response headers and bodies. For an asynchronous API you operate, send its documented POST request, record the returned job ID, then send a GET to its monitoring URL. Compare the HTTP status with the job state in the body; they answer different questions.

Try it with curl

Start a job, then poll the URL the server gives you in Location.

curl -i -X POST https://api.example.com/exports \
  -H 'Content-Type: application/json' \
  -d '{"format":"pdf"}'

curl -i https://api.example.com/exports/8f3a

The response headers can include a polling interval:

HTTP/2 202
location: /exports/8f3a
retry-after: 5

Read retry-after: 5 as an instruction in this API to wait five seconds before polling. Document that convention for your clients; HTTP 202 itself sets no polling interval.

Frequently asked questions

What does 202 Accepted mean?

A 202 response means the server accepted the request for processing but has not completed it yet. The client should use the supplied status URL or notification mechanism to learn whether the operation finishes or fails.

What is the difference between 202 and 200?

200 means the request completed successfully. 202 means the request was accepted but processing is not finished. Use 202 for long-running operations that cannot complete immediately.

How do I check the status of a 202 request?

The 202 response typically includes a Location header or response body with a URL to poll for status. Alternatively, use webhooks to receive notifications when processing completes.

When should I use 202 vs 201?

Use 201 when a resource is created immediately. Use 202 when creation is queued for later processing. 201 means creation is complete; 202 means processing is incomplete and the outcome is pending.

Sources

  1. MDN Web Docs: 202 Accepteddeveloper.mozilla.org
  2. RFC 9110: 202 Acceptedrfc-editor.org

Keep going

Browse /search