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 line | Unit you count | Proof you need | What it does not prove |
|---|---|---|---|
| Ad delivery | Platform-reported impression | Campaign report | A person paid attention |
| Click | Click event | Tagged destination URL or session record | A reservation was made |
| Reservation | Unique reservation record | Campaign label plus reservation ID | The party arrived |
| Seated party | Unique reservation whose party checked in | Reconciled host-stand outcome | A check was paid |
| Paid reservation party | Unique seated reservation party linked to at least one paid, non-voided settled check | Reservation-to-POS match | The ad caused an incremental visit |
| Matched sales | Deduplicated settled-check dollars | POS checks tied to paid reservation parties, net of voids and refunds | Profit 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:
- Platform-reported delivery or clicks
- Campaign-tagged reservation
- Verified seated party and covers
- Directly matched settled check
- Like-for-like movement in covers or sales
- Controlled estimate of incremental business
- 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:
| Field | What to write down |
|---|---|
| Campaign label | The exact value passed into the booking record |
| Ad and offer | The creative, copy, audience, daypart, and promised terms |
| Final URL | The exact destination after every redirect |
| Reservation ID | The unique reservation record; it does not prove how many guests were identified |
| Visit outcome | Open/future, completed seating, canceled, no-show, or unresolved |
| Covers | Verified people seated with that reservation |
| Check outcome | Matched, unmatched, open, ineligible, or unresolved |
| Check value | Net settled dollars after voids, refunds, and discounts |
| Costs | Every 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:
| Booker | What to verify |
|---|---|
| OpenTable | Check whether the current export returns your campaign label in `ot_source` or `ot_campaign`; the documented Feast setup did. |
| Resy | A 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 booker | Ask 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:
- Open the exact live ad destination as an outside guest would.
- Make a clearly labeled test reservation through the real booking path.
- Confirm the campaign label and reservation ID appear in the exported booking record.
- Have an authorized tester check in and complete a small in-person purchase.
- Leave the transaction paid and non-voided until it appears in the matched reporting.
- Verify the reservation, seated party, and check are joined to the same test record.
- 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:
- If another person pays, retain the seated reservation but mark the check unmatched unless a permitted record proves the join.
- If the party pays cash, use a permitted reservation-to-check key if one exists; otherwise keep the sale outside directly matched dollars.
- If several checks belong to one party, count one paid reservation party and deduplicate the checks before summing sales.
- If the check is voided or refunded, remove its reversed dollars from paid sales.
- If the restaurant cannot reconcile the outcome, keep it unresolved rather than forcing a match.
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:
- Media spend
- Creative production
- Influencer compensation, when an influencer made the ad
- Content license, account-level partnership-ad permission, and any bonus triggered by actual paid use, when each applies
- Software and agency fees allocated to this campaign on a written, consistent basis
- Reservation, deposit, or payment fees attributable to the campaign
- One incentive treatment: actual incremental food, packaging, payment-processing, fulfillment, and paid-labor cost caused by the incentive, not its menu face value
- Other incremental service labor that is not already counted in incentive fulfillment
- Monetized owner or manager time, if you include it, kept separate from paid service labor
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 shows | What it means | What to do next |
|---|---|---|
| Clicks, no tagged reservations | The ad generated platform activity, but the booking handoff is broken or the page did not produce bookings | Retest the final URL, redirects, widget handoff, and exported campaign field |
| Tagged reservations, weak seating | Booking happened; the arrival problem is downstream | Review date, daypart, offer terms, reminder process, cancellation pattern, and no-shows |
| Seated parties, poor check coverage | Guests arrived, but the identity-to-POS join is weak | Audit host check-in, reservation IDs, payer changes, cash, split checks, and reversal handling |
| Matched checks, poor contribution | The evidence reaches sales, but the economics do not clear the cost | Repair the offer, check value, variable cost, or campaign cost |
| Healthy matched contribution, no like-for-like lift | The matched records look good, but displacement or over-credit may remain | Run a cleaner comparison with a fixed baseline or holdout |
| Too many open or unresolved records | The evidence is not mature enough for a decision | Wait 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:
| Row | Exact unit |
|---|---|
| Platform delivery and clicks | Platform-reported events, labeled as such |
| Tagged reservations created | Unique reservation records |
| Mature known reservation outcomes | Seated, canceled, and no-show counts |
| Excluded reservation states | Open/future, immature, ineligible, duplicate, and unresolved counts |
| Seated-party rate | Successful 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 parties | Unique reservation parties with verified in-person seating |
| Completed covers | People seated with those parties, reported separately from parties and guests |
| Unique identified guests | People individually identified in permitted records; the booker counts once, and companions count only when separately identified |
| Mature known check outcomes | Matched and unmatched seated reservations |
| Excluded check states | Open, immature, ineligible, and unresolved counts |
| Check-match coverage | Successful 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 checks | Deduplicated check count |
| Matched net settled sales | Dollars after discounts, voids, and refunds |
| Verified paid reservation parties | Unique 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 cost | Sum of every applicable acquisition-ledger row allocated once to the same complete campaign cohort and dates |
| Cost per verified paid reservation party | Total acquisition cost divided by verified paid reservation parties from that same complete campaign cohort |
| Matched-check variable costs | Ordinary food, packaging, processing, fulfillment, and incremental labor costs for the matched checks, each counted once |
| Non-fulfillment campaign costs | Applicable media, creative, influencer, rights, software, agency, and other campaign costs not already counted in check fulfillment |
| Matched contribution | Matched net settled sales minus matched-check variable costs and non-fulfillment campaign costs |
| Observed lift | Like-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.