n8n API reliability

How to Retry Failed n8n API Requests Without Creating Duplicates

A timeout can hide a successful order, lead, payment, or message. Use one stable operation key, retry only temporary failures, and record the outcome before the workflow tries again.

Small business operator reviewing a failed request, delayed retry, duplicate guard, and successful API result

The safe n8n retry pattern is simple: create one stable idempotency key for the business operation, send the same key and payload on every attempt, retry only temporary failures, and store the confirmed result. Turning on Retry On Fail without that protection can repeat a successful side effect when the first response was lost.

The dangerous case: an API creates the order, but the connection closes before n8n receives the response. n8n sees a timeout. A second POST with a new key can create a second order even though the first request actually worked.

Decide whether the request is safe to repeat

HTTP defines GET, HEAD, OPTIONS, and TRACE as safe methods. PUT, DELETE, and the safe methods are idempotent by their intended semantics. POST is not automatically idempotent. The HTTP specification therefore says a client should not automatically retry a non-idempotent request unless it knows the operation is idempotent or can prove the first request was not applied.

Real APIs add their own rules, so the provider's documentation remains the contract. A DELETE endpoint may be harmless to repeat, while a POST that sends an email, creates a payment, or reserves stock needs explicit duplicate protection.

Failure Default action Duplicate risk
Network timeout or reset Retry the identical request with the same operation key High, because the remote service may already have committed the action
429 Too Many Requests Wait for the provider's limit window, then retry Controlled only if the operation remains idempotent
500, 502, 503, or 504 Use a small bounded retry policy when the provider permits it Potentially high for state-changing requests
400, 401, 403, or most 404s Fix the request, credentials, permission, or resource first Blind retries add load but rarely fix the cause
409 Conflict Inspect the API-specific error before deciding May indicate an existing operation or key conflict

Step 1: create one key for one business operation

Build the key before the HTTP Request node from an ID that already belongs to the event: an order ID, checkout ID, lead ID, invoice ID, or source event ID. Include the action name so different operations on the same record cannot collide.

={{ 'create-order:' + $json.orderId }}

Keep this value unchanged across automatic node retries, manual execution retries, and later recovery runs. Do not use $now, the execution ID, or a freshly generated random value on each attempt. Those identify the attempt, not the operation, so the destination sees every retry as new work.

The key must also stay paired with the same endpoint and payload. If you correct the amount, recipient, or other business data, treat that as a deliberate new operation according to the provider's rules.

Step 2: use the API's idempotency feature first

If the destination API supports idempotency, send the stable key in the exact header or field its documentation specifies. Stripe, for example, accepts an Idempotency-Key header for POST requests and returns the stored result when the same request is repeated with the same key. That header name is not universal. Some APIs use a request ID, client reference, deduplication ID, or a provider-specific field.

  1. Open the HTTP Request node and add the provider's documented idempotency header.
  2. Map the stable operation key as its value.
  3. Keep the method, URL, and request body identical on every retry.
  4. Save the external object ID from the confirmed response for later reconciliation.

Do not assume: adding an Idempotency-Key header only works when the destination implements that contract. An unknown header may simply be ignored.

Step 3: configure a bounded n8n retry

Every n8n node has a Retry On Fail setting. When enabled, n8n reruns the node after a failure until it succeeds or reaches the configured attempt limit. For a known transient endpoint, start with a small policy such as three tries and a short wait between tries. Increase it only when the provider's limit and incident behavior justify the extra traffic.

This built-in setting is best when every error produced by that node is safe to retry. If you need status-aware behavior, enable Include Response Headers and Status and Never Error in the HTTP Request node. The node can then pass the status code and headers to an IF or Switch branch instead of stopping on every non-2xx response.

Step 4: slow down 429 retries

A 429 response means the client sent too many requests in the provider's current limit window. Some APIs include Retry-After as seconds or an HTTP date. Read and honor it when the provider documents that behavior. If the header is absent, use the API's published limit and increase the delay between attempts rather than retrying immediately.

The HTTP Request node also has Items per Batch and Batch Interval options. They control how many input items are sent in each batch and how many milliseconds n8n waits between batches. Use them to prevent a known burst from creating the 429 in the first place.

Step 5: add a persistent duplicate check when needed

When the API has no idempotency feature, keep a small request ledger. n8n's Data Table node can check whether a row exists, insert rows, update them, and upsert by conditions. A practical table uses these columns:

Column Purpose
request_key Stable ID for the business operation
status pending, succeeded, failed, or unknown
external_id ID returned by the destination when available
updated_at Timestamp for recovery and stale-pending review
  1. Check for a row with the request key.
  2. If it already says succeeded, return the stored result and skip the API call.
  3. If no row exists, record pending, then call the API.
  4. On a confirmed 2xx response, update the row to succeeded and store the external ID.
  5. On a timeout, keep the state as unknown until you query the destination or retry safely.

This ledger is useful for sequential or low-concurrency workflows, but a check followed by an insert is not an atomic lock. Two executions can check at the same moment and both see no row. For parallel production traffic, prefer destination-side idempotency or a database table with a unique constraint on request_key and an atomic claim operation.

Do not use workflow static data as a production lock

The $getWorkflowStaticData() helper looks convenient for storing processed IDs, but n8n labels it experimental, says the data should be small, and warns that it may behave unreliably under high-frequency executions. That makes it unsuitable as the main duplicate barrier for valuable orders, payments, leads, or outbound messages.

A production-safe request sequence

  1. Validate that the event contains a stable source ID.
  2. Create the operation key once.
  3. Check any local success record.
  4. Send the request with the provider's idempotency mechanism.
  5. Retry only network failures, 429s, and provider-approved temporary errors.
  6. Reuse the same key and payload for every attempt.
  7. Store the external ID after confirmed success.
  8. Route exhausted or uncertain outcomes to an Error Workflow or manual review queue.

Keep request-level recovery separate from broad diagnosis. If you do not yet know why the node failed, use the failed n8n workflow debugging guide. Once the retry budget is exhausted, use an n8n Error Workflow to send the failure to Telegram, Slack, Google Chat, email, or another incident channel.

Common questions

Does Retry On Fail prevent duplicates in n8n?

No. It repeats the failed node. Duplicate prevention comes from idempotent request semantics, a provider-supported operation key, or a persistent store that can claim each business operation exactly once.

Should I retry every 500 response?

Not automatically. A 500 can leave a state-changing operation with an uncertain outcome. Follow the provider's error guidance, keep the same idempotency key, use a bounded retry policy, and reconcile the remote record when the result remains unknown.

Can the Remove Duplicates node replace an idempotency key?

It can remove repeated input items, but it cannot prove that a remote API did or did not apply an earlier request after a timeout. Protect the side effect at the API or persistence layer.

Sources checked

n8n partner link

Want managed n8n for the workflow?

I may earn a commission if you sign up through this link, at no extra cost to you.

Try n8n Cloud

Need one risky API workflow mapped?

Send the API operation, failure response, source ID, and expected business outcome. I will help separate safe retries from duplicate risk.

Map the retry path