An operation that takes ninety seconds does not fit in a request, and holding the connection open converts every timeout in the chain into a failure mode.
POST /api/exports
→ 202 Accepted
Location: /api/exports/9c1f4a7e
Retry-After: 5
GET /api/exports/9c1f4a7e
→ 200 { "state": "running", "progress": 0.4 }
→ 303 See Other
Location: /api/exports/9c1f4a7e/download
The 202 says the request was accepted and not that the work is done, which is exactly the distinction a long operation needs. Retry-After tells a client how often to poll rather than leaving it to guess, and clients guess badly in both directions. The status resource should outlive the job by long enough for a client that crashed to come back and find out what happened, which means it is a stored record rather than a queue lookup.