Feast AnalyticsHow to Track OpenTable Reservations From Facebook Ads: Follow the Booking to the Check

How to Track OpenTable Reservations From Facebook Ads: Follow the Booking to the Check

Track Facebook ads to OpenTable reservations, seated parties, and settled checks without treating a click or booking as restaurant revenue.

To track OpenTable reservations from Facebook ads, give each campaign a unique label in the booking link, prove that label survives in the reservation record, reconcile the booking to a seated party, and match that party to a paid, non-voided POS check. A click, a reservation record, a seated party, and a settled check are four different finish lines; report each one separately.

That distinction is the difference between knowing an ad generated booking activity and knowing what happened in the dining room. The same principle powers a broader ad-to-check tracking setup: every handoff must preserve enough evidence for the next one.

Finish lineUnit you countProof you needWhat it does not prove
Ad deliveryPlatform-reported impressionCampaign reportA person paid attention
ClickClick eventTagged destination URL or session recordA reservation was made
ReservationUnique reservation recordCampaign label plus reservation IDThe party arrived
Seated partyUnique reservation whose party checked inReconciled host-stand outcomeA check was paid
Paid reservation partyUnique seated reservation party linked to at least one paid, non-voided settled checkReservation-to-POS matchThe ad caused an incremental visit
Matched salesDeduplicated settled-check dollarsPOS checks tied to paid reservation parties, net of voids and refundsProfit or causal lift

1. Choose the paid check as the finish line before you build the link

Write down one finished outcome: a campaign-tagged reservation that became a verified in-person seating and matched at least one paid, non-voided settled check.

Keep parties, covers, reservations, and checks in separate columns. One reservation can bring several covers, and one party can split payment across several checks. Your main success row should count unique reservation parties; keep covers and check count as supporting rows.

The reservation booker is one identified person. The party is one visit event, and covers are the people seated for it. Companions are not unique identified guests unless your records identify them separately. Keep the reservation record, reservation party, unique identified guests, covers, and checks as five separate counts.

Use this evidence ladder instead of one blended “ROI” total:

  1. Platform-reported delivery or clicks
  2. Campaign-tagged reservation
  3. Verified seated party and covers
  4. Directly matched settled check
  5. Like-for-like movement in covers or sales
  6. Controlled estimate of incremental business
  7. Contribution after all applicable costs

2. Give the campaign one name that can survive every handoff

Create one short campaign label, such as FB-BRUNCH-SEPT, and use it in the ad, final booking URL, reservation export, and POS match file.

Record this campaign sheet before launch:

FieldWhat to write down
Campaign labelThe exact value passed into the booking record
Ad and offerThe creative, copy, audience, daypart, and promised terms
Final URLThe exact destination after every redirect
Reservation IDThe unique reservation record; it does not prove how many guests were identified
Visit outcomeOpen/future, completed seating, canceled, no-show, or unresolved
CoversVerified people seated with that reservation
Check outcomeMatched, unmatched, open, ineligible, or unresolved
Check valueNet settled dollars after voids, refunds, and discounts
CostsEvery campaign and matched-check cost used in the decision

For OpenTable, verify whether your current export preserves ot_source and ot_campaign. In a Feast setup documented in January 2026, OpenTable attached both fields to exports even though they were not visible in the normal interface; cached browser values and the handoff from a website to the widget could also change which value survived.

Do not assume that behavior is identical in every account or website. Your own paid test decides whether the current path works.

3. Make the campaign label reach the reservation record

Send the ad to a final URL that passes the same campaign label into the reservation system, then export a test reservation and find the label beside its unique ID. If the ad lands on your website first, the site must preserve that label when the guest opens the booking widget or leaves for the reservation page.

In one Feast implementation, all widget traffic reached OpenTable as restaurant, which made paid and organic bookings indistinguishable; the fix passed the campaign values through the restaurant's Wix site into the booking widget.

Do not copy one reservation book's setup into another just because both take reservations. Verify the booker you have:

BookerWhat to verify
OpenTableCheck whether the current export returns your campaign label in `ot_source` or `ot_campaign`; the documented Feast setup did.
ResyA restaurant documented a Stripe-to-Meta purchase event for prepaid Resy reservations through Make, but that event proved a reservation payment signal, not a seated party or final restaurant check.
Tock or another bookerAsk which current export, API, or reservation field preserves the exact campaign label and reservation ID; do not launch until your own test record returns both.

