← Blog

·

Meta Conversions API for WhatsApp: sending the sale back to your ads

Updated on October 25, 2026

The Conversions API for Business Messaging is Meta’s official way to report that a conversation started by a Click-to-WhatsApp ad turned into a sale, a lead or another outcome. You capture the ctwa_clid from the webhook, store it with the conversation and, when the event happens, send a POST to the dataset of your WhatsApp Business account with action_source: "business_messaging" and messaging_channel: "whatsapp". The event shows up in Events Manager and gets attributed to the ad.

This guide covers the requirements, the step-by-step setup, the supported events, a Node.js example, and how to handle duplicates and personal data.

Why send the sale back

Without this feedback, Meta only sees the top of the funnel: how many people clicked and started a conversation. The sale happens later, in the chat or at your checkout, and stays invisible to Ads Manager. With the Conversions API, you give Meta the real outcome of each click.

The first step is having attribution in your own system: storing the webhook’s referral and linking the order to the click. That’s covered in how to know which ad generated the sale. This article picks up where that one ends.

Requirements

Per the Conversions API for Business Messaging onboarding guide, for Click-to-WhatsApp ads you need:

RequirementDetail
Meta developer appCreated in the App Dashboard
whatsapp_business_management permissionWith advanced access
whatsapp_business_manage_events permissionWith advanced access; apps that already have advanced access to whatsapp_business_messaging are approved automatically when they apply
Marketing API access levelThe “Marketing API Access Tier” feature on the app
Cloud API integrationHosted by Meta (the recommended option)
Token with both permissionsSystem user, business integration system user, or Embedded Signup token

To generate a token that doesn’t expire, see permanent token with a system user.

Step by step

1. Find your waba_id

It’s the WhatsApp Business account ID. You can find it in WhatsApp Manager and in the webhook, in the entry[].id field.

2. Create or retrieve the dataset

A dataset is where Meta collects events from different sources (website, app, physical store, chats). It’s owned by the business. A POST to the WhatsApp Business account’s dataset endpoint creates one, or returns the existing one:

curl -X POST "https://graph.facebook.com/v26.0/WABA_ID/dataset?access_token=TOKEN"

A GET on the same endpoint returns the existing dataset_id. The response is an ID: store it, it’s where your events go.

3. Capture the ctwa_clid

The ctwa_clid arrives in the referral object of the incoming message when the conversation starts from a Click-to-WhatsApp ad. Meta describes it as a personal identifier, unique per click, and recommends storing it with the conversation. It’s not included for ads shown in WhatsApp Status.

4. Send the event

When the conversion happens, send it to /{DATASET_ID}/events:

curl -X POST "https://graph.facebook.com/v26.0/DATASET_ID/events?access_token=TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": [
      {
        "event_name": "Purchase",
        "event_time": 1761400000,
        "action_source": "business_messaging",
        "messaging_channel": "whatsapp",
        "user_data": {
          "whatsapp_business_account_id": "WABA_ID",
          "ctwa_clid": "ARAkLkA8rmlFeiCktEJQ-QTwRiyYHAFDLMNDBH0CD3qpjd0HR4..."
        },
        "custom_data": {
          "currency": "BRL",
          "value": 297.00
        }
      }
    ]
  }'

event_time is the conversion time in Unix seconds. The official example also includes partner_agent, a field partners use to identify themselves; if you integrate directly without a partner, it doesn’t apply.

5. Check Events Manager

After you send it, the event appears in Events Manager under the dataset. That’s where you confirm the integration is working.

Supported events

According to the FAQ in the official guide, the Conversions API for Business Messaging supports:

EventWhen to use it
PurchasePayment confirmed
LeadSubmittedPerson sent the requested details (name, email, interest)
QualifiedLeadLead qualified by your team or an AI agent
ViewContentPerson viewed a product or catalog in the chat
AddToCartItem added to cart
InitiateCheckoutPayment link or PIX code generated (PIX is Brazil’s instant payment system)
CartAbandonedCart not completed
OrderCreatedOrder created
OrderShippedOrder shipped
OrderDeliveredOrder delivered
OrderCanceledOrder canceled
OrderReturnedOrder returned
RatingProvidedCustomer gave a score (for example, a post-purchase NPS)
ReviewProvidedCustomer left a review

Meta adds a caveat: these events should represent interactions that happen in the messaging thread. If the purchase happens on your website or app, use the Conversions API for web or app events, with the matching action source.

Node.js example

