This prompt is designed for integration engineers who need to handle at-least-once webhook delivery semantics reliably. The core job is to analyze an incoming webhook payload against a history of previously processed events and produce a deterministic decision: process the event as new, skip it as a duplicate, or escalate it for human review when the evidence is ambiguous. You should use this prompt when your webhook consumer cannot rely solely on idempotency keys provided by the sender, or when you need a secondary deduplication layer that fingerprints the payload content itself to catch replay attacks, retries with lost headers, or events from systems that don't support idempotency keys at all.
Prompt
Duplicate Webhook Delivery Handling Prompt

When to Use This Prompt
Defines the job, reader, and constraints for detecting duplicate webhooks and producing an idempotent processing decision.
The ideal user is a backend or platform engineer embedding this prompt into a webhook ingestion pipeline. Required context includes the current payload, a set of recently processed event fingerprints (with timestamps), and a configurable similarity threshold. The prompt is not a replacement for database-level unique constraints or idempotency-key storage—it is a decision-support layer that handles edge cases those simpler mechanisms miss, such as near-duplicate payloads with minor timestamp drift, reordered delivery where a duplicate arrives before the original is fully committed, or partial payload changes that suggest a legitimate update rather than a retry. Do not use this prompt for real-time financial settlement or safety-critical actuation where deterministic, auditable logic is required without model inference.
Before wiring this prompt into production, define your fingerprinting strategy: which fields contribute to the fingerprint, whether you normalize timestamps, and how you handle nested objects. The prompt works best when paired with a fast pre-filter that eliminates obvious non-duplicates before invoking the model. After the model returns a decision, your application layer must enforce the action—the prompt advises, but your code commits the idempotent write. For high-throughput systems, batch recent fingerprints into the context window and set a strict time-bound on the lookback window to keep latency predictable.
Use Case Fit
Where this prompt works, where it fails, and what inputs it assumes for duplicate webhook delivery handling.
Good Fit: At-Least-Once Delivery Systems
Use when: your system receives webhooks from providers that guarantee at-least-once delivery (Stripe, Shopify, GitHub). The prompt excels at fingerprinting payloads to detect duplicates that arrive out of order or with slight timestamp drift. Guardrail: Always combine this prompt with a persistent idempotency store; the prompt decides the action, but your application must enforce the deduplication state.
Bad Fit: Exactly-Once or Ordered Protocols
Avoid when: your transport layer already guarantees exactly-once delivery or strict ordering (gRPC streaming, ordered message queues). The prompt adds unnecessary latency and complexity when the infrastructure handles deduplication. Guardrail: Use this prompt only at the application boundary where delivery guarantees are weak; do not insert it into already-reliable internal pathways.
Required Inputs: Payload Fingerprint Components
What the prompt needs: the raw webhook payload, the event type, an idempotency key (if provided by the sender), and a fingerprint strategy (hash of critical fields, event ID, or business key). Without a clear fingerprinting rule, the prompt cannot distinguish true duplicates from similar-but-distinct events. Guardrail: Define your fingerprinting fields in the prompt's [FINGERPRINT_STRATEGY] variable before deployment; never rely on the model to invent a strategy at runtime.
Operational Risk: False Duplicate Detection
What to watch: the prompt may classify two distinct events as duplicates if the fingerprinting strategy is too aggressive (e.g., hashing only the event type and customer ID while ignoring the actual change). This causes dropped events and silent data loss. Guardrail: Include a human-review escalation path for high-value events where the confidence score falls below 0.95, and log all deduplication decisions with the fingerprint hash for auditability.
Operational Risk: Missed Duplicates Under Payload Drift
What to watch: webhook providers may add or reorder fields between retries, causing the fingerprint to change and the duplicate to be processed twice. This is common with payment providers that enrich payloads on retry. Guardrail: Strip volatile fields (timestamps, request IDs, debug metadata) before fingerprinting, and test with real provider retry payloads—not just identical copies.
When to Escalate Instead of Decide
What to watch: the prompt should not make irreversible side-effect decisions (refunding a payment, sending a shipment) based solely on its duplicate classification. Guardrail: For high-risk event types, the prompt's output should be a recommendation that requires human approval or a secondary system check before execution. Mark these event types in the [ESCALATION_POLICY] variable.
Copy-Ready Prompt Template
A reusable prompt that fingerprints webhook payloads and decides whether to process, skip, or flag a delivery as a potential duplicate.
The prompt below is designed to be dropped into an idempotency decision harness. It receives a candidate webhook payload alongside a set of previously processed payload fingerprints and their outcomes. The model's job is not to execute the webhook logic but to produce a structured decision—process, skip, or review—along with a fingerprint and a concise rationale. This separation keeps the AI's role narrow and testable: it classifies duplication risk while your application code enforces the decision and handles side effects.
textYou are an idempotency decision engine for a webhook ingestion pipeline. Your task is to determine whether an incoming webhook delivery is a duplicate of a previously processed event. ## INPUT - Candidate payload: [CANDIDATE_PAYLOAD] - Previously processed fingerprints and outcomes: [PROCESSED_FINGERPRINTS] ## FINGERPRINTING RULES 1. Generate a fingerprint from the candidate payload using these fields in order of priority: [IDEMPOTENCY_KEY_FIELD], [EVENT_TYPE_FIELD], [TIMESTAMP_FIELD], [RESOURCE_ID_FIELD], [PAYLOAD_HASH_FIELDS]. 2. If [IDEMPOTENCY_KEY_FIELD] is present, use it as the primary fingerprint component. 3. If [IDEMPOTENCY_KEY_FIELD] is absent, construct the fingerprint from the remaining fields concatenated with a pipe delimiter. 4. Normalize timestamps to UTC ISO 8601 before fingerprinting. 5. Ignore fields listed in [IGNORE_FIELDS] when constructing the fingerprint. ## DECISION RULES - Return "process" if the fingerprint does not match any previously processed fingerprint. - Return "skip" if the fingerprint matches a previously processed fingerprint AND the prior outcome was "processed" or "skipped". - Return "review" if the fingerprint matches a previously processed fingerprint AND the prior outcome was "review" or "failed", OR if the candidate payload contains fields that differ materially from the matched prior payload beyond [IGNORE_FIELDS]. - Return "review" if the candidate payload timestamp is more than [MAX_CLOCK_SKEW_SECONDS] seconds behind the current time or ahead by more than [MAX_FUTURE_TOLERANCE_SECONDS] seconds. ## OUTPUT_SCHEMA Return a valid JSON object with exactly these fields: { "decision": "process" | "skip" | "review", "fingerprint": "string", "matched_fingerprint": "string | null", "rationale": "string (max 200 characters)", "confidence": "high" | "medium" | "low" } ## CONSTRAINTS - Do not invent payload fields. Use only fields present in the candidate payload. - If the payload is malformed or missing required fingerprinting fields, set decision to "review" and explain why in the rationale. - Do not execute any side effects. Only return the decision JSON. - If multiple prior fingerprints match, reference the most recent one in matched_fingerprint. ## EXAMPLES [EXAMPLES] ## RISK_LEVEL [RISK_LEVEL]
To adapt this template, replace the square-bracket placeholders with your webhook provider's actual field names and operational thresholds. [IDEMPOTENCY_KEY_FIELD] should point to the provider's native idempotency key if one exists (e.g., stripe.event.id or shopify.webhook.id). [PAYLOAD_HASH_FIELDS] defines which payload fields contribute to the fingerprint when no explicit key is present—choose fields that uniquely identify the business event, such as order_id plus event_type. [IGNORE_FIELDS] is critical for avoiding false duplicates caused by fields that change on every delivery, such as delivery_attempt, signature, or webhook_id. [MAX_CLOCK_SKEW_SECONDS] and [MAX_FUTURE_TOLERANCE_SECONDS] should reflect your system's tolerance for clock drift; 300 seconds (5 minutes) is a common starting point. [EXAMPLES] should include at least three few-shot demonstrations: a clear duplicate with matching idempotency key, a new event with no prior fingerprint match, and a timestamp-drift case that triggers review. [RISK_LEVEL] accepts low, medium, or high and should be set based on the downstream cost of duplicate processing—payment events warrant high and stricter review thresholds.
Before wiring this prompt into production, validate that the model consistently returns parseable JSON matching the output schema. Run it against a golden test set that includes exact duplicates, near-duplicates with ignored-field changes, reordered deliveries, and payloads with missing fingerprinting fields. If the model returns review for more than 5% of non-duplicate events in shadow mode, tighten the fingerprinting rules or expand [IGNORE_FIELDS]. For high-risk use cases, route all review decisions to a human operator or a dead-letter queue rather than auto-processing. Never use this prompt to make the final processing decision without application-layer enforcement of the returned decision.
Prompt Variables
Required inputs for the duplicate webhook delivery handling prompt. Each placeholder must be populated before the prompt is assembled and sent to the model.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[WEBHOOK_PAYLOAD] | The raw HTTP body of the incoming webhook delivery, including headers that carry idempotency keys or signatures. | {"event": "order.created", "order_id": "ord_987", "amount": 2999} | Must be valid JSON. Parse check required. Null or empty payload triggers immediate rejection before prompt assembly. |
[IDEMPOTENCY_KEY] | The client-supplied or provider-supplied key used to detect duplicate deliveries. May be extracted from a header like Idempotency-Key or computed from payload fingerprint. | key_abc123_2025-03-15T10:30:00Z | Must be non-empty string. If missing, fall back to [PAYLOAD_FINGERPRINT]. Validate format matches expected key schema (UUID, prefixed string, or timestamped key). |
[PAYLOAD_FINGERPRINT] | A deterministic hash of the payload content used for deduplication when no explicit idempotency key is provided. | sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 | Must be a hex-encoded SHA-256 string. Recompute from [WEBHOOK_PAYLOAD] before prompt assembly and verify match. Mismatch indicates payload corruption. |
[DELIVERY_TIMESTAMP] | The timestamp when this specific delivery attempt was received, used to detect reordered or delayed deliveries. | 2025-03-15T10:31:05.123Z | Must be ISO 8601 UTC. Parse check required. Compare against [PREVIOUS_DELIVERY_TIMESTAMPS] to detect out-of-order arrival. |
[PREVIOUS_DELIVERY_TIMESTAMPS] | Array of timestamps from prior deliveries with the same idempotency key or fingerprint, used to detect replay and reordering. | ["2025-03-15T10:30:58Z", "2025-03-15T10:30:42Z"] | Must be an array of ISO 8601 UTC strings, sorted ascending. Empty array allowed for first delivery. Null means no history available; treat as first delivery. |
[PROCESSING_STATE] | The current processing state for this idempotency key: null (unseen), 'processing', 'completed', or 'failed'. Retrieved from the idempotency store before prompt assembly. | completed | Must be one of: null, 'processing', 'completed', 'failed'. If 'completed', prompt should return cached result. If 'processing' and within timeout, prompt should return 'wait'. If 'failed', prompt should assess retryability. |
[CACHED_RESULT] | The previously stored result for this idempotency key when [PROCESSING_STATE] is 'completed'. Null otherwise. | {"status": "processed", "order_ref": "int_456"} | Must be valid JSON when [PROCESSING_STATE] is 'completed'. Null allowed otherwise. Schema must match expected output contract for the webhook handler. |
[RETRY_BUDGET_REMAINING] | Number of remaining retry attempts allowed before escalation. Prevents infinite retry loops on poison messages. | 3 | Must be a non-negative integer. If 0, prompt must produce an escalation decision, not a retry instruction. Validate against configured max retries before prompt assembly. |
Implementation Harness Notes
How to wire the duplicate webhook detection prompt into a production ingestion pipeline with validation, retry, and state storage.
The duplicate webhook delivery prompt is designed to sit inside a webhook ingestion handler, not as a standalone decision point. When a webhook arrives, the handler must first extract the raw payload, headers, and delivery timestamp before calling the model. The prompt expects a structured input containing the current payload, a set of recently processed payload fingerprints, and the idempotency window configuration. Because webhook providers often retry deliveries with slight payload variations (reordered fields, updated timestamps, or appended metadata), the handler should normalize the payload before fingerprinting—strip provider-specific envelope fields, sort JSON keys, and remove non-deterministic values like X-Request-Id headers that change across retries. The model's decision (process, skip, or quarantine) must be treated as advisory; the handler should enforce the final idempotency check against a durable state store, not rely solely on the model's classification.
Wire the prompt into a pipeline with three stages: pre-processing, model inference, and post-decision enforcement. In pre-processing, compute a content fingerprint (SHA-256 of the normalized payload) and a semantic fingerprint (key field hash, such as order_id + event_type). Query your state store for recent deliveries matching either fingerprint within the idempotency window. Pass the current payload, the list of candidate duplicates with their timestamps and fingerprint match types, and the window configuration into the prompt's [INPUT] placeholder. For model inference, use a fast, cost-effective model (GPT-4o-mini or Claude Haiku) with temperature=0 and response_format set to the JSON schema defined in the prompt template. Set a strict timeout of 2–3 seconds; if the model call fails or times out, fall back to a deterministic rule: skip if an exact content-fingerprint match exists within the window, otherwise process. Log every model decision alongside the fingerprint evidence for auditability.
Post-decision enforcement requires atomic state updates to prevent race conditions. When the model returns process, write the fingerprint to the state store using a conditional insert (e.g., DynamoDB attribute_not_exists or Redis SETNX) before executing the business logic. If the conditional write fails, another concurrent handler already processed a duplicate—log the collision and skip. When the model returns skip, verify that a matching fingerprint actually exists in the state store; if not, the model may have hallucinated a duplicate and you should escalate to quarantine. When the model returns quarantine, store the payload in a dead-letter queue with the model's reasoning and alert an on-call engineer. Implement a retry budget for model call failures: three attempts with exponential backoff (1s, 2s, 4s), then fall back to the deterministic rule. Never retry a quarantine decision—human review is required before reprocessing.
Validation and eval checks should run continuously against this pipeline. Instrument the handler to emit metrics: model latency, decision distribution (process/skip/quarantine), fallback rate, and fingerprint collision rate. Build a regression test suite with known duplicate scenarios: exact payload retry, reordered fields, timestamp drift within the window, timestamp drift outside the window, partial payload changes (e.g., updated status field on a retry), and concurrent deliveries with sub-second arrival gaps. For each test case, assert the final processing decision (not just the model's output) and verify that no duplicate side effects occur. Run these tests in CI on every prompt change. In production, sample 5% of skip decisions and replay the original payload through a shadow pipeline to confirm idempotency holds. If the shadow pipeline produces a different decision, flag the trace for review and consider tightening the fingerprinting strategy or adjusting the idempotency window.
Expected Output Contract
Fields, format, and validation rules for the idempotent processing decision returned by the Duplicate Webhook Delivery Handling Prompt. Use this contract to validate the model's output before taking action in your webhook handler.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
decision | enum: PROCESS | SKIP | REVIEW | Must be exactly one of the three allowed values. Reject any other string. | |
fingerprint | string (hex-encoded SHA-256) | Must match the fingerprint computed from the provided [PAYLOAD_FINGERPRINT] input. Reject if mismatch. | |
idempotency_key | string | Must match the [IDEMPOTENCY_KEY] from the incoming webhook. Reject if missing or altered. | |
confidence | number (0.0 to 1.0) | Must be a float between 0.0 and 1.0 inclusive. If confidence < 0.85 and decision is PROCESS, escalate to human review. | |
reasoning | string | Must be non-empty and reference at least one of: fingerprint match, timestamp comparison, payload hash, or event ID lookup. Reject if empty or generic. | |
conflict_detail | object or null | If decision is REVIEW, this field is required and must contain 'conflict_type' and 'existing_event_id' keys. If decision is PROCESS or SKIP, null is allowed. | |
retry_after_seconds | integer or null | If decision is REVIEW, provide a suggested retry delay. Must be a positive integer. If decision is PROCESS or SKIP, null is allowed. | |
cache_ttl_seconds | integer | Suggested time-to-live for caching this decision. Must be a positive integer. Default to 86400 if not specified, but reject if negative or zero. |
Common Failure Modes
What breaks first when handling duplicate webhooks in production and how to guard against it.
Fingerprint Collision from Normalized Payloads
What to watch: The prompt generates the same fingerprint for legitimately different events after whitespace normalization or key sorting, causing false deduplication. Guardrail: Include raw payload bytes or a canonical checksum in the fingerprint input, and test with semantically identical but structurally different payloads.
Timestamp Drift Masks True Duplicates
What to watch: Replayed or delayed deliveries arrive with significantly different timestamps, causing the model to treat them as distinct events. Guardrail: Explicitly instruct the model to ignore timestamp fields when computing fingerprints, and use a separate freshness check for staleness decisions.
Partial Payload Changes Evade Detection
What to watch: A retry delivery includes updated metadata or a new retry_count field, altering the fingerprint and bypassing deduplication. Guardrail: Define an explicit set of idempotency fields in the prompt and instruct the model to exclude transport-layer metadata from the fingerprint computation.
Idempotency Key Absence Causes Silent Duplicates
What to watch: The webhook sender does not include a standard idempotency key, forcing the model to rely solely on payload fingerprinting, which is fragile. Guardrail: Add a pre-processing step that checks for an Idempotency-Key header first, and only fall back to the prompt-based fingerprinting when the header is missing.
Reordered Delivery Breaks Sequence-Dependent Logic
What to watch: Events arrive out of order, and the prompt incorrectly classifies a late-arriving earlier event as a duplicate of a later event. Guardrail: Include a sequence number or event version in the prompt context and instruct the model to use it for ordering decisions, not just duplicate detection.
Model Hallucinates a Processing Decision
What to watch: In edge cases with ambiguous payloads, the model invents a processing action not grounded in the provided rules. Guardrail: Constrain the output to a strict enum of allowed decisions (process, skip, escalate) and validate the response against this schema before executing any side effects.
Evaluation Rubric
Test cases to validate the duplicate webhook detection prompt before production deployment. Each row targets a specific failure mode: reordered delivery, timestamp drift, or partial payload changes.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Identical payload, same [EVENT_ID] | Outputs | Outputs | Send same payload twice with identical [EVENT_ID] and [TIMESTAMP]; check decision field |
Reordered delivery (older event arrives after newer) | Outputs | Outputs | Send event with [TIMESTAMP] T2 first, then event with [TIMESTAMP] T1 (T1 < T2) for same [IDEMPOTENCY_KEY]; verify older event is discarded |
Timestamp drift (clock skew > 30s between producer and consumer) | Outputs | Outputs | Send event with [TIMESTAMP] skewed 60s behind system clock but unique [EVENT_ID]; check that decision is new with skew warning |
Partial payload change (same [EVENT_ID], different [PAYLOAD_HASH]) | Outputs | Outputs | Send first payload with [EVENT_ID] X and [PAYLOAD_HASH] A, then resend [EVENT_ID] X with [PAYLOAD_HASH] B; verify conflict escalation |
Missing [IDEMPOTENCY_KEY] in incoming webhook | Outputs | Outputs | Send payload with [EVENT_ID] present but [IDEMPOTENCY_KEY] null or absent; check error decision and reject action |
Duplicate [EVENT_ID] with identical [PAYLOAD_HASH] after 24-hour retention window | Outputs | Always outputs | Send duplicate after configured [RETENTION_WINDOW_HOURS] + 1 hour; verify new decision with expiry warning |
Concurrent delivery (two identical events arrive within 100ms) | Exactly one event outputs | Both events output | Fire two identical webhook deliveries with same [EVENT_ID] simultaneously within 100ms; verify exactly one is processed |
Empty or null [PAYLOAD_HASH] | Outputs | Outputs | Send payload with [PAYLOAD_HASH] set to empty string or null; check rejection |
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
Add canonicalization before fingerprinting: normalize timestamps to a tolerance window, strip transport-level headers, and extract only business-significant fields. Include idempotency key from the [IDEMPOTENCY_HEADER] if present. Add a processed-event cache with TTL and require the model to explain its decision.
Prompt modification
codeYou are a webhook deduplication engine. Analyze the incoming webhook against the processed-event cache and idempotency store. Input: - Incoming payload (canonicalized): [CANONICALIZED_PAYLOAD] - Idempotency key from header: [IDEMPOTENCY_KEY] - Processed event cache (fingerprint → status): [EVENT_CACHE] - Max clock skew tolerance: [CLOCK_SKEW_MS]ms Determine: 1. Is this a duplicate by idempotency key? 2. Is this a duplicate by payload fingerprint? 3. Is this a reordered delivery (earlier event arriving late)? Return JSON: { "decision": "process" | "skip" | "quarantine", "duplicate_by": "key" | "fingerprint" | "none", "reordered": boolean, "reasoning": string, "cache_update": {"fingerprint": string, "status": string, "ttl_seconds": number} }
Watch for
- Timestamp normalization stripping meaningful sequence information
- Cache poisoning if an attacker replays with modified nonce fields
- Silent format drift when upstream webhook providers change payload shape

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