01 · Before and afterThe pattern
// order matters: identity of the request first, then its progress
const row = await keys.find(userId, key);
if (!row) return claimAndRun();
if (row.fingerprint !== hash(method, path, body)) return reply(422); // different request, same key
if (row.status === 'processing') return reply(409); // same request, still running
return replay(row.responseStatus, decrypt(row.responseBody)); // same request, done02 · Run it on your appThe check
If your API stores responses for replay, are they encrypted or redacted at rest, and is the response size bounded?
If the honest answer is no or not sure, this is worth a look before it reaches production.