Open Tracked/Integrations/Meta CAPI for a custom website via server GTM

Meta CAPI for a custom website via server GTM

On a custom site you build the data layer yourself. That is more work than a plugin and gives you exactly the data you want.

4 min read · Updated October 26, 2026

YYour custom siteDData layer and event IDServer container to Meta
In this guide
Key takeaways
  • A custom site needs three things: a data layer with clean events, a shared event ID and a server container (or direct API call) that sends to Meta.
  • Send hashed e-mail and phone with consent, and pass fbp, fbc, IP and user agent.
  • If a container is too much, you can call the Conversions API directly from your backend, but you lose reuse for other platforms.

Plugins exist for Shopify and WordPress. If your site is built from scratch, on Laravel, Rails, Django, Node, Next.js or anything else, there is no plugin and nobody to hand you a data layer. That is not a problem: the work is the same and you control it. This page shows the pieces, with code you can adapt. It follows how to set up the Conversions API and event deduplication. It also applies to single-page apps, which have their own traps.

1. Decide the events

Write the list first. For a store: view_item, add_to_cart, begin_checkout, purchase. For lead generation: generate_lead. Add the parameters each needs. See which events to send. The list is your specification and your test plan.

Set up in minutes

Connected in minutes

Add your domain, install the pixel, connect your ad platforms and watch the first events land.

2. Push events to the data layer

// when an order is placed (thank-you page, once per order)
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: "purchase",
  event_id: "ord_" + ORDER_ID,
  ecommerce: {
    transaction_id: ORDER_ID,
    value: ORDER_TOTAL,
    currency: "USD",
    items: ITEMS
  },
  user_data: { email: CUSTOMER_EMAIL, phone: CUSTOMER_PHONE }
});

Clear the previous ecommerce object before each push, as shown. Hash the e-mail and phone in the server container, or on your server, rather than sending plain values to third parties.

3. Send to your tagging server

Install the web container, and set the server container URL in the Google tag to your tagging subdomain. Open Tracked's Setup Wizard gives you ready container files for the web and server containers. See the setup guide and DNS configuration.

Try it

Works with your stack

Grab a logo and throw it. These are the tools Open Tracked already talks to.

Grab one. Throw it.

4. Add the Meta tag and event ID

In the server container, add the Conversions API tag, set the dataset ID and token, and map purchase to Purchase. Use the event_id from the event data. Do the same in the pixel tag in the web container so the two copies share the ID.

5. Single-page apps

  • Fire page_view on route changes, not only on first load.
  • Make sure the data layer is updated before the event fires.
  • Avoid firing purchase twice if the confirmation view re-renders.
  • Test the back button and refresh.

6. Direct API fallback

If you only need Meta and have a backend, you can call the Conversions API from your server. The example below is in Node.js and shows the shape. Hash e-mail and phone after trimming and lower-casing, and send the same event ID as the pixel.

const crypto = require("crypto");
const sha = v => crypto.createHash("sha256").update(String(v).trim().toLowerCase()).digest("hex");

await fetch(`https://graph.facebook.com/v21.0/${DATASET_ID}/events?access_token=${TOKEN}`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ data: [{
    event_name: "Purchase",
    event_time: Math.floor(Date.now() / 1000),
    event_id: "ord_" + orderId,
    action_source: "website",
    event_source_url: pageUrl,
    user_data: { em: [sha(email)], ph: [sha(phone)], client_ip_address: ip, client_user_agent: ua, fbp, fbc },
    custom_data: { currency: "USD", value: total }
  }] })
});

Keep the token in a secret store, not in code. Check Meta's current API version in its documentation.

Why a container is still worth it

The direct call works, and each new platform means new code, new token handling and new consent logic. A server container sends the same event to Meta, Google, TikTok and GA4 from one place. With Open Tracked, power-ups such as Cookie Keeper, the Data Store and Enricher, Visitor Location and Bot Detection are on every plan, so you do not build them.

Test

  1. Place a test order on a staging site.
  2. Check the data layer in the console.
  3. Open server Preview and the Meta tag's outgoing request.
  4. Check Meta Test Events for browser and server copies with the same ID.
  5. Compare Meta purchases with your orders for a week.
0 of 7 done
Works worldwide

Runs on your domain, anywhere

Your tracking runs on your own domain, so a visit from any country is handled the same way.

Frequently asked questions

Can I use the Conversions API on a custom website?

Yes. Build a data layer, share an event ID and send through a server container or direct API calls from your backend.

Do I need Tag Manager?

No, but a server container helps if you use several platforms.

How do I hash customer data?

Trim and lower-case, then SHA-256. Do not hash IP address or user agent.

What about single-page apps?

Fire events on route changes and make sure each purchase fires once.

Is there a ready container for custom sites?

Open Tracked's Setup Wizard gives you container files to start from.

Do I need spreadsheets to read my results?

No. Once tracking is live, the Open Tracked analytics shows spend, revenue, ROAS and profit, and you can ask Ari, the built-in AI assistant, questions about your own numbers in plain words. Ari's allowance depends on your analytics plan.

Is Open Tracked different from Open Track or Open Space Track?

No. Open Tracked is the official name of our server-side tracking platform, and the website is opentracked.io. Many people search for it as Open Track, OpenTrack or Open Space Track. All of them lead to the same product: server-side Google Tag Manager hosting, first-party analytics and a CRM pipeline.

Fix your tracking at the source

Open Tracked hosts your server-side Tag Manager, keeps first-party cookies alive and shows what each ad is really worth.

Open Tracked
Written by

The Open Tracked team

We build Open Tracked: server-side tracking hosting, analytics and the tools around them, for stores that spend on ads. Questions about this guide, or an idea for the next one?

Write to us Read the docs

Was this article helpful?

Comments

Loading comments...

Turn better tracking into better marketing performance

Start free