What broke · Meta Conversions API · 4 September 2026

Why a moved appointment counts as two bookings.

When a homeowner moves an appointment, the ad platform can count it as a second booking. Your report says one estimate. Ads Manager says two. The ads learn that a no-show who rebooked is worth double.

What Meta does

When two events arrive with the same event name and the same event id (the fields Meta calls event_name and event_id), Meta keeps one and drops the other. That is what lets a browser pixel and a server send report the same purchase, without counting it twice. The window is 48 hours. After it, the same id is a new event.

Meta also accepts a website event whose time, the field event_time, is up to 7 days in the past. Those windows differ, and people tend to remember only the second.

What broke

A booking system sends a booking event (Meta calls it Schedule) when a homeowner confirms an appointment, with the lead's own id as the event_id. Reasonable: one lead, one appointment, one id. Then the homeowner no-shows and rebooks eight days later, or moves the visit from a manage link. The confirm path runs again, sends Schedule again, same id. Meta's 48 hours have passed. Two conversions.

The report the client reads counts distinct leads, so it says one. You tell the client the spend reconciles with Ads Manager. It does not. The gap is the number of moves. Worse than the report: Meta learns from whatever you tell it. To the bidding, a homeowner who no-showed and rebooked is now worth two bookings. That is the opposite of what a booking signal is for.

What to do

  • Gate the send on a record of acceptance, not on intent. Write "the platform accepted this event for this lead" only when the API says so. Before sending, ask that record. A first send that failed leaves nothing behind, so a move after a failed first send sends. A move after a successful one correctly does not.
  • Do not solve it with a counter or a flag set before the send. A flag written before acceptance only records an intention. A failed send then blocks the retry that would have rescued it.
  • One lead, one appointment. If your own numbers count distinct leads, the conversion stream has to as well. Otherwise the two never reconcile, and you explain the gap on every report.
  • If you also send a deeper event when the visit happens, give it its own id, for example lead-sat. It is a separate event and must never dedupe against the booking.

What this does not cover

  • Browser-side duplicates from a second pixel or plugin sending without an event_id at all. Different failure; the fix is in the tag, not the server.
  • Google. Its offline conversion import keys on the click id plus the conversion time. It has its own rules for a repeated upload. This note is Meta only.
  • Whether a rebooked appointment should count as one or two in your own business. This note assumes one.