When a send fails and you retry it later, the browser has closed. Some of what Meta matches on goes with it. What a retry can still carry, what it cannot, and where it must stop.
Most implementations send the conversion inside the request that produced it, once. They use whatever "run this after the response" hook the platform offers. Meta rate-limits for thirty seconds. Or the token endpoint has a bad minute. Or the worker dies before the hook drains. That booking never reaches the ad account. Nothing raises an error. Nobody hears. You book the homeowner and serve them as promised. The only trace is a conversion that is not there. It shows up weeks later as a campaign that will not learn.
| Key | What it is | On the live send | On a retry |
|---|---|---|---|
em, ph | hashed email and phone, the two strongest | yes | yes, from the record |
zp | hashed zip, weak alone | yes | yes |
external_id | your own id for the person, hashed; what clusters a lead's events into one person | yes | yes |
fbc | the click, rebuilt as fb.1.<landed ms>.<fbclid> from what the landing page stored | yes | yes, if you stored the fbclid and the landing time |
fbp | the pixel's browser id, read from the cookie by the page making the call | yes | no: it is a browser fact and exists only in the tab |
| IP, user agent | not hashed, per the spec; what Meta leans on to reconcile a website event with its session | yes, off the request | no: there is no request |
The tempting fix is to store the IP against the lead so the retry can replay it. Do not. That puts personal data in your database to improve a match. Next to email and phone, the improvement is marginal. The right shape is simple. The retry sends a weaker event, and the record says which sends it retried. The retry rate becomes a number you can read.
event_id) for 48 hours.The retry exists to rescue a send that failed, or that landed and whose "accepted" write failed. In the second case the platform already holds the event. It drops a resend inside 48 hours as a duplicate, which is what you want. Past 48 hours the same resend is a second conversion. So the retry may reach back 48 hours and no further. Anything older is a loss you take in the open. Days three to seven only help if the platform stayed down for most of a week. In that case the original did not land either.
A retry four hours later must carry the original time, event_time, not now. Otherwise a booking made on Tuesday lands on Wednesday. Every cost-per-booking number that reads a date is then off by the length of the outage. This is easy to get wrong. On the live path the two times are the same, so the bug stays invisible until the first outage.
An event whose match rides on fbp alone, such as a "held a slot, never confirmed" audience
event fired before there is a name or phone. A retry would send a thin match and record it as sent. The record then claims a signal that did not land. Losing it is better than lying about it.