Analytics
Conversion Reporting
Report WhatsApp-attributed purchases and product views to Meta’s Conversions API via Connectly 🧾
POST
Conversion Reporting
When a customer clicks a Click-to-WhatsApp (CTWA) ad and later purchases on your site, Connectly can forward that conversion event to Meta’s Conversions API on your behalf — so the originating ad gets credit in Ads Manager. You send the event to Connectly; you never need to talk to Meta directly.
The cutoff slides forward continuously, so a timestamp accepted in yesterday’s batch can legitimately be refused today — which is why the error names the current one.
Purchases are deduplicated on
Connectly forwards each
Endpoint
Integration journey
1
Get your API key
Open the Connectly inbox → Settings → General → API Key. Create a new key with all scopes unchecked (full access) or reuse an existing one if you still have the plaintext. The key is shown only once — copy and store it securely. Never expose it client-side or commit it to source control.
2
Enable purchase tracking in your campaign
In the Flow Builder, open the Audience step of your Click-to-WhatsApp card and tick “Track purchases completed on my own site and report them to the Ads Manager”. Without this, carousel CTA links will not carry the required tracking parameters.
3
Capture tracking parameters at landing
Once your campaign sends, Connectly auto-appends five query parameters to every CTA link:Persist all five values when the customer lands on your site — store them in the session or against the customer record — so they’re available at checkout.
4
Call the conversion endpoint on purchase
When the customer completes a purchase, POST a single conversion event to Connectly with the tracking parameters captured at landing.
5
Verify in Ads Manager
Connectly forwards the event to Meta. Conversions typically appear in Meta Events Manager and roll up into Ads Manager attribution within a few hours.
Request body
Top-level fields
string
required
Verbatim copy of the
cnct_tracking_id query parameter from the landing URL. Identifies the originating WhatsApp/CTWA session at the customer level.string
required
Meta CAPI event name. Accepted values:
"Purchase", "AddToCart", "ViewContent" or "LeadSubmitted". Any other value returns 400 INVALID_ARGUMENT.Send AddToCart when the customer adds a product or plan to their cart on your site. Every payload field is optional for it; send currency and value together when you include a price.You only need to send LeadSubmitted and ViewContent for activity on your own site. Connectly already reports both automatically for in-WhatsApp activity — ad clicks, button taps and link clicks inside the conversation.string
required
Verbatim copy of the
sendout_id query parameter from the landing URL. Credits the conversion to the correct Connectly campaign.object
required
CTWA attribution data.
object
required
Per-event detail. For
Purchase, currency and value are required. For AddToCart they are optional, but must be sent together: one without the other returns 400 INVALID_ARGUMENT.Example request
Response
events_received: 1 confirms Connectly received and recorded the event. Connectly logs the conversion to your campaign analytics regardless of whether the Meta CAPI forward succeeds. If Meta rejects the event, you receive a non-200 response with Meta’s verbatim error message.
forward_reference_id is the reference the attribution network returned for this event — Meta’s fbtrace_id today. Quote it when raising a support case about an event that doesn’t appear in Events Manager. It is empty when no forward fired, for example a Purchase whose order_id was already reported (see Deduplication).
Error responses
Every validation failure returns the same status anderrorType — 400 with ERROR_TYPE_INVALID_ARGUMENT. There is no distinct code per field, so if you need to branch on which check failed, read details: the rejected field is the key and the reason is the value (for example { "event_time": "too_old" }).
Notes
Send one event per API call. For multi-item orders, include all items in the
contents[] array within a single Purchase event — do not send multiple POST requests for the same order.cnct_tracking_id,sendout_id,ctwa_clid, andad_idmust be captured from the landing page URL at visit time and passed back when the customer converts — which may happen later in the same session.- Set
event_timeto the actual order timestamp, not the time you call the API — but keep it within the last 7 days. See Event time must be recent. - Retrying a
Purchasethat carriesorder_idis safe: it reaches Meta once. Retries of any other event, or of aPurchasewithoutorder_id, each count again. See Deduplication.
Event time must be recent
event_time may be backdated — that is what it is for — but only up to 7 days. Meta’s limit is unusually strict about what happens past it:
TheThe failure is all-or-nothing: one stale timestamp doesn’t cost you that one event, it costs every event in the request. This matters most for backfills and batch flushes — exactly the cases where backdating is tempting. If you are replaying older conversions, anything past 7 days can no longer be reported; send it with noevent_timecan be up to 7 days before you send an event to [Meta]. If anyevent_timeindatais greater than 7 days in the past, we return an error for the entire request and process no events.
event_time and it will be recorded as happening now, or leave it out entirely.
Connectly refuses a too-old event_time before it reaches Meta, so you get an error naming the offending value and the current cutoff rather than a request-level rejection from Meta:
Deduplication
Meta does not deduplicate conversions sent through this API. Their Business Messaging documentation is explicit:Meta does not assist with deduplicating events for Conversions API for Business Messaging so we highly encourage advertisers to perform deduplication before sending them over Conversions API for Business Messaging.The 48-hour
event_id deduplication Meta documents elsewhere applies to events sent to a Pixel ID. Conversions reported here are Business Messaging events, attributed through ctwa_clid, and that mechanism does not cover them.
Purchases are deduplicated on order_id
Connectly forwards each Purchase to Meta once per order_id, per Connectly business, for 45 days:
- A retry is safe. Sending the same
order_idagain returns200withevents_received: 1and an emptyforward_reference_id, and nothing is forwarded a second time. - An order Connectly’s AI agent already reported counts once too. If the agent reported a purchase for an
order_id, your report of the sameorder_idis not forwarded again, and the reverse. - A failed forward can be retried. If Meta rejected the event, you get an error and the
order_idis released, so your retry is forwarded. - A timeout is not retried into a duplicate. If Connectly could not tell whether Meta received the event (the call to Meta timed out or was cut off), the
order_idstays claimed and a retry is answered as received. A lost purchase is the safer outcome than one counted twice. - After 45 days the same
order_idis forwarded again.
What is still yours to prevent
- A
Purchasewithoutorder_idhas nothing to deduplicate on: every call counts. AddToCart,ViewContentandLeadSubmittedare not deduplicated: every call counts, whateverevent_idyou send.- A browser pixel reporting the same sale counts twice. There is no matching between the two.
One dataset per WhatsApp Business Account
Meta holds one dataset per WABA, and every conversion Connectly forwards for that WABA lands in it. If you run more than one brand or product line on the same WABA, their events share a dataset. Deduplication is per Connectly business: two brands on separate Connectly businesses can both reportORD-7821, and both are forwarded. Two brands under one Connectly business that both produce ORD-7821 share one order_id, so the second is treated as a retry and not forwarded. Give each brand a distinguishable prefix (VIS-ORD-7821, FIO-ORD-7821); it also keeps brand-level totals apart in the shared dataset when you reconcile.
Attribution itself is unaffected: each event carries the ctwa_clid of the click that produced it, so Meta credits the correct ad and campaign regardless of which brand shares the dataset. Only dataset-level totals combine the brands.