Growth Infrastructure

The Unsexy but Most Powerful Conversions API Setup

No one brags about server-side tracking, but it is the thing that makes your Meta ads optimize properly. Here is the full setup, step by step: your payment system tells n8n about each sale, Claude Code wires it up, and n8n sends it to Meta. No plugin, no browser in between.

Watch the video

The Systems Summary

Nobody posts a highlight reel about server-side tracking, it is unsexy. But the Conversions API (CAPI) is the single most powerful thing you can set up for your Meta ads, because it feeds the algorithm clean, confirmed sales to optimize on.

This guide uses one rule: server-side only. Your payment system (Razorpay in the example) tells n8n about each sale, Claude Code writes the mapping, and n8n sends the sale to Meta. No visitor's browser sits in between, so ad blockers and closed tabs cannot lose the sale. Never used n8n before? Read what is n8n first. This setup is the tracking stage of my full AI performance marketing workflow.

Why "Unsexy" Actually Means Most Powerful

Everyone wants to talk about creative and targeting. Almost no one wants to talk about tracking, it is technical and unglamorous, and that is exactly why it is an edge. In 2026, browser signals leak from iOS, cookie blocking, and ad blockers, so the pixel alone misses a big chunk of your conversions. The Conversions API sends purchase data server-to-server, straight to Meta, so the algorithm sees the full picture and optimizes on real revenue.

Here is why the "unsexy" route is actually the most powerful one. Dedicated providers like Stape do server-side tracking well, but that is all they do, and they charge a recurring subscription for it. Building it on n8n costs a fraction of that because you self-host it, and you get far more flexibility: the same tool that sends your conversions can also fire WhatsApp messages, sync leads to your CRM, and run the rest of your business automations. You are not renting one narrow feature, you own a platform that does this and everything else.

And you do not need to be technical to set it up: Claude Code handles the code and debugging for you.

Pro-Tip

Set up CAPI before you scale spend, not after. Every day you run ads without clean server-side data is a day the algorithm optimizes on an incomplete picture.

When You Need This Setup

If your site runs on Shopify or WordPress, Meta's ready-made partner connection in Events Manager is the easier route, use that. This setup is for everything the ready-made connections miss:

  • Custom-built websites with no plugin to install.
  • Razorpay (or other) payment pages where the sale happens outside your site builder.
  • Lead forms that save to Google Sheets or a CRM instead of a store.
  • Sales that close on WhatsApp or a phone call, marked as won in a sheet or CRM.
  • Agencies who want one setup they can repeat for every client.

The 3 Ingredients, Mapped Out

The whole setup is just three pieces connecting in one direction: your sale → n8n (wired up with Claude Code) → Meta's Conversions API. Click each ingredient to see its role and exactly what you need:

Server-Side Conversions API Setup

3 Ingredients You Actually Need

Meta Ads

Where the data goes, and the keys you need
Its Role

Meta is the destination. Your server-side purchase events flow here so the ad algorithm learns what actually drives sales. To connect, you generate two things inside Events Manager: your dataset ID and a Conversions API access token.

What You Need
Business Manager accountDataset / Pixel IDConversions API access tokenEvents Manager access
In Practice

In Events Manager → your dataset → Settings → Conversions API → "Generate access token." Copy that token and the dataset ID, those two values are everything the workflow needs from Meta. (Heads up: the token expires about every 90 days, so rotate it.)

Browser-Side vs Server-Side: Who Sends the Sale?

There are two ways n8n can hear about a sale. Tap each one to see why this guide only uses the second:

Who Sends the Sale to n8n?

Browser-Side vs Server-Side

Browser-Side

Avoid
Core Objective

Code running in the customer's phone or laptop browser tells n8n that a sale happened. It sounds simple, but the message travels from the customer's device, so anything on that device can stop it, and the browser treats your n8n address as an outsider.

Key Action Items
Ad blockers can block itLost if the tab closes earlySeen as third-partyOnly knows what the page knows
Simple Example

A customer pays on a Razorpay page and closes the tab before the thank-you page loads. The browser never sends the sale, so Meta never hears about it, and your campaign optimizes as if that sale never happened.

Who Tells n8n About a Sale

Razorpay checkout

Razorpay calls your n8n webhook the moment a payment is captured.

Shopify store

Shopify's order-created webhook sends each new order.

WooCommerce

WooCommerce's order webhook sends each new order.

Google Sheets lead form

n8n watches the sheet and picks up every new row.

Meta lead form

n8n's lead ads trigger receives each new lead.

WhatsApp or phone sale

Mark the deal as won in your CRM or sheet, and n8n picks it up.

Step 1: Get Your Meta Keys

Meta is the destination, the place your server-side events are sent so campaigns can optimize. You generate your keys inside Events Manager. You need two values, plus a Business Manager account:

