SiteError.comYour friendly guide to HTTP status codes
Status CodesBlog
  1. Home
  2. Blog
  3. Understanding HTTP 202 Accepted: The Async Contract That Promises Less Than You Think

Understanding HTTP 202 Accepted: The Async Contract That Promises Less Than You Think

August 17, 20267 min read
2xxSuccess

202 Accepted is a success code that isn't actually promising success. It's the honest response for work that's been queued but not finished — a batch job, a video encode, an email send — and its entire value comes from being upfront about what it does not guarantee. This post covers what 202 actually promises, the status-polling and Location-header patterns that make it usable in practice, how it compares to 200, 201, and 204, and how to return it correctly.

What Is a 202?

A 202 tells the client that the request has been accepted for processing, but the processing itself hasn't happened yet — and might not happen at all.

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. — RFC 9110, Section 15.3.3

In plain English: "I've received your request and will process it later." That's the whole contract — the server acknowledges the request was well-formed enough to queue, without making any promise about the outcome once it actually runs.

202 doesn't guarantee the operation will succeed — just that it's been queued. Always provide a way for clients to check the operation status (via a job ID or status URL).

What 202 Does Not Promise

This is the part of the spec that's easy to skim past: the RFC explicitly says the queued work "might or might not eventually be acted upon." That's a deliberately weak guarantee, and it matters for how you design around 202:

  • It doesn't promise the operation will succeed. The job could fail validation once a worker picks it up, hit a downstream error, or simply never run.
  • It doesn't promise a timeline. There's no implied SLA — "later" could mean seconds or hours.
  • It doesn't promise the final result will match what you'd expect from a synchronous 200 or 201. The eventual outcome is a separate concern from the receipt itself.

What 202 does promise is narrower and more honest: the request was accepted into a queue. Everything else — success, failure, timing — is a story the client has to go find out separately, which is exactly why 202 only works well when it's paired with a way to check back.

The Status-Polling Pattern

Because 202 defers the actual outcome, a bare 202 with no follow-up mechanism leaves the client stuck. The standard fix is to hand the client something to check later — usually a job ID, a status URL via the Location header, or both:

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /jobs/abc123
 
{"status": "queued", "jobId": "abc123"}

The client is then expected to poll GET /jobs/abc123 (or a webhook can notify it instead) until the job resolves to a terminal state — typically represented with its own status code once the resource exists: 200 or 201 for success, or an error code if the job ultimately failed. The Location header here isn't pointing at the finished resource the way it does on a 201 — it's pointing at a status resource that describes progress, which may itself change shape as the job moves from queued to running to done.

202 vs 200 vs 201 vs 204

CodeMeaningUse when
200 OKThe request succeeded, synchronouslyThe result is available immediately in the response
201 CreatedA resource was created, synchronouslyThe new resource exists by the time the response is sent, with a Location pointing at it
204 No ContentThe request succeeded, nothing to returnThe operation completed synchronously but there's no body to send back
202 AcceptedThe request was queued, asynchronouslyThe work hasn't completed yet — the response is a receipt, not a result

202 is the odd one out in this group: it's the only code here where the response is sent before the outcome is known. The other three all describe something that already happened by the time the client sees the response.

Common Causes

The shapes of work that legitimately produce a 202:

  1. Batch processing job queued — a bulk import, export, or report generation that runs on a worker rather than inline with the request.
  2. Email scheduled for delivery — the send is queued against a mail provider rather than confirmed as delivered.
  3. Async operation started — video encoding, image processing, or any task expensive enough that blocking the request until it finishes isn't practical.

Returning 202 Correctly

Express / Node.js

app.post("/videos/:id/encode", async (req, res) => {
  const job = await queue.enqueue("encode-video", { videoId: req.params.id });
 
  res
    .status(202)
    .location(`/jobs/${job.id}`)
    .json({ status: "queued", jobId: job.id });
});

Next.js App Router

// app/api/videos/[id]/encode/route.ts
export async function POST(
  request: Request,
  { params }: { params: Promise<{ id: string }> },
) {
  const { id } = await params;
  const job = await enqueueEncodeJob(id);
 
  return Response.json(
    { status: "queued", jobId: job.id },
    { status: 202, headers: { Location: `/jobs/${job.id}` } },
  );
}

NGINX

NGINX doesn't originate 202s — queuing is an application-layer decision — but it passes an upstream's 202 straight through like any other response:

location /api/ {
    proxy_pass http://backend;
    # 202 responses from the backend are forwarded as-is
}

REST API JSON body

HTTP/1.1 202 Accepted
Content-Type: application/json
Location: /jobs/abc123
 
{"status": "queued", "jobId": "abc123"}

Common Pitfalls

  1. Returning 202 with no way to check the outcome. A bare 202 and nothing else leaves the client with no path to find out whether the work succeeded — always pair it with a job ID, a status URL, or a webhook.
  2. Treating 202 as a guarantee of eventual success. The RFC is explicit that the work "might or might not eventually be acted upon" — surface real failure states through the status resource rather than assuming the queue always finishes.
  3. Using 202 for work that's actually fast enough to do synchronously. If the operation reliably completes in the time of a normal request, returning 200 or 201 directly is simpler and gives the client an immediate, authoritative answer.
  4. Pointing the Location header at a resource that doesn't exist yet. Unlike 201's Location, a 202's Location should point at a status resource that exists now, not at the eventual output that hasn't been created.
  5. Leaving the status resource in a permanently "pending" state. If a job fails, times out, or is abandoned, the status endpoint should reflect that terminal state — not leave clients polling forever against a job that will never resolve.

Wrapping Up

202 is a status code that tells the truth about uncertainty instead of pretending the work is already done. The rules of thumb:

  • 202 means the request was accepted into a queue — not that it succeeded, and not on any particular timeline
  • Pair it with a job ID or status URL, since the response itself carries no outcome
  • Reserve it for work that genuinely can't complete synchronously — don't reach for it just to make a slow endpoint feel faster
  • The eventual result belongs to a separate resource, checked later, that resolves to its own 200, 201, or error status

For more, see our pages on 202 Accepted, 200 OK, 201 Created, and 204 No Content.

Full Reference

202 Accepted

The request has been accepted for processing, but the processing has not been completed.

Related Status Codes

✅200OK🎉201Created📋202Accepted📢203Non-Authoritative Information🫥204No Content🔄205Reset Content🍕206Partial Content📊207Multi-Status📝208Already Reported♻️226IM Used
Back to Blog

Popular Status Codes

  • 200 OK
  • 301 Moved Permanently
  • 302 Found
  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable

Compare Codes

  • 401 vs 403
  • 301 vs 302
  • 404 vs 410
  • 500 vs 502
  • Compare any codes →

Categories

  • Informational
  • Success
  • Redirection
  • Client Error
  • Server Error
  • NGINX
  • Cloudflare
  • AWS ELB
  • Microsoft IIS

Tools

  • Cheat Sheet
  • Status Code Quiz
  • URL Checker
  • API Playground
  • Blog

© 2026 SiteError.com. All rights reserved.