The example below sends Purchase when the order is paid, using the ctwa_clid stored with the conversation. It flags the order as sent to avoid repeating the event, because Meta doesn’t deduplicate events for this API: the official recommendation is for advertisers to deduplicate before sending.

const GRAPH = 'https://graph.facebook.com/v26.0';
const { META_CAPI_TOKEN, DATASET_ID, WABA_ID } = process.env;

export async function sendPurchase(order, db) {
  if (!order.ctwa_clid || order.capi_sent_at) return; // no click or already sent

  const body = {
    data: [{
      event_name: 'Purchase',
      event_time: Math.floor(new Date(order.paid_at).getTime() / 1000),
      action_source: 'business_messaging',
      messaging_channel: 'whatsapp',
      user_data: { whatsapp_business_account_id: WABA_ID, ctwa_clid: order.ctwa_clid },
      custom_data: { currency: 'BRL', value: order.total },
    }],
  };

  const r = await fetch(`${GRAPH}/${DATASET_ID}/events?access_token=${META_CAPI_TOKEN}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });

  const result = await r.json();
  if (!r.ok) throw new Error(`CAPI: ${result.error?.message ?? r.status}`);

  await db.markCapiSent(order.id, new Date());
  return result;
}

If you prefer no-code tools, the same POST can go out from an HTTP node in n8n.

Without a ctwa_clid: hashed customer data

Not every conversion has a ctwa_clid, for example a conversation that started before you began storing the click. In that case, the official guide lets you send SHA-256 hashed customer data instead of the click, and Meta tries to match the event to an ad. Rules for this path:

  • user_data must include page_id (the Facebook Page ID). Without it, the event is rejected, even with valid customer data.
  • Include at least one customer parameter, such as ph (phone) or em (email), normalized and SHA-256 hashed.
  • external_id isn’t used for matching on this path.
  • Attribution only covers ad interactions from the past 7 days and is available in a subset of countries.
import { createHash } from 'node:crypto';

const sha256 = (v) => createHash('sha256').update(v).digest('hex');

// phone as digits only, with country code: 5511988887777
const user_data = {
  page_id: process.env.PAGE_ID,
  whatsapp_business_account_id: process.env.WABA_ID,
  ph: [sha256('5511988887777')],
};

Whenever you have the ctwa_clid, use it: Meta says it matches more reliably and doesn’t have these limits.

Things to watch

  • Duplicates. Send each conversion once. Use a flag on the order (such as capi_sent_at) or a table of sent events.
  • One dataset per Page. The guide says only one dataset can be linked to a Page. If you already use the Conversions API for your website, you can reuse the existing dataset; Meta says adding business messaging doesn’t interfere with the current integration.
  • Personal data. The ctwa_clid and hashed phone numbers are personal data. Document the legal basis, limit access and set a retention period. If you operate in Brazil, see LGPD and WhatsApp (LGPD is Brazil’s data protection law); this is not legal advice.
  • Token on the server. The Conversions API token never goes to the browser or the customer’s app.

How to do it with Vectalk

Vectalk forwards webhooks in Meta’s format, so the referral with the ctwa_clid reaches your URL unchanged, ready to be stored (webhooks docs). The Conversions API call goes from your server straight to Meta, using an app and a token with the permissions listed above. If sales close through re-engagement, PIX and cart recovery inside the free window opened by the ad helps increase the conversions you report. Create your account at apps.vectalk.com.br/register.

Frequently asked questions

Do I need the Meta Pixel to use the Conversions API on WhatsApp?

No. For chat events, the destination is a dataset linked to the WhatsApp Business account, created through the dataset API or Events Manager. The Pixel is for website events.

Can I send a sale that happened on my website?

Yes, but not through this path. Business messaging events should represent interactions inside the chat. For website purchases, use the Conversions API for web.

How long after the click can I send the event?

With a ctwa_clid, the guide doesn’t set a deadline. Without it, using hashed data, attribution only covers ad interactions from the past 7 days; later events are accepted but not attributed.

Does Meta deduplicate events sent twice?

Not for this API. The official guide recommends that advertisers deduplicate before sending.

What goes in custom_data?

The conversion value and currency, for example "currency": "BRL" and "value": 297.00 for a sale of R$ 297.00 (Brazilian reais).


Official sources checked on October 25, 2026: Conversions API for Business Messaging, Customer information parameters, Text messages webhook (referral), Access tokens, Vectalk: webhooks.

Integre o WhatsApp oficial ao seu sistema

A Vectalk entrega a Cloud API da Meta com os mesmos payloads e webhooks, um token para todas as contas e documentação completa.