• Dataset / Pixel ID: the ID of the dataset your events belong to (Events Manager → Data Sources → your dataset → Settings).
• Conversions API access token: in that same Settings tab, find the Conversions API section, choose "Set up manually," and click Generate access token. Meta sets up a Conversions API system user for you, no app review required.

Copy the token the moment it appears, Meta does not show it again. If you lose it, you generate a new one.

Pro-Tip

Paste the token into Meta's Access Token Debugger to see its expiry. Tokens made through a system user normally do not expire, but they stop working if someone revokes them or removes the system user, so treat the token like a password and keep it only inside n8n.

Step 2: Plan Your Events With Claude

Before building anything, decide what to send. Ask Claude with the prompt below, changing the first sentence to match your business.

Prompt to copy: plan your events
I sell a course through Razorpay and collect leads through a form on my website. Which Meta Conversions API events should I send, when should each one fire, and which customer details should each one include? Give me a table, and tell me which details must be hashed.

The Usual Event Plan

For most businesses, Claude comes back with something like this:

EventWhen it firesComes fromCustomer details to include
PurchasePayment is capturedRazorpay webhookEmail, phone, name, city, value, currency, Meta cookies, browser info
LeadA form is submittedForm backend or Google SheetsEmail, phone, name, Meta cookies, browser info
Purchase (offline)A WhatsApp or phone deal is marked wonCRM or sheetEmail, phone, value. This one is an offline sale, not a website event

Step 3: Connect Razorpay to n8n

The example uses a Razorpay checkout, the classic "no plugin exists" case. In this guide, your n8n lives at n8n.example.com; use your own address.

  • In n8n: add a Webhook node as the trigger. Copy its production link, for example https://n8n.example.com/webhook/razorpay-capi.
  • In Razorpay: go to Dashboard → Account & Settings → Webhooks → Add new webhook. Paste the n8n link, set a secret, and tick the payment.captured event.
  • Check the signature first: Razorpay signs every call with your secret in the X-Razorpay-Signature header (HMAC SHA256 of the raw body). Ask Claude Code to add this check as the first step, so nobody else can send fake sales to your link.
  • Convert the amount: Razorpay sends amounts in paise. Divide by 100 before sending the value to Meta, or your ₹2,499 sale shows up as ₹2,49,900.
  • Expect repeats: Razorpay can send the same webhook more than once. Step 6 (the event ID) makes Meta ignore the repeats.
Your site
Server creates the orderCopies _fbp, _fbc, browser info and page address into the order notes
Customer paysRazorpay checkout
Razorpay
payment.captured webhookPayment details + your notes, signed with your secret
n8n
Check the signatureRejects anything Razorpay did not send
Map and hashPaise to rupees, hash email and phoneClaude Code
Meta
Conversions APIPurchase event, event ID = Razorpay order ID
Server to server from start to finish: no visitor's browser ever sends anything to n8n.

Step 4: Carry the Meta Cookies Through Checkout

Server-side has one catch: Meta matches a sale to the right ad much better when it also gets a few details from the customer's browser, and a payment webhook does not have them on its own.

• _fbp: a Meta cookie that says "this is the same browser Meta has seen before".
• _fbc: a Meta cookie that says "this person arrived from a Meta ad click".
• Browser info (the user agent): Meta requires it for website events.
• The page address where the purchase happened: also required for website events.

The fix is simple and still server-side. When your site's server creates the Razorpay order, the customer's request already carries those cookies and the browser info. Your server copies them into the order's notes, and when the payment is captured, Razorpay's webhook delivers them to n8n together with the email and phone. Nothing is sent from the browser to n8n.

Razorpay notes allow up to 15 fields of up to 256 characters each. Browser info can be longer than that, so split it across two fields (for example ua_1 and ua_2) and have Claude Code join them back in n8n. The _fbc cookie only exists when someone arrived from an ad click, so if it is missing, that is normal: send what you have.

Pro-Tip

Do not skip this step. A payment webhook knows who paid, but not which ad they came from. Without the Meta cookies and browser info, Meta struggles to connect the sale to your ad, so your campaigns optimize on weaker data, and Meta requires the browser info and page address for website events anyway. Copy them into the Razorpay order notes when your server creates the order. It takes Claude Code a few minutes, and it is the difference between a sale Meta can use and a sale it mostly cannot.

Step 5: Let Claude Code Build the Mapping

This is the step that makes the whole thing doable if you are not a developer. Claude Code is Anthropic's agentic coding assistant, and it writes the n8n code node that turns a Razorpay payment into a Meta event. You can start from the ready-made n8n CAPI template and let Claude Code adapt it.

Paste a real Razorpay webhook sample (the JSON n8n shows for the Webhook node) into Claude Code along with the prompt below, so it writes the mapping against your actual field names instead of guessing. When Meta rejects an event, paste the error back and Claude Code fixes it. One rule from Meta worth knowing: events older than 7 days are rejected, so the workflow should send each sale as soon as it arrives.

