How to monitor distinct email opens using Mailgun webhooks

I’ve been working with Mailgun’s API recently and got the basic functionality working perfectly. However, I’m running into an issue with tracking email opens.

The problem is that Mailgun records every single time someone opens the same email. If a recipient opens my email multiple times, it creates separate open events for each instance.

My question: What’s the most effective approach to identify when a particular email gets opened for the first time only?

I’m wondering if I should rely on the default tracking data that comes with the webhook, or if it would be better to set up custom variables when sending the emails initially. What specific fields or identifiers work best for distinguishing individual emails in the webhook response?

For context, I’m using plain PHP with Mailgun’s quick start code (no special frameworks or extensions). The webhook integration is already functional, I just need to filter out duplicate opens from the same recipient.

I’ve been working with Mailgun webhooks for two years now, and tracking unique opens is tricky but doable. Here’s what works for me: Mailgun’s webhook gives you a message-id and recipient field - combine these as your unique database key. I always normalize the email first (lowercase + trim whitespace) before storing it. For processing, I use INSERT IGNORE with these fields as the primary key. This handles most duplicates automatically. One thing that caught me off guard: some email clients fire multiple open events within seconds. I added a small time buffer using the webhook’s timestamp field to filter these out. The nice thing about message-id is it stays consistent across all webhook events for the same email, so you don’t need custom variables when sending.

had the same headache last year. easiest fix is using mailgun’s built-in message-id field with the recipient email. just store those pairs in a simple table when the first open happens, then ignore any opens with the same pair after that. don’t need custom variables - the message-id is already unique for each email.

Hit this exact problem six months back with our newsletter tracking. Here’s what worked: create a composite ID using recipient email + unique message ID. When you send through Mailgun, throw in a custom variable like message_id or campaign_id with the recipient data. In your webhook handler, set up a tracking table that stores email + message_id + timestamp for first opens only. Before logging any open event, check if that email/message_id combo already exists. If it’s there, dump the webhook data. If not, log it as a real first open. Watch out for the webhook’s recipient field - it sometimes includes display names. I strip out everything except the actual email address before checking for dupes. This method’s been bulletproof for us, no false positives.