In one reservation-led Feast setup, the reservation itself identified the booker without a separate scan at that first step. It still did not establish that the party arrived or paid.

4. Prove the full chain with a paid test before spending on the campaign

Run one end-to-end acceptance test through the same link, website, booking screen, host procedure, and POS connection the guest will use. A successful test ends only after the paid check appears in the matched campaign-sales record.

Use this order:

  1. Open the exact live ad destination as an outside guest would.
  2. Make a clearly labeled test reservation through the real booking path.
  3. Confirm the campaign label and reservation ID appear in the exported booking record.
  4. Have an authorized tester check in and complete a small in-person purchase.
  5. Leave the transaction paid and non-voided until it appears in the matched reporting.
  6. Verify the reservation, seated party, and check are joined to the same test record.
  7. Only then void or refund the test transaction and verify that the dollars disappear from paid sales while the reversal remains auditable.

If the positive check never appears, stop. Fix the first broken handoff instead of accepting a click event, reservation confirmation, or estimated check as a substitute.

5. Reconcile every reservation after its dining time passes

A reservation stays open until its scheduled time and your fixed outcome-review window have both elapsed. After that window, assign one known outcome: seated, canceled, or no-show. Keep unresolved records separate rather than guessing.

Your seated-party rate must use one exact population:

Seated-party rate = unique eligible ad-tagged reservations with verified in-person seating ÷ unique eligible ad-tagged reservations whose scheduled dining time and fixed outcome-review window fully elapsed and whose final seated, canceled, or no-show result was reconciled and known.

The numerator is the successful subset of that exact denominator. Hold an early seating out of the rate until its full review window closes, and report open/future, immature, ineligible, duplicate, and unresolved records separately.

This matters in real service. One documented Feast campaign produced booking records that included a no-show, an immediate cancellation, and a far-out reservation; none of those records could honestly be called a completed visit at the time of the report.

6. Match the seated party without trusting the name alone

If your reservation and POS records share a stable ID, match on it first. Otherwise, use only permitted fields the two systems share, then use service date, time, table, and party details to investigate exceptions. Never use a first name by itself when two parties could share it.

A Feast account recorded a wrong check match when two guests with the same first name were seated at the same time. That is not a small cleanup error: it assigns another table's spending to the campaign.

Treat these cases honestly:

The check-match coverage rate also needs a mature, known population:

Check-match coverage = unique eligible verified seated reservations successfully linked to at least one paid, non-voided settled check ÷ unique eligible verified seated reservations whose fixed check-review window fully elapsed and whose matched-or-unmatched outcome was reconciled and known.

The numerator is the successful subset of that denominator. Hold an early match out until its full check-review window closes, and report open, immature, ineligible, and unresolved check matches outside the rate.

7. Calculate cost per paid reservation party and contribution on separate ledgers

Cost per paid reservation party counts unique parties, not reservation records created, covers, or individual checks. It tells you how much the campaign cost for each reservation that reached both the dining room and a paid check.

Define the acquisition cohort as all eligible ad-tagged reservation records created during the fixed campaign window for the stated location. Wait until every record's scheduled dining time, outcome-review window, and check-reconciliation window have fully elapsed and both results are known.

Cost per verified paid reservation party = total acquisition cost assigned once to that complete campaign cohort ÷ unique reservation parties from that same cohort whose successful outcome was verified in-person seating plus at least one matched paid, non-voided settled check.

The denominator is the successful subset of that exact cohort. Hold early paid parties out until both windows close; show open or future, immature, ineligible, duplicate, and unresolved records separately. Assign all acquisition cost once to the same cohort and dates, including spending that produced no successful party.

Build total acquisition cost from mutually exclusive rows:

Do not add a subtotal beside the components that create it. Do not charge the same labor to incentive fulfillment and service labor, and do not count an included vendor charge again.

Contribution uses a different ledger:

Matched contribution = net settled sales after discounts − all ordinary variable food, packaging, processing, fulfillment, and incremental labor costs of the matched checks − non-fulfillment campaign costs.

The matched-check variable costs already contain the actual cost of any incentive item served on those checks, so do not subtract that incentive cost a second time. Mark any booking, deposit, or processing fee already included in check-level variable costs so it does not enter campaign costs again. Matched contribution remains a directional result for the records you could join; it is not proof that the ad caused the sales, and it is not the restaurant's full profit.

Before a booking matures, keep its estimated reservation value separate from completed sales.

8. Repair the first break instead of arguing over one blended number

The first failing stage tells you what to fix next. Do not rewrite an upstream success as a downstream one.

What the record showsWhat it meansWhat to do next
Clicks, no tagged reservationsThe ad generated platform activity, but the booking handoff is broken or the page did not produce bookingsRetest the final URL, redirects, widget handoff, and exported campaign field
Tagged reservations, weak seatingBooking happened; the arrival problem is downstreamReview date, daypart, offer terms, reminder process, cancellation pattern, and no-shows
Seated parties, poor check coverageGuests arrived, but the identity-to-POS join is weakAudit host check-in, reservation IDs, payer changes, cash, split checks, and reversal handling
Matched checks, poor contributionThe evidence reaches sales, but the economics do not clear the costRepair the offer, check value, variable cost, or campaign cost
Healthy matched contribution, no like-for-like liftThe matched records look good, but displacement or over-credit may remainRun a cleaner comparison with a fixed baseline or holdout
Too many open or unresolved recordsThe evidence is not mature enough for a decisionWait for the fixed windows to close or repair the missing record before judging

Meta and the reservation book may report different booking totals because they can observe different steps and paths. One Feast implementation recorded Meta claiming bookings from a broadly installed OpenTable pixel even when the restaurant's campaign-specific record could not see the same path. Use each system's number for the state it actually observed.

Your weekly scorecard should therefore show:

RowExact unit
Platform delivery and clicksPlatform-reported events, labeled as such
Tagged reservations createdUnique reservation records
Mature known reservation outcomesSeated, canceled, and no-show counts
Excluded reservation statesOpen/future, immature, ineligible, duplicate, and unresolved counts
Seated-party rateSuccessful subset of unique eligible ad-tagged reservations with verified in-person seating divided by unique eligible ad-tagged reservations whose scheduled dining time and fixed outcome-review window fully elapsed and whose seated, canceled, or no-show result was reconciled and known
Verified seated partiesUnique reservation parties with verified in-person seating
Completed coversPeople seated with those parties, reported separately from parties and guests
Unique identified guestsPeople individually identified in permitted records; the booker counts once, and companions count only when separately identified
Mature known check outcomesMatched and unmatched seated reservations
Excluded check statesOpen, immature, ineligible, and unresolved counts
Check-match coverageSuccessful subset of unique eligible verified seated reservations linked to at least one paid, non-voided settled check divided by unique eligible verified seated reservations whose fixed check-review window fully elapsed and whose matched-or-unmatched outcome was reconciled and known
Paid non-voided settled checksDeduplicated check count
Matched net settled salesDollars after discounts, voids, and refunds
Verified paid reservation partiesUnique parties from the fully elapsed, reconciled-known campaign cohort that reached verified seating and at least one matched paid, non-voided settled check
Total acquisition costSum of every applicable acquisition-ledger row allocated once to the same complete campaign cohort and dates
Cost per verified paid reservation partyTotal acquisition cost divided by verified paid reservation parties from that same complete campaign cohort
Matched-check variable costsOrdinary food, packaging, processing, fulfillment, and incremental labor costs for the matched checks, each counted once
Non-fulfillment campaign costsApplicable media, creative, influencer, rights, software, agency, and other campaign costs not already counted in check fulfillment
Matched contributionMatched net settled sales minus matched-check variable costs and non-fulfillment campaign costs
Observed liftLike-for-like movement, clearly labeled as observed rather than caused

For the broader keep, repair, or stop decision, use the restaurant ad diagnosis after both windows close.

Find the break between the reservation and the check

If you can export the booking and POS records but still cannot tell where the join fails, Feast's Restaurant Marketing Audit is built around the marketing-to-check evidence needed to make a keep, repair, stop, or cleaner-test decision.

The current limited-time offer is $27 one time, with no subscription. Access normally costs $47 per month or $500 per year. The purchase includes lifetime restaurant performance reporting and Revenue Simulator access, plus one Restaurant Marketing Strategy Session. Get your restaurant's reservation-to-check evidence audited.