Wiring up CAPI is one piece of a much bigger shift, running the whole ad account with AI as the method, which is what our AI-first performance marketing course is built around. If you would rather have an expert check whether your pixel and Conversions API are sending the right events, that is part of my Meta ads consultation.

Prompt to copy: build the mapping
Here is a sample Razorpay payment.captured webhook from my n8n Webhook node. Write an n8n Code node that turns it into a Meta Conversions API Purchase event:

- First, verify the X-Razorpay-Signature header (HMAC SHA256 of the raw body with my webhook secret). Stop if it does not match.
- event_name "Purchase", action_source "website", event_time = payment time in seconds, event_source_url = the page address from the order notes.
- event_id = the Razorpay order ID.
- Clean and SHA-256 hash the email (trim, lowercase) and phone (digits only, with country code 91).
- Send fbp, fbc and the browser user agent from the order notes as they are, not hashed. Join ua_1 and ua_2 if the user agent was split.
- value = amount divided by 100 (Razorpay sends paise), currency "INR".

Then show me the final JSON you would send, so I can check it before going live.

Step 6: Stop Meta Counting a Sale Twice

Keep your Meta Pixel on the site. It still catches browser events like page views and add-to-cart, and it reports the purchase too. Now Meta hears about the same sale twice: once from the Pixel and once from n8n.

Meta removes the duplicate when both reports carry the same event ID and the same event name, and arrive within 48 hours of each other. So:

• In the Pixel's Purchase event on your thank-you page, pass the Razorpay order ID as eventID.
• In n8n, send the same order ID as event_id, with the same event name, "Purchase".

Meta keeps one and drops the other. The same ID also stops Razorpay's repeated webhooks from being counted twice.

Pro-Tip

Use the order ID, not the payment ID. Your thank-you page and the webhook both know the order ID, so the two reports always match.

Step 7: Test It in Events Manager

Never go live without seeing a real event arrive:

  • Get a test code: Events Manager → Data Sources → your dataset → Test Events. Copy the test code it shows.
  • Add it to n8n: send it as test_event_code in the request, only while testing.
  • Make a test payment on your checkout (a small real payment you refund, or Razorpay test mode while you build).
  • Watch it arrive: the Purchase event appears in the Test Events window, received from the server. If the Pixel also fired, check that Meta shows the pair as deduplicated.
  • Remove the test code before going live. Meta says it is only for testing.
Events Manager
Open Test EventsCopy the test code
n8n
Add test_event_codeOnly while testing
Checkout
Make a test paymentSmall payment you refund, or Razorpay test mode
Check the result
Purchase arrivesReceived from the server
DeduplicatedIf the Pixel fired too, Meta keeps one
Go live
Remove the test codeReal sales now flow to Meta
Never go live until you have seen a real event arrive from the server.

Step 8: Read and Improve Event Match Quality

Event Match Quality is Meta's score out of 10, shown beside each event in Events Manager with a rating label. It tells you how well Meta can match your events to real people, and better matching means better optimization. A Purchase from a checkout, with email and phone, should be one of your best-scoring events. If it reads low, check these:

What lowers the scoreThe fix
No email or phone sentSend both from the payment record, hashed
Email or phone hashed without cleaning firstTrim and lowercase the email; digits only with country code for the phone; then hash
No _fbp or _fbcCopy the cookies into the Razorpay order notes (Step 4)
No browser infoCopy the user agent into the notes; Meta requires it for website events
Few details overallAdd name, city and country where you have them, hashed

Does Sending Through Your Own n8n Server Count as "Third-Party"?

A question every agency asks: if a client's sales go to my n8n server and then to Meta, will Meta treat it as third-party or restrict the domain?

For Meta, no. Meta identifies your events by the client's dataset ID and access token, not by which server sends them. The event also carries the client's page address, so it belongs to the client's site. Agencies, Zapier and Shopify all send events on behalf of other businesses every day.

What does get a dataset restricted is the content of the events, not the sender:
• businesses in sensitive categories, such as health or finance, sending details Meta does not allow for them
• customer details sent unhashed, or tucked into page addresses and custom fields
• fake or duplicated purchases

The real "third-party" problem only appears in the browser: when a website's page sends events straight from the visitor's browser to another domain. That is exactly why this guide is server-side only.

Advanced: If a Browser Must Send Events to n8n

Sometimes you cannot avoid it, for example a page event that only exists in the browser. To a browser, clientsite.com sending to n8n.example.com looks like an outsider, so ad blockers may stop it and it cannot read the client's cookies.

The fix is to give your n8n server a second name under the client's domain, like track.clientsite.com. This is pointing, not forwarding: the browser looks up where track.clientsite.com lives in the internet's phonebook (DNS), then talks to your n8n server directly while still calling it track.clientsite.com. With a forward, the browser would end up visibly talking to n8n.example.com, which defeats the point.

