I assume every POST will fail once. The client keeps a local queue with a unique operation id. The server treats that id as a unique key. Retry becomes a no-op instead of a duplicate receipt.
This is dull. It is also the difference between a tool people trust in aisle 7 and a tool they only use near the office AP.
Timeouts are part of the contract
A hang is worse than a fast failure. I fail, show queued, and let them keep working. Sync when the radio comes back.
Do not retry the unsafe
A "decrement inventory" without an idempotency key should not auto-retry. A "save this photo" should. Classify your writes.