Ad and Conversion Tracking

What OpenCourt sends to Meta and Google — and what it never sends

A plain-English breakdown of the conversion data OpenCourt shares with ad platforms, how it protects your customers' privacy, and what stays private.

When you turn on Ad and Conversion Tracking, OpenCourt reports your online sales to the ad platforms you connect — so Meta and Google can see which ads actually bring in paying customers. This page explains exactly what gets sent, and just as importantly, what never does.

The events OpenCourt reports

Six things get reported, and only these:

  • A page view — someone visited your club's booking pages (sent from their browser).
  • A checkout started — someone reached the payment step (sent from their browser).
  • A purchase — someone actually paid for something online. This one is sent from OpenCourt's servers using Meta's Conversions API, not from the customer's browser — so it still arrives even when ad blockers or iOS privacy settings block browser tracking. Your purchase data is the signal that matters most, and server-side delivery is what keeps it reliable.
  • A new membership — when someone buys their first membership, a Subscribe event is sent alongside the purchase (never instead of it). Renewals, bookings, events, and store sales report a purchase only. So does a presale deposit: a deposit is not a recurring membership yet, so it reports Purchase only — Subscribe fires later, if and when the presale converts.
  • A new customer's free booking — their first online order at your club, when it cost them $0, reports a Lead with a value of 0, never a Purchase. See Free bookings are reported as a Lead below.
  • A refund — sent to Meta only, when you refund a reported sale from OpenCourt (to the card or in person), or lose a chargeback on it. See Refunds are reported to Meta below.

Google gets the same picture: GA4 receives page_view, begin_checkout, purchase, and generate_lead for a free booking. Google Ads receives the purchases as offline click conversions, and free bookings too if you map them (see below).

The value reported is what the customer actually paid

Each purchase carries the net cash captured — the amount after any promo code, pass, or account credit — never the list price. That keeps your ad optimization honest: the platforms learn to find customers based on real revenue, not inflated sticker prices.

Front-desk sales are excluded — on purpose

Sales your staff ring up at the front desk (admin and POS sales) are never sent. A walk-in who paid at the counter didn't come from an online ad, and mixing that revenue in would teach the ad platforms the wrong lessons about which ads work. Only online sales — the ones an ad could plausibly have driven — are reported.

Free bookings are reported as a Lead

If a customer covers a booking entirely with a pass, account credit, or a 100% promo code, no cash is captured. Free events work the same way. When that free order is the customer's first order at your club, OpenCourt reports it as a Lead event with a value of 0 — with the same content_category, content_name and customer matching as a purchase.

A free order from an existing customer sends nothing. Most free bookings come from members and pass holders booking against something they already bought — at the clubs where this launched, nearly all of them. Reporting those as leads would teach the ad platforms to find people who are already your customers, and Lead is the same event your own website may fire for contact forms.

A free order is never reported as a $0 Purchase. A zero-value purchase would drag down your reported return on ad spend and teach the ad platforms to find people who never pay. Because Lead is a separate event, nothing changes for a campaign that optimizes for purchases. If you run a free-first-session offer, build a Custom Conversion on Lead (filter on content_category to narrow it, for example space) and optimize that campaign for it.

  • Meta receives the Lead automatically.
  • GA4 receives it as generate_lead.
  • Google Ads receives it only if you map the free_booking row to its own conversion action — see Set up Google Ads conversion tracking. Leave that row empty and free bookings are not sent to Google Ads. They never fall back to your default action.

Refunds are reported to Meta

When you refund a sale from OpenCourt — to the customer's card or in person, in full or in part — or lose a chargeback on it, OpenCourt tells Meta, so you can measure the revenue you actually kept:

  • Meta cannot change a purchase it has already recorded. Instead, OpenCourt sends a separate Refund event worth the amount returned, labeled like the original sale. To see revenue after refunds in Ads Manager, create a custom metric: purchase value minus Refund value. OpenCourt never subtracts more than it reported: if a customer disputes a sale you already refunded, no second Refund is sent.
  • Google Ads is not updated. Google's conversion upload service can only add conversions; it cannot remove or re-value one. Reconcile Google Ads revenue against OpenCourt's own reports.
  • GA4 is not updated either. Purchases reach GA4 from the customer's browser, and a refund has no browser session to report from.

Only sales OpenCourt reported to Meta are covered. A refund to account credit does not change anything: no cash left your club, and OpenCourt reports cash. A refund issued directly in your Stripe dashboard is not sent either — refund from OpenCourt. Refunds made before September 28, 2026 are not sent. Refunds made on or after that date are, including any made in the days before this update reached your account. A refund made more than 180 days after the sale is not sent, because OpenCourt no longer keeps what it reported for that sale.

Purchases made in the OpenCourt app

The OpenCourt customer app runs the same booking site inside a native shell. Inside the app, OpenCourt deliberately does not run the browser pixel — firing a tracking pixel inside an iOS app without Apple's tracking permission prompt is a policy exposure we will not take on your behalf.

In-app purchases are still reported. They go out server-side through the Conversions API exactly like web purchases, so no sale is lost. What is missing is the browser-side context: the page views, the checkout-started events, and the click identifiers Meta uses to tie a sale back to one specific ad. So an in-app purchase is more likely to be counted as revenue without being credited to the ad that caused it.

What travels with each purchase

A few extra fields go along with every purchase so the platforms (and you) can tell sale types apart:

FieldWhat it contains
content_categoryWhich kind of sale it was — one of: space (a court, bay or lane booking), event, day_fee, add_on (equipment rental), membership, membership_presale (a deposit taken before the club opens), pass_package (a punch card or lesson bundle), membership_renewal, store, coach_lesson, gift_card. A charge OpenCourt cannot classify — a few legacy and manually entered charge types — is sent without this field rather than in a catch-all bucket
content_categoriesEvery category in the order, comma-joined in the same order as above (membership,space). content_category can only name one thing, so use this one with a contains rule to build "any order that included a membership"
event_typePresent whenever the purchase is attached to something on your schedule: OpenPlay, OpenGame, League, Clinic, Tournament, Lesson or Other. This includes space bookings (usually OpenGame) and coach lessons (Lesson) — it is not limited to the event category
content_nameThe name of what was bought — the event's name, the membership plan, the product, the rented equipment, or (for a booking) your own space category or space name. When none of those can be resolved it falls back to the charge's own description, so this field is never empty
content_ids / contents / num_itemsThe itemized contents of the order
is_new_customerWhether this was the person's first purchase at your club
membership_statusA coarse label only: member, non-member, or lapsed

Customer identifiers are hashed before they leave OpenCourt

For an ad platform to credit a sale to an ad, it needs to recognize which of its users made the purchase. OpenCourt handles this with one-way hashing (SHA-256): the customer's email, phone number, and a per-club customer ID are scrambled into a fingerprint before sending. Meta or Google can match that fingerprint against the hashes of their own logged-in users — but the raw email and phone number are never transmitted, and a hash can't be reversed back into them. You get accurate ad attribution without handing over your customer list in readable form.

Your responsibilities

When you turn the feature on, OpenCourt shows a data-sharing disclosure that you accept — that covers OpenCourt's side of the sending. Your club remains responsible for its own privacy disclosures: your privacy policy should mention ad-platform data sharing, and your region may require a cookie or consent banner (for example under GDPR in Europe or CPRA in California). This isn't legal advice — if you're unsure what your region requires, check with a legal advisor.