Map the trigger's stable unique identifier into Source Event ID on every data-creating action. That is the whole guard, and it is required rather than optional.
Why it matters
Zapier retries. Triggers re-fire, autoreplay runs, someone turns a Zap off and on again. Without a guard, each of those becomes a duplicate expense in a financial record — far more annoying to clean up than to prevent.
What to map
Use the identifier the source system already assigns as unique and stable for that event:
- Gmail → the message ID
- Google Drive → the file ID
- A form → the submission ID
- Slack → the message or file ID
Never map a timestamp, a random value, or a counter. Those change on replay, which defeats the entire mechanism.
What happens on a replay
Replaying the same Source Event ID for the same operation returns Safe Retry
Replayed as true instead of creating a second record. One financial record
exists, not two.
Reusing the same ID with conflicting data is rejected rather than silently merged, so a mis-mapped ID surfaces as an error you can see instead of quietly corrupting the sheet.
Which actions take it
Every action that creates a record: Upload Receipt, Create Expense, Add Mileage Entry, Add Income Entry, Start Gmail Receipt Scan, and Create Expense Report. The read-only searches and the polling triggers do not need one.
Not the same as duplicate detection
Source Event ID protects against the same event being processed twice.
ExpenseBot's duplicate detection is separate: it recognizes when a different
submission describes a receipt already in your sheet, and reports the outcome as
duplicate rather than writing a second row. You want both.
