API and development

Handling 202 Accepted and Refresh Jobs

Cold Workshop data should not freeze your app. When a resource is not cached yet, the API returns 202 Accepted, starts a background refresh, and tells your client when to retry.

Retry pattern Retry-After Cold cache

The flow

GET /v1/mods?search=radio

HTTP/1.1 202 Accepted
Location: /v1/refresh/jobs/9f0b7d0f6fd4f88a
Retry-After: 2
X-Cache: MISS

{"id":"9f0b7d0f6fd4f88a","status":"queued","resource_url":"/v1/mods?search=radio","retry_after_seconds":2}

If a cold-cache request returns 202 Accepted, wait the number of seconds in Retry-After, then retry the original URL. Most clients do not need to poll the job URL.

The rules

  • 202 is not an error. Do not log it as a failure or give up on the first response.
  • Respect Retry-After. Retrying faster does not speed up the refresh.
  • Bound your retries. Three to five attempts is enough for most clients.
  • Retry the original URL. The job endpoint reports status only; it does not contain the final data.

Minimal implementation

import time
import requests

def fetch_with_refresh(url, max_attempts=4):
    headers = {"User-Agent": "my-tool/1.0 ([email protected])"}
    for _ in range(max_attempts):
        response = requests.get(url, headers=headers, timeout=15)
        if response.status_code != 202:
            response.raise_for_status()
            return response.json()
        wait = int(response.headers.get("Retry-After", "2"))
        time.sleep(wait)
    raise RuntimeError("Still refreshing after retry limit")

mods = fetch_with_refresh("https://api.reforgermods.net/v1/mods?search=radio")

When to poll the job URL

Poll Location only when you want to display progress, such as queued, running, or succeeded. After succeeded, request the original resource_url again. After failed, back off and retry the original URL later.

Why it works this wayThe API can answer instantly from cache, serve stale data while refreshing, and avoid making clients wait on Workshop latency.
Integration Guide