Server-Side Tracking for Home Services: Setup Guide
To implement server-side tracking for a home-service website, connect a permitted visit to a real business outcome and verify the server delivery separately. Installing a script is one step. You also need persistent storage, a source integration, stable action IDs and a named operator.
This walkthrough uses PipelineOn open source v0.3.2, free open-source software. It is an implementation route for a technical owner, not a claim that every CRM connects automatically. The examples are synthetic and do not demonstrate advertising performance.
On this page
- Choose direct application tracking or server GTM
- 1. Get the versioned software and prepare persistent storage
- 2. Install the collector and connect consent
- 3. Preserve the accepted visit reference
- 4. Import a real outcome through a trusted backend
- 5. Verify the linked report before enabling Meta
- 6. Configure optional Meta CAPI in test mode
- 7. Test failures and name the operating owner
Choose direct application tracking or server GTM
| Route | Suitable starting point | What still needs an owner |
|---|---|---|
| Open-source application | You want source capture, normalized outcomes, linked reports and optional Meta delivery | Hosting, consent setup and the source bridge |
| Server GTM | You already use tags and want a configured server container | Container, hosting, event sources and destination tags |
| Native or managed connection | A supported provider already covers the required source and outcome | Account configuration, scope checks and exception handling |
Google’s server-side tagging introduction explains the server-container architecture. Compare ten server-side options and tracking costs before choosing infrastructure. The steps below use the open-source application, which is not a server GTM host.
1. Get the versioned software and prepare persistent storage
Download the release ZIP and verify it against the release’s SHA256SUMS file. Read the README for the current contract and deployment limits.
The first release runs one website in one application process using persistent SQLite storage. Use the documented Node 24.14.x runtime or Docker configuration. Do not run multiple replicas against the same database. The licence is free; infrastructure and operation are your responsibility.
Copy .env.example to .env, configure the exact permitted website origins and generate independent read and write secrets. Keep secrets on the server. Run the supplied tests before relying on the deployment, and keep the database on persistent storage rather than an ephemeral application filesystem.
For public use, configure an HTTPS reverse proxy and the exact KIT_PUBLIC_URL. Restrict request sizes and rates at the proxy. Back up the complete data directory with the service stopped and test restoration separately. The open-source overview describes the boundaries of the standalone licence.
2. Install the collector and connect consent
Replace these example values with your real HTTPS software origin and configured site ID:
<script defer src="https://attribution.example.com/pixel.js"
data-site="your-website"></script>
<form data-attribution-site="your-website">...</form>
The collector starts without collection or browser storage. After it loads and your consent manager permits collection, call:
OpenAttribution.sites['your-website'].consent(true);
// Call this when permission is withdrawn:
OpenAttribution.sites['your-website'].consent(false);
Global Privacy Control disables collection. Test both permitted and declined states. The form should still work when tracking is unavailable. The software collector is not an extra Meta Pixel and does not automatically read Meta cookies.
3. Preserve the accepted visit reference
The server returns an accepted visitorSessionId. The opted-in form adds a hidden field at submission. Your backend must save that field with the inquiry and preserve its association with the later source records. Do not rename or discard it when the CRM creates the lead.
For a custom integration, .getTrackingContext() returns the accepted context or null, and open-attribution:session announces readiness. Avoid delaying or blocking the customer’s inquiry while waiting for tracking. If the reference is unavailable, save the request normally and leave attribution unlinked.
Campaign tags and session references are evidence of a visit, not proof of a person’s identity. Do not put customer names, email addresses or private details into campaign labels or URLs. Use the first-party data guide for the handoff rules.
4. Import a real outcome through a trusted backend
Your adapter maps the source fact and sends it to POST /v1/outcomes with the server-only write token. Do not expose that token in browser JavaScript or send unverified raw provider webhooks directly to the private endpoint.
Version 0.3 also supports POST /v1/events with canonical names such as lead_qualified, appointment_booked and payment_received. The business-event guide defines the source facts and platform mappings. The existing outcome route remains supported.
This synthetic completed-payment shape follows the release example:
{
"externalId": "payment-example-123",
"source": "your-payment-system",
"eventType": "payment",
"occurredAt": "2026-10-14T00:00:00Z",
"sourceUpdatedAt": "2026-10-14T00:01:00Z",
"outcome": "completed",
"visitorSessionId": "44444444-4444-4444-8444-444444444444",
"amountMinor": 125050,
"currency": "USD"
}
Replace the time, source ID and session with actual evidence. 125050 USD minor units represents $1,250.50. Use integer minor units for the chosen currency. Omitted value is unknown; a known zero is different.
An identical source/ID retry is a duplicate. Corrections require a newer authoritative sourceUpdatedAt; do not manufacture a new payment ID. Only completed payments count as revenue. Choose one payment source so the CRM and accounting system do not import the same receipt twice.
For calls, use the documented normalized /v1/calls contract and a verified provider relay. Answered does not automatically mean qualified. For bookings, preserve the actual completed booking record. Native source credentials and mapping remain your integration’s responsibility.
5. Verify the linked report before enabling Meta
Inspect the inquiry and outcome in the dashboard. Confirm campaign capture, source record, accepted session link, selected touch model and payment amount. A first Google visit followed by a Facebook return can produce different first- and last-touch credit for the same payment.
Inspect the tracking doctor for missing source tags, unlinked outcomes and disclosed history limits. Its report checks saved data; it does not prove a fresh Meta delivery. An unknown source should remain unknown rather than being assigned by resemblance to another record.
6. Configure optional Meta CAPI in test mode
Use a dataset you administer and follow the release README’s Meta envelope and test instructions. Configure the dataset ID, access token and test-event code on the server. Your mapped integration supplies permissioned matching fields, original event time and actual action source; website events require the real website context.
The software maps completed payments to Purchase, completed bookings to Schedule, received/completed forms to Lead and explicitly qualified completed calls to Lead. A won deal is not a completed payment. Visit references and UTMs are not substitutes for Meta matching fields.
Assign one server sender per logical conversion. If another connector owns it, use external ownership to skip software delivery. If browser and server report the same action, coordinate event name and event ID. A retry keeps the same identity; a later booking is a new action.
Inspect both the retained receipt and Events Manager Test Events. An accepted receipt proves provider acknowledgement, not matching, ad attribution or improved results. Follow the CAPI guide and Pixel comparison for the destination checks.
7. Test failures and name the operating owner
Replay an imported record, submit an invalid form, test a missing session and exercise a temporary destination failure in a safe test setup. The expected behavior is explicit: no false successful inquiry, no new business action from a replay, visible unlinked data and stable retry IDs.
Test a newer source correction. After a destination attempt, changes may require review; an already accepted event cannot be recalled by editing the database. Handle downstream correction or deletion separately.
Name who maintains credentials, backups, source adapters and failed deliveries before switching to live mode. Previously accepted test outcomes are not simply replayed as live conversions; use genuine new outcomes after configuration changes. For later CRM actions, follow offline events back to Facebook. For a broader shortlist, compare Facebook Ads tools for home services.
Sending the same business facts to Google Ads
The v0.3 release includes a direct Google Ads Data Manager adapter alongside Meta. Map each chosen business milestone to its own offline conversion action and review which actions are primary for bidding. Supply an authorized OAuth connection, actual consent choices and permissioned customer-provided matching data. GTM is optional.
Start with validation only, then use new live business facts after checking the configuration. A request ID confirms submission; the sender polls the same request for a processing result. Processing still does not prove an ad match or attributed revenue. GA4 and conversion adjustments are not included. Follow the versioned Google Ads guide and canonical event mappings.
Frequently Asked Questions
Can I implement server-side tracking for free?
The open-source software has no software licence fee. You still provide hosting, a trusted source integration and operation. Meta campaign spend and any source-system API costs are separate.
Is server-side tracking the same as CAPI?
No. Server-side tracking is a broader architecture. Meta CAPI is a particular destination API. A server setup still needs source records, correct mapping and a tested sender to deliver those events.
Does installing the script connect my CRM automatically?
No. The script captures permitted website evidence. A trusted backend or workflow must preserve the accepted session reference and import normalized CRM, call, booking or payment outcomes.
Written by
PipelineOn Research Team