Idempotency
While Transyt deduplicates events at the ingestion level, your application may still receive the same event more than once — for example, if a delivery times out but your app actually processed it, or during a replay.
Why Duplicates Happen
Section titled “Why Duplicates Happen”- Delivery timeout — Your app processed the event but didn’t respond within 30 seconds, so Transyt retried
- Manual replay — Someone replayed the event from the dashboard or API
- Network issues — The response was lost in transit
Strategies
Section titled “Strategies”Use the Event ID
Section titled “Use the Event ID”Every delivery includes a unique event_id (UUID). Store processed event IDs and skip any you’ve already seen:
# Rails exampledef process_webhook(payload) event_id = payload["event_id"]
# Skip if already processed return if ProcessedEvent.exists?(event_id: event_id)
ActiveRecord::Base.transaction do ProcessedEvent.create!(event_id: event_id) # Process the event... endendUse the External ID
Section titled “Use the External ID”The external_id field contains the provider’s own deduplication key (e.g., Stripe’s evt_xxx). This can be useful for cross-referencing with the provider’s records:
return if Payment.exists?(stripe_event_id: payload["external_id"])Make Operations Idempotent
Section titled “Make Operations Idempotent”Design your processing logic so that applying the same event twice produces the same result:
- Use
upsertinstead ofinsertfor database operations - Check the current state before making changes
- Use unique constraints at the database level
Acknowledging Events
Section titled “Acknowledging Events”After processing, you can explicitly acknowledge events via the API:
# Mark as processedcurl -X POST https://ingest.transyt.com/admin/events/{event_id}/ack \ -H "X-Admin-Token: YOUR_ADMIN_TOKEN"
# Mark as failedcurl -X POST https://ingest.transyt.com/admin/events/{event_id}/fail \ -H "X-Admin-Token: YOUR_ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"error": "Insufficient inventory"}'