Idempotent Form Submission
Make one submit mean one result, even when the network retries.
What it adds
Idempotency keys on high-impact writes so a double-click, a retry, or a refresh cannot create the same record twice.
What your agent is told to do
5
What your agent is told to do
5-
1
Find the writes where a duplicate is expensive — payments, orders, invitations, provisioning, anything that sends money or email.
-
2
Generate an idempotency key when the form is rendered, send it with the submission, and persist it server-side alongside the result of the first successful attempt.
-
3
When the same key arrives again, return the stored result instead of doing the work a second time. When the same key arrives with a different payload, reject it — that is a client bug, not a retry.
-
4
Also disable the submit control while a request is in flight and show a pending state, so the common case never reaches the server twice.
-
5
Do NOT treat the disabled button as the protection. It only covers one browser tab; the endpoint is still reachable directly, from a retry, or from a second device. The server-side key is the actual guarantee.
Edge cases it handles
6
Edge cases it handles
6- The key must survive a page refresh and a browser back-navigation, or the user gets a fresh key and a second record.
- The client can time out after the server has already committed. The retry must find the stored result, not start over.
- Two requests with the same key arriving concurrently must not both proceed — hold a lock or a unique constraint on the key.
- Keys must expire, but not so quickly that a slow retry slips through as a new write.
- A failed attempt must not burn the key permanently; the user should be able to fix the input and submit again.
- Do not key on the payload hash alone — two genuinely intended identical submissions are legal and must both go through.
Definition of done
8
Definition of done
8- Every high-impact write accepts and requires an idempotency key.
- A repeated key returns the original result and performs no second write.
- A repeated key with a changed payload is rejected with a clear error.
- Submit controls disable during flight and show a pending state.
- Concurrent duplicate requests resolve to exactly one record.
- Key expiry is a documented, deliberate window.
- The feature matches the existing design system.
- No existing functionality is broken.
Related features
Password Generator
Password Generator
Offer a strong password in one click wherever someone sets or changes credentials.
What it does
A generate control on password fields that produces a strong value, shows it, and hands it to the user safely.
How it works
- 1 Add the control to every place a password is set: sign-up, password change, password reset completion, and any admin screen that provisions credentials for someone else.
- 2 Generate the value in the browser using the platform's cryptographic random source. The value must never be produced on the server or sent anywhere.
- 3 Reveal the generated password by default so the user can record it, and offer a regenerate control beside it. A hidden generated password that the user cannot see is a password they will immediately reset.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/password-generator
Rate Limiting
Rate Limiting
Stop one client from ruining it for everyone.
What it does
Throttling on the endpoints that get abused: auth, search, exports, and public forms.
How it works
- 1 Identify the endpoints worth protecting: sign-in, sign-up, password reset, search, exports, and anything unauthenticated.
- 2 Limit by a stable identifier — user ID where signed in, IP otherwise. Be aware IP is shared behind NAT and proxies.
- 3 Return 429 with a Retry-After header. Do not silently drop the request.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/rate-limiting
Client Version Compatibility
Client Version Compatibility
Handle the tab that has been open since two deploys ago.
What it does
The server tells the client which build it expects, and the client responds — quietly for an optional update, insistently when the old code can no longer talk to the API.
How it works
- 1 Stamp every build with a version identifier and return it on API responses, either in a header or a small metadata endpoint. The client compares it against the version it was built as.
- 2 Separate two cases and treat them differently. A newer build being available is an optional update — offer it and let the user finish what they are doing. An API contract the running client cannot satisfy is a hard incompatibility and must block further writes.
- 3 For an optional update, show an unobtrusive, dismissible prompt and apply the new version at the next natural navigation. Do not interrupt.
Copy the prompt
No account needed
Add this feature to my app:
https://addthisfeature.com/x/client-version-compatibility
How it works
-
1
Copy the link
Grab the Markdown instruction URL for this feature.
-
2
Give it to your AI
Paste it into Claude Code, Cursor, v0, Lovable — whatever you build with.
-
3
It inspects, then implements
Your agent reads your existing app first, then adds the feature to fit it.
Works with your stack
These instructions are written to adapt. They tell the agent to detect your framework, match your existing design system, and reuse what you already have — rather than assuming a particular stack.
Need it tighter than that? Customize the feature and tell it exactly what you're running.