Tips > Building Workflows

Use `$execution.id` for Idempotency Keys

When your workflow calls external APIs that charge money or trigger irreversible actions (sending emails, creating payments, posting to social media)

When a workflow calls external APIs that charge money or trigger irreversible actions, use $execution.id combined with an item index to build idempotency keys. Passing this key on requests -- for example as Stripe's Idempotency-Key header -- prevents duplicate charges or actions when n8n retries a node. For bulletproof safety across manual re-runs, derive the key from business data instead.

Why use $execution.id for idempotency keys?

When your workflow calls external APIs that charge money or trigger irreversible actions (sending emails, creating payments, posting to social media), use $execution.id combined with an item index to generate idempotency keys. This prevents duplicate actions if n8n retries the workflow or the node executes twice.

How do you generate an idempotency key in n8n?

Real-world example: Creating Stripe payment intents where a duplicate call would charge the customer twice.

// Mode: Run Once for Each Item
const item = $input.item.json;
const itemIndex = $input.all().indexOf($input.item);

// Deterministic idempotency key: same execution + same item = same key
const idempotencyKey = `${$execution.id}_${itemIndex}_${item.orderId}`;

const response = await this.helpers.httpRequest({
  method: 'POST',
  url: 'https://api.stripe.com/v1/payment_intents',
  headers: {
    'Authorization': `Bearer ${item.stripeSecretKey}`,
    'Idempotency-Key': idempotencyKey,
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: `amount=${item.amount}&currency=${item.currency}&customer=${item.customerId}`,
});

return [{
  json: {
    ...item,
    paymentIntentId: response.id,
    idempotencyKey,
    status: response.status,
  }
}];

What is the scope of an $execution.id key?

Warning: Idempotency Key Scope

The key is unique per execution. If you manually re-execute the workflow, $execution.id changes and a new payment intent will be created. For truly bulletproof idempotency, derive the key from business data only (e.g., orderId + invoiceDate).

Related: Use Edit Fields in "Map Each" Mode for Simple Renames · Configure Payload Size and Binary Data Mode for Large Files

Showcase builds

19 complete workflows from my own projects, each with its n8n workflow JSON to import. Showcase entries link the file at the end of the article.

See the showcase builds

Keep reading

190 entries grouped by topic, from first workflow to queue mode. Free, no signup.

Browse the encyclopedia

Need it built?

I design, build and run n8n systems for clients. Every engagement starts with a $1,500 diagnostic audit, credited toward the build.

Book an introductory call