Add one of these records in the client's domain settings:

Record typeNamePoints toUse it when
CNAMEtrackn8n.example.comRecommended. If your server's address changes, every client alias follows automatically
AtrackYour server's IP, e.g. 203.0.113.10Your n8n sits behind Cloudflare's proxy, so a CNAME from another account would be blocked

Common DNS Mistakes

  • Cloudflare error 1014, "CNAME Cross-User Banned": you see this when the client's CNAME points to a hostname that is proxied (orange cloud) in a different Cloudflare account. Use the A record instead, or Cloudflare for SaaS (custom hostnames), which is built for exactly this.
  • No padlock for the new name: your n8n server must accept track.clientsite.com and hold a security certificate for it, or the browser shows a warning. Add the name to your web server settings (nginx or Caddy) and issue a free Let's Encrypt certificate. Caddy does it automatically.
  • Changes are not instant: DNS updates usually work within minutes, but can take a few hours.

Privacy: You Are Handling Your Client's Customer Data

When raw customer emails and phone numbers reach your n8n server before they are hashed, you are processing your client's customer data. Under India's Digital Personal Data Protection (DPDP) Act, that needs to be covered:

• Agree it in writing with the client: what data you receive, why, and that you do not keep it.
• The client's privacy notice should say that purchase data is shared with advertising partners like Meta.
• Hash as early as possible in the workflow, and do not store raw details in n8n's execution logs longer than needed.

This is not legal advice. If the client is in a regulated industry, they should check with their own lawyer.

Keeping It Running

  • Check Events Manager diagnostics weekly for warnings about missing parameters or failed events.
  • Re-test after every site or checkout change, a renamed field can silently break the mapping.
  • Watch the token: if events suddenly stop, check the access token first (revoked or removed system user) and generate a new one.
  • Keep an eye on n8n: one self-hosted instance can run this workflow alongside every other automation you build. Make sure it is backed up.

Frequently Asked Questions

What exactly do I need from Meta to set this up?
Two things from Events Manager, plus a Business Manager account: your dataset (Pixel) ID, and a Conversions API access token generated under your dataset's Settings → Conversions API → Generate access token. No app review is required.
Is the Conversions API token the same as the access token?
They are effectively the two values people mean when they say "access token and Conversions API token." In practice you need the dataset/Pixel ID and one access token generated specifically for the Conversions API in Events Manager.
Do I need to be a developer to build this?
No. Claude Code writes the technical bits: the signature check, the field mapping, the hashing of customer data, and any debugging. You describe the requirement in plain English and paste back any errors.
Why not just use the browser pixel?
The pixel alone loses conversions to iOS restrictions, cookie blocking, and ad blockers. The Conversions API sends data server-to-server so Meta receives events the browser misses. Keep both, and use the same event ID so Meta counts each sale once.
Does sending events from my own n8n server count as third-party?
Not for Meta. Meta identifies events by the dataset ID and access token, not by the sending server. Third-party issues only appear when a visitor's browser sends events to another domain, which is why this setup is server-side only.
Will Meta count my purchase twice if both the Pixel and n8n send it?
Not if both send the same event ID and the same event name within 48 hours. Use the Razorpay order ID as the event ID in both places.
What is a good Event Match Quality score?
Meta scores it out of 10 with a rating label in Events Manager. Higher is better. A Purchase event with email, phone, the Meta cookies and browser info should score among your best events. If it is low, check the Step 8 table.
How is this different from a dedicated tool like Stape?
Dedicated server-side tracking providers like Stape do the Conversions API well, but that is their entire scope, and they charge a monthly subscription. Running it on n8n costs a fraction because you self-host it, and the same platform also sends WhatsApp messages, syncs leads, and automates the rest of your business.
How often do I have to maintain it?
Rarely. Check Events Manager diagnostics weekly, re-test after checkout changes, and generate a new access token if it is ever revoked. Otherwise the workflow keeps sending events on its own.

Want the Whole Tracking System, Not Just CAPI?

My Performance Marketing course covers tracking end to end: Pixel, Conversions API, Google Tag Manager, GA4 and attribution, plus Meta, Google and ChatGPT ads, creative and AI, with ready-to-use kits including the Advance Tracking Blueprint, and a Discord community where I answer your questions. ₹2,499.

See the Course
Weekly newsletter

Join AI Growth Weekly.

Honest takes on marketing, AI and growth, from someone who does this every day.

Free. One email a week. Unsubscribe anytime.

Piyush Sachdeva

By Piyush Sachdeva.

AI-first marketing and growth consultant. Founder of Social Masla. Creator of Pulse. Best-selling author of The Growth Engine: Beyond AI and Advertising.