Meta Conversions API node for n8n

Meta Conversions APIsends Meta (Facebook) conversion events from n8n. Map raw values and the node normalizes and SHA-256 hashes them to Meta's spec, omits absent fields rather than sending a hash of an empty string, and keeps your access token in a credential instead of the workflow. MIT licensed. Source, npm.

Meta reference: Conversions API get started, server event parameters, customer information parameters

Setup

In n8n: Settings, Community nodes, Install, then enter the package name.

n8n-nodes-meta-conversions-api

Add a trigger, a Webhook is the common one, then add Meta Conversions API. Webhook into the node is the whole workflow.

  1. Dataset ID: from Events Manager under Data sources.
  2. Event Name and Action Source, plus Event Source URL for website events, which Meta requires.
  3. Map at least Email or Phone under Customer Information, plus Client IP Address and Client User Agent.
  4. Set Options, Test Event Code while testing, then remove it to go live.

Credential

The credential holds the token and nothing else. Dataset ID is a node parameter, because one token often covers several datasets and a node-level value can be an expression.

FieldWhere to find it
Access TokenEvents Manager, your dataset, Settings, Generate access token. For a token that outlives your personal login, use Business Settings, Users, System users, with the ads_management permission. Meta has five kinds of token and only two are worth using: which one to pick.
API VersionGraph API version, e.g. v23.0. Defaults to v23.0.

Test resolves the token's owner through the Graph API, which proves the token is valid and unexpired. It does not check access to a dataset, since the credential does not know which one you mean. A token that is valid but not permitted on a given dataset surfaces as an error on the node, naming it.

Parameters

ParameterWhat it isWhere to find it / accepted values
Dataset IDThe dataset the event is written to. Formerly the pixel ID.Events Manager, Data sources. The ID sits under the dataset name. Supports an expression, so one workflow can route to several datasets.
Event NameThe event Meta records.Meta's 17 standard events plus PageView, or Custom Event to type your own. A custom name must match Ads Manager exactly, including case.
Action SourceWhere the conversion happened. Required on every event.website, app, email, phone_call, chat, physical_store, system_generated, business_messaging, other. Must match the dataset type.
Event Source URLThe page URL the event happened on.Required by Meta for website events. Shown only when Action Source is Website.
Event IDDeduplication key against the browser pixel.Whatever your pixel sends as eventID for the same event. Leave empty and the node generates one from the execution ID, which is idempotent on retry but will not deduplicate against the pixel.
Event TimeWhen the event happened.Unix seconds (1784059038), Unix milliseconds, or an ISO date. Leave empty for now. Meta rejects the whole request if any event is over 7 days old.
ValueMonetary value of the conversion.Empty sends no value. 0 is sent as a real value. Required for Purchase.
CurrencyISO 4217 code for Value.Only sent when Value is set. Defaults to USD.

Value and currency

An event either has a value or it does not, and you should not need a Switch to express that. If Value resolves to empty, the node omits custom_data entirely. If it resolves to a number, the node sends value and currency. One field covers both cases.

0 is a real value and is sent. A non-numeric value such as N/A raises an error naming the item rather than booking the conversion at zero. Purchase is the one standard event where Meta requires a value, so the node refuses to send one without it.

Customer information

Map raw values. Each is normalized to Meta's rules and SHA-256 hashed where Meta requires it. Fields left empty are omitted, never sent as a hash of an empty string, because SHA256("") is a well-formed hash of nobody. Values that are already SHA-256 digests are passed through rather than hashed twice.

FieldSent asNormalization
Emailem, hashedTrimmed and lowercased. Values without an @ are dropped.
Phoneph, hashedDigits only, leading zeros stripped, no plus sign. Needs a country code, or set Default Country Calling Code.
First Namefn, hashedLowercased, punctuation removed.
Last Nameln, hashedLowercased, punctuation removed.
Cityct, hashedLowercased, spaces and punctuation removed.
Statest, hashedLowercased alphanumerics. Two-letter ANSI code for US states.
Zip Codezp, hashedLowercased, no spaces. US ZIP+4 truncated to five digits.
Countrycountry, hashedLowercase ISO 3166-1 alpha-2. usa is dropped, us is sent.
Date of Birthdb, hashedAny parseable date, converted to YYYYMMDD in UTC.
Genderge, hashedReduced to f or m.
External IDexternal_id, hashedYour stable user ID, trimmed. Keep it consistent across events.
Client IP Addressclient_ip_address, rawIPv4 or IPv6. An X-Forwarded-For chain is reduced to the client IP.
Client User Agentclient_user_agent, rawPassed through. Meta lists it as required for website events.
Fbc (Click ID)fbc, rawThe _fbc cookie. A bare fbclid is upgraded to fb.1.<time>.<fbclid>.
Fbp (Cookie ID)fbp, rawThe _fbp cookie.
Lead IDlead_id, rawMeta lead ad ID.
Subscription IDsubscription_id, rawYour subscription ID for this user.

