This prompt is for integration test engineers and backend developers who need to translate an API's idempotency requirements into verifiable, automation-ready Gherkin scenarios. The core job-to-be-done is taking a technical specification—often a single sentence like 'the payment endpoint must be idempotent'—and expanding it into a comprehensive set of behavior contracts that cover duplicate requests, concurrent submissions, key lifecycle, and collision handling. The ideal user has access to the API specification, the idempotency key header name, and any known business rules around key expiration or scope (e.g., per-account vs. global). Without this context, the prompt will produce generic scenarios that miss critical implementation details.
Prompt
Idempotency Acceptance Criteria Prompt

When to Use This Prompt
Define the job, reader, and constraints for generating idempotency acceptance criteria.
Use this prompt when you are building integration tests for any state-changing endpoint where a retried request must not produce a duplicate side effect. This includes payment capture, order creation, ledger entries, and resource provisioning. The prompt is designed to produce Gherkin feature files that can be directly fed into BDD frameworks like Cucumber or SpecFlow. It is not suitable for read-only endpoints, fire-and-forget operations where duplicates are acceptable, or workflows that rely on external transactional guarantees without an idempotency key. Do not use this prompt if you are looking for a general explanation of idempotency; it assumes the reader already understands the concept and needs executable specifications.
Before running this prompt, gather the exact idempotency key header name, the key's scope (e.g., per merchant, per account, or global), the documented or intended expiration window, and any known collision behavior. The output will include scenarios for the happy path (first request accepted, duplicate returned with original result), concurrent submissions, key reuse after expiration, missing or malformed keys, and cross-scope collision attempts. After generating the scenarios, you must validate them against the actual API implementation—this prompt produces a starting point for test design, not a replacement for exploratory testing against the real system. Pay special attention to the [IDEMPOTENCY_KEY_EXPIRATION] and [KEY_SCOPE] placeholders; if you leave them unresolved, the generated scenarios will contain vague assertions that cannot be verified.
Use Case Fit
Where this prompt works and where it does not. Use these cards to decide if the Idempotency Acceptance Criteria Prompt fits your current testing workflow.
Good Fit: API Endpoints with Side Effects
Use when: you are testing POST, PUT, PATCH, or DELETE endpoints where duplicate requests could cause double charges, duplicate records, or corrupted state. Guardrail: The prompt is designed to generate scenarios around idempotency-key lifecycle, not read-only GET requests.
Bad Fit: Purely Read-Only Operations
Avoid when: testing GET endpoints or read-only queries that have no side effects. Guardrail: The prompt will produce irrelevant scenarios about state changes where none exist. Use a standard API contract test prompt instead.
Required Input: Idempotency Key Specification
What to watch: The prompt needs explicit rules for key scope, expiration, and collision behavior. Guardrail: Provide your API's idempotency documentation as [CONTEXT]. Without it, the model will invent plausible but incorrect key-handling rules that don't match your implementation.
Required Input: Concurrency Model
What to watch: Duplicate requests and concurrent submissions require understanding of your locking or serialization strategy. Guardrail: Include details on whether your system uses pessimistic locking, optimistic concurrency control, or distributed locks in the [CONTEXT] to generate accurate race-condition scenarios.
Operational Risk: Key Expiration Blind Spots
What to watch: The prompt may not surface scenarios for keys that expire between the first request and a retry. Guardrail: Explicitly request scenarios covering key expiration boundaries, storage cleanup, and replay attacks with expired keys. Add these as explicit [CONSTRAINTS] in the prompt template.
Operational Risk: Downstream Non-Idempotency
What to watch: Your API may be idempotent, but downstream services (payment processors, databases, queues) might not be. Guardrail: Extend the prompt's scope to include integration-layer scenarios. Add [CONSTRAINTS] requiring scenarios that verify idempotency across the full request chain, not just the entry point.
Copy-Ready Prompt Template
A reusable prompt template for generating idempotency acceptance criteria and Gherkin scenarios from API specifications and system design documents.
This prompt template translates technical specifications for idempotent operations—such as payment endpoints, order creation, or any state-changing API—into executable Gherkin scenarios. It is designed to be copied directly into your prompt library or AI harness, with square-bracket placeholders that your application layer should populate before sending the request to the model. The template forces the model to reason about the full idempotency-key lifecycle: creation, storage, validation, expiration, collision handling, and concurrent request behavior.
textYou are a senior integration test engineer specializing in API reliability and safe-retry patterns. Your task is to generate executable Gherkin acceptance criteria for idempotent behavior based on the provided API specification and system design context. ## INPUT [API_SPECIFICATION] [IDEMPOTENCY_DESIGN_DOC] ## CONSTRAINTS - Generate only Gherkin scenarios with Given-When-Then structure. - Cover the full idempotency-key lifecycle: first request, duplicate request, concurrent requests, key expiration, key collision, and cross-client key isolation. - Include explicit examples tables for request payloads, idempotency keys, and expected responses. - For each scenario, specify the expected HTTP status code, response body shape, and any side-effect guarantees (e.g., exactly-one execution). - Flag any scenario where the specification is ambiguous and state the assumption you made. - Do not invent API behavior not present in the input documents. ## OUTPUT_SCHEMA Return a JSON object with the following structure: { "scenarios": [ { "id": "string", "name": "string", "category": "first-request | duplicate-request | concurrent-request | key-expiration | key-collision | cross-client-isolation | key-reuse", "gherkin": "string (multi-line Gherkin with Given, When, Then)", "examples_table": [ { "columns": ["string"], "rows": [["string"]] } ], "expected_status": 200, "expected_response_shape": {}, "side_effect_guarantee": "string", "assumptions": ["string"] } ], "coverage_gaps": ["string (categories or edge cases not addressed by the input documents)"], "ambiguities_flagged": ["string (specification points that require clarification before implementation)"] } ## EXAMPLES Example scenario structure: { "id": "IDEM-001", "name": "Duplicate request with same idempotency key returns stored result", "category": "duplicate-request", "gherkin": "Given a payment endpoint \"POST /payments\"\nAnd a valid idempotency key \"idem-abc123\" was used in a successful request that returned status 201 with body {\"id\": \"pay-001\", \"status\": \"succeeded\"}\nWhen a second request is sent with the same idempotency key \"idem-abc123\" and identical body\nThen the response status is 200\nAnd the response body matches the original response {\"id\": \"pay-001\", \"status\": \"succeeded\"}\nAnd no new payment is created", "examples_table": [ { "columns": ["Request", "Idempotency-Key", "Expected Status", "Expected Body"], "rows": [ ["POST /payments {\"amount\": 100}", "idem-abc123", "201", "{\"id\": \"pay-001\"}"], ["POST /payments {\"amount\": 100}", "idem-abc123", "200", "{\"id\": \"pay-001\"}"] ] } ], "expected_status": 200, "expected_response_shape": {"id": "string", "status": "string"}, "side_effect_guarantee": "No duplicate payment created; original result returned unchanged.", "assumptions": ["Idempotency key storage duration exceeds the retry window."] } ## RISK_LEVEL [RISK_LEVEL]
To adapt this template, replace [API_SPECIFICATION] with your OpenAPI spec, endpoint documentation, or a plain-text description of the endpoint's request and response contracts. Replace [IDEMPOTENCY_DESIGN_DOC] with your team's design decisions around key storage, expiration policy, collision strategy, and scope (per-account, per-endpoint, or global). The [RISK_LEVEL] placeholder should be set to high for payment or financial operations—this signals the model to apply stricter validation and flag more edge cases. If your application needs a different output format, modify OUTPUT_SCHEMA before injecting the prompt. Always validate the model's output against the schema before accepting it into your test management system.
Prompt Variables
Required inputs for the Idempotency Acceptance Criteria Prompt. Each placeholder must be populated before the prompt can produce reliable Gherkin scenarios.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[ENDPOINT_SPEC] | The API endpoint definition including method, path, and request body schema | POST /v1/payments { amount, currency, source } | Must include HTTP method and path. Schema fields must be named. Reject if only a URL is provided. |
[IDEMPOTENCY_MECHANISM] | Description of how idempotency is implemented: key header name, storage, and expiration policy | Idempotency-Key header, stored in Redis with 24h TTL, scoped per merchant account | Must specify key location (header, body field), storage type, and TTL. Reject if TTL is missing. |
[STATE_CHANGE_DESCRIPTION] | Narrative or structured description of the side effects the endpoint produces on success | Creates a payment resource, deducts balance, emits PaymentCreated event | Must list all persistent side effects. Reject if only HTTP status codes are described. |
[CONCURRENCY_MODEL] | How the system handles overlapping requests: locking strategy, isolation level, or queue behavior | Optimistic locking on account row; second concurrent request receives 409 Conflict | Must describe behavior for simultaneous requests with same key. Reject if 'not handled' with no explicit error contract. |
[KEY_SCOPE_RULES] | Rules defining the uniqueness boundary for idempotency keys | Key is scoped to merchant_id + endpoint; same key on different merchants is independent | Must define scope dimensions (account, endpoint, resource type). Reject if scope is undefined. |
[ERROR_CONTRACT] | Existing error response schema for conflict, expiration, and malformed key scenarios | 409 body: { error: 'idempotency_conflict', existing_resource_id, status } | Must include response body fields for each error case. Reject if only HTTP status codes are listed. |
[KEY_LIFECYCLE_RULES] | Rules for key reuse after success, expiration, and manual deletion | Key cannot be reused after successful response; returns 409 with original result on replay | Must specify post-success behavior and post-expiration behavior. Reject if lifecycle is incomplete. |
Implementation Harness Notes
How to wire the idempotency acceptance criteria prompt into a CI pipeline, test generation service, or manual QA workflow.
This prompt is designed to be called programmatically as part of a test asset generation pipeline. The primary input is a structured API specification (OpenAPI, gRPC proto, or a plain-text endpoint description) and the target idempotency strategy (e.g., Idempotency-Key header, token-based, or payload hash). The output is a set of Gherkin feature files. To integrate this, wrap the prompt in a thin service that accepts an API spec and a strategy type, injects them into the [API_SPECIFICATION] and [IDEMPOTENCY_STRATEGY] placeholders, and calls the LLM. The service should enforce a strict output contract: the response must contain only the Gherkin text block, or a parseable JSON object with a scenarios array if you modify the template to request structured output.
Before the generated .feature files land in your test repository, implement a validation gate. A lightweight parser should verify that every scenario contains the mandatory tags (@idempotency, @safe-retry, @concurrent), that Given steps reference a known initial state (e.g., 'a payment with ID X does not exist'), and that Then steps assert on the exact resource state, not just HTTP status codes. For high-risk domains like payment processing, add a human review step in your CI pipeline: if the prompt generates a new scenario involving a 409 Conflict or a key-collision case, flag it for a senior engineer to confirm the expected behavior before the test is merged. Log the prompt version, model, and input hash alongside the generated scenarios to enable traceability when a test fails in production and you need to determine if the failure is a spec bug or a generation artifact.
For retry and error handling, configure your harness to call the LLM with a temperature of 0.0 to maximize determinism. If the output fails validation (e.g., a missing Scenario Outline for a parameterized test), do not silently discard it. Instead, feed the raw output and the validator error message into a repair prompt that asks the model to fix the specific structural issue. Limit this repair loop to a single retry to avoid infinite correction cycles. Finally, treat the generated Gherkin as a starting point, not a finished test suite. The harness should append a comment header to each .feature file noting the generation date, the source API spec version, and a warning that human review is required before the test gates a release.
Expected Output Contract
Defines the required fields, types, and validation rules for the structured output of the Idempotency Acceptance Criteria Prompt. Use this contract to build a parser or validator in your test harness.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
feature_name | String | Must match the pattern 'Idempotency: [API Endpoint or Operation Name]'. Non-conforming strings should trigger a format warning. | |
scenarios | Array of Objects | Array must contain at least one object. An empty array is a failure signal indicating the model could not derive any scenarios. | |
scenarios[].name | String | Must be a non-empty string summarizing the scenario, e.g., 'Duplicate POST with same idempotency key'. Null or empty strings are invalid. | |
scenarios[].gherkin | String | Must be a valid multi-line string containing Given/When/Then steps. Validate that it starts with a Gherkin keyword (Given, When, Then, And, But). | |
scenarios[].idempotency_key_lifecycle | String | Must be one of the enum values: 'new', 'reused', 'expired', 'missing', 'malformed'. Any other value is a schema violation. | |
scenarios[].concurrent_safety | String | If present, must be one of: 'safe', 'race_condition_risk', 'duplicate_processing_risk'. Null is acceptable if the scenario does not involve concurrency. | |
scenarios[].expected_http_status | Integer | Must be a valid HTTP status code (200, 201, 409, 422, 500). A non-integer or out-of-range value should fail validation. | |
scenarios[].expected_response_body_checks | Array of Strings | Each string must be a concrete, verifiable assertion (e.g., 'response.id is identical to the original request'). An empty array signals a missing output contract. |
Common Failure Modes
Idempotency acceptance criteria are precise but fragile. These are the most common ways they break in production and how to catch them before they reach the test suite.
Key Lifecycle Gaps
What to watch: The prompt omits scenarios for key expiration, reuse after success, or key collision across clients. The resulting Gherkin only covers the happy path of a fresh key. Guardrail: Add a pre-generation checklist that forces explicit coverage of key creation, storage, expiry, and post-success rejection before scenario generation begins.
Concurrency Blind Spots
What to watch: Scenarios treat duplicate requests as sequential, missing the case where two requests with the same key arrive simultaneously before either completes. The spec passes in tests but fails under load. Guardrail: Require at least one scenario with an explicit When two concurrent requests arrive clause and a defined locking or atomicity expectation in the output schema.
Scope Ambiguity
What to watch: The prompt does not force the model to define whether idempotency is scoped per-resource, per-account, or globally. Scenarios mix scopes or default to an unstated assumption. Guardrail: Add a required [IDEMPOTENCY_SCOPE] input field and validate that every generated scenario references the correct scope boundary in its preconditions.
Response Differentiation Failure
What to watch: The spec treats all idempotent retries as returning identical responses, ignoring cases where the system must distinguish 'original success' from 'replayed success' via headers or status codes. Guardrail: Include a constraint that each scenario must assert on the Idempotency-Replayed header or equivalent signal, and flag scenarios that only check the body.
Error State Omission
What to watch: The prompt focuses on success retries and neglects idempotency behavior when the first request failed with a non-retryable error. The spec is silent on whether a failed request consumes the key. Guardrail: Require at least one scenario per terminal error code that asserts whether the key remains valid for a subsequent retry or is consumed by the failure.
Payload Mismatch Assumption
What to watch: The spec assumes retries carry identical payloads. In production, clients may resend with a different body under the same key. The prompt does not generate scenarios for this mismatch. Guardrail: Add a mandatory scenario that sends a different request body with a reused key and asserts either rejection or idempotent handling of the original payload only.
Evaluation Rubric
Use this rubric to evaluate the quality of generated idempotency acceptance criteria before integrating them into your test suite. Each criterion targets a specific failure mode common in safe-retry specifications.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Idempotency-Key Lifecycle Coverage | Scenarios cover key generation, submission, validation, expiration, and reuse prohibition | Missing scenarios for key expiration or reuse after successful completion | Count distinct lifecycle phases in generated Gherkin; expect >= 4 phases covered |
Concurrent Request Handling | At least one scenario specifies behavior for two requests with the same key arriving simultaneously | No scenario mentions concurrency, race conditions, or locking | Keyword search for 'concurrent', 'simultaneous', 'race', or 'parallel' in scenario descriptions |
Duplicate Request Idempotency | Duplicate request with same key returns the original response, not a new side effect | Scenario describes duplicate as creating a new resource or returning a different status code | Check response body and status code assertions in duplicate-request scenarios match original-response assertions |
Key Collision Handling | Scenarios define behavior when two different requests accidentally share an idempotency key | No scenario addresses key uniqueness or collision detection | Search for scenarios where key is reused with different request payload; expect 409 Conflict or equivalent |
Key Expiration and Cleanup | Scenarios specify what happens after key TTL expires: rejection, new key required, or re-acceptance | No mention of key expiration time, storage duration, or cleanup policy | Look for time-bound preconditions in Gherkin 'Given' steps referencing key age or expiry |
Error Response on Replay Mismatch | Scenarios define error response when a replayed request body differs from the original | Replay scenario assumes success or ignores payload mismatch | Check 'Then' steps for 422 Unprocessable Entity or equivalent error with mismatch detail |
Scope and Isolation | Scenarios clarify whether idempotency scope is per-resource, per-account, or global | No scope declaration; key behavior is ambiguous across resources or tenants | Verify 'Given' steps include resource or tenant context; check for cross-scope key reuse scenarios |
Observability and Logging Signals | Scenarios assert that idempotency hits, misses, and conflicts produce distinct log or metric signals | No assertions about logging, metrics, or trace headers in any scenario | Search for 'log', 'metric', 'trace', or 'observability' in scenario steps or notes |
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Adapt This Prompt
How to adapt
Use the base prompt with a single idempotency scenario and lighter validation. Focus on the happy path: same key, same response. Skip key expiration, concurrent submissions, and collision handling initially.
Simplify the output schema to require only the Gherkin scenario body without the full metadata wrapper. Remove the idempotency_key_lifecycle_stages and collision_handling sections from [OUTPUT_SCHEMA].
Watch for
- Scenarios that only test duplicate requests arriving sequentially, missing concurrent overlap
- Missing negative cases for key reuse after success
- Overly broad
[CONSTRAINTS]that produce generic retry scenarios instead of idempotency-specific behavior

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us