Inferensys

Prompt

Idempotency Acceptance Criteria Prompt

A practical prompt playbook for generating executable Gherkin acceptance criteria that verify safe-retry behavior, idempotency-key lifecycle, and concurrent request handling in state-changing endpoints.
Developer doing prompt engineering on laptop, prompt variations visible on screen, casual coding session.
PROMPT PLAYBOOK

When to Use This Prompt

Define the job, reader, and constraints for generating idempotency acceptance criteria.

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.

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.

PRACTICAL GUARDRAILS

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.

01

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.

02

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.

03

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.

04

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.

05

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.

06

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.

PROMPT PLAYBOOK

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.

text
You 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.

IMPLEMENTATION TABLE

Prompt Variables

Required inputs for the Idempotency Acceptance Criteria Prompt. Each placeholder must be populated before the prompt can produce reliable Gherkin scenarios.

PlaceholderPurposeExampleValidation 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.

PROMPT PLAYBOOK

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.

IMPLEMENTATION TABLE

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 ElementType or FormatRequiredValidation 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.

PRACTICAL GUARDRAILS

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.

01

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.

02

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.

03

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.

04

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.

05

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.

06

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.

IMPLEMENTATION TABLE

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.

CriterionPass StandardFailure SignalTest 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

ADAPTATION OPTIONS

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
Prasad Kumkar

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.