Meta's phone format is Meta's alone

Meta wants bare digits: +1 (213) 373-4253 hashes as 12133734253, with no plus sign. Other ad platforms disagree, and every wrong shape still returns events_received: 1. Map the raw number and let the node format it.

Where fbc and fbp come from: the _fbc and _fbp cookies set by the Meta pixel on your site. If you have no pixel, pass the fbclid query parameter from the landing URL as Fbc and the node formats it. Both are the strongest signals available, because they tie the event to an actual ad click.

Custom data

Key and value pairs sent inside custom_data, such as content_name or your own fields. Values are sent as-is.

Reserved keys

Server event parameters such as action_source, event_name and event_id live at the top of the event, not inside custom_data. Meta ignores them when nested, so the node rejects them here and points at the option that sets them.

Options

Meta reference: main body parameters

OptionWhat it does
Test Event CodeRoutes the event to Test Events instead of counting it. Events Manager, your dataset, Test Events. The code is per-dataset.
Default Country Calling CodePrepended to phone numbers that arrive without one, e.g. 1. A phone without a country code will not match.
API VersionOverrides the Graph API version from the credential.
Opt OutUses the event for attribution only, not for delivery optimisation.
Action Source URL ReferrerThe HTTP referrer of the page that triggered the event.
Limited Data UseApplies Meta's LDU flag. Reveals country and state options.
Batch EventsSends all input items in one request, up to Meta's limit of 1000, grouped by dataset. Off by default: Meta rejects the entire batch if any single event is invalid.

Output

Meta reference: using the API

One item per event, carrying Meta's response and the event as sent.

{ "events_received": 1, "messages": [], "fbtrace_id": "AfGdnLPtkz0_2Tw-U3Rl87K", "dataset_id": "1234567890123456", "test_event_code": "TEST12345", "event": { "event_name": "Schedule", "event_time": 1784059038, "action_source": "website", "user_data": { "em": ["87924606b4131a8ace...."], "client_ip_address": "254.254.254.254", "client_user_agent": "Mozilla/5.0 ..." }, "event_id": "12345", "event_source_url": "https://example.com/thanks", "custom_data": { "value": 5, "currency": "USD" } } }

The event is returned exactly as it reached Meta, so you never have to guess what was hashed: an email mapped in raw leaves as a digest under em. test_event_code is present only when set, so a test send is distinguishable from a real one in the output.

Errors

The node validates before sending and fails on the item at fault. Turn on Settings, Continue on fail to route failures to a second branch instead.

CheckFails whenWhy
Event Source URLEmpty on a website eventMeta requires it
Event TimeOver 7 days oldMeta rejects the whole request, not just that event
ValuePresent but not a numberOtherwise the conversion books at 0 silently
PurchaseNo valueMeta requires value and currency on Purchase
Custom DataUses a reserved keyMeta ignores server event parameters nested in custom_data
Customer InformationNothing survives normalizationAn event with no identifier cannot be attributed to anyone

Testing

  1. Events Manager, your dataset, the Test Events tab. Copy the test event code. It is per-dataset.
  2. On the node, under Options, add Test Event Code and paste it.
  3. Execute. The event should appear in Test Events within a few seconds.
  4. When it looks right, remove the code. While it is set, the event does not count as a real conversion.

In Test Events, Received from: Server confirms the event came from the API rather than the pixel, and User data keys lists the identifiers Meta actually read out of it, which is the only place you can see that the hash survived the trip.

events_received: 1 is not success

It means Meta parsed the request. Not that the event was accepted, matched, attributed, or treated as a test. An event with no usable identifiers returns exactly the same response as one that worked. Judge the setup on event match quality in Events Manager, never on the response.

Events return success but never appear in Test Events? The action source usually does not match the dataset type. An offline event set will not show website events: Meta accepts the request, answers events_received: 1, and counts the event as a real conversion instead of a test. Offline datasets need physical_store. Also check the marketing-channel selector on the Test Events tab, which filters what you see, and confirm the code came from the dataset you are sending to.

Best practices covers what Meta asks you to do beyond getting the request accepted.