For POST requests, the client generates a unique key (Idempotency-Key: uuid) and sends it in a header. The server stores the result under that key: if the same request arrives again, it returns the stored result without reprocessing. Stripe, Twilio, and other payment APIs require this.
A worker must be prepared to receive the same message twice (at-least-once delivery). Store processed IDs and check before processing.