# Send Conversions API Event

Report a conversion — a lead, a purchase, a cart — to Meta's Conversions API from this conversation's channel, so ad optimisation can see what happened after the click.

## Getting here

**Automate → Workflows**, open a workflow, click **+** on the canvas, then pick **Send Conversions API Event** under **Add Steps**.

## Before you start

- An **owner**, **admin** or **agent** can add this step and save the workflow. Publishing that workflow — the thing that makes it run on live conversations — is an **owner** or **admin** action.
- Building and running workflows depends on your plan; see [pricing](/pricing).
- This conversation's channel needs a WhatsApp, Messenger or Instagram connection in **Settings → Integrations**. Until then the drawer shows a connect card instead of the fields — on WhatsApp the dataset is created automatically on the first send; on Messenger and Instagram an owner or admin must link a **Dataset ID** and **Dataset access token** from Meta Events Manager on the channel in **Settings → Channels**.

## Set up

1. Open the workflow and click **+** where the event belongs.
2. Pick **Send Conversions API Event**.
3. Choose **Meta CAPI event name** from Meta's business-messaging list.
4. Optional: set **Value** and **Currency** as a pair — naming only one sends the event with no price.
5. Optional: set **Test event code** to have the event land in Meta Events Manager's Test Events instead of counting as real traffic.
6. Save the step, then publish the workflow.

## Fields

| Field | What it means | Default | Limits |
| --- | --- | --- | --- |
| Meta CAPI event name | Which conversion this is, from Meta's business-messaging list (Purchase, LeadSubmitted, InitiateCheckout, AddToCart, ViewContent, OrderCreated and others). | LeadSubmitted | Only Meta's business-messaging names are offered — the web-pixel-only names (Lead, CompleteRegistration) are rejected by Graph and do not appear here. |
| Value | The sale or lead's amount — a number, or a placeholder like `{{deal.value}}`. | — | Sent only paired with Currency; either alone is dropped, not sent as a bare number. |
| Currency | A 3-letter ISO code, or a single placeholder like `{{deal.currency}}` that resolves to one. | — | Sent only paired with Value. |
| Test event code (optional) | Meta Events Manager's test code, from its Test Events tool. | — | With a code set, the event lands in Test Events and is not counted as real traffic. |

## How it works

- What leaves Inchat, and when: the instant the step runs, one call to Meta's Conversions API carrying the event name, a de-duplication id, and identity signals for THIS conversation's channel — on WhatsApp, the WhatsApp Business Account id and the customer's phone number hashed with SHA-256 (never sent in the clear); on Messenger, the Page id and the page-scoped user id; on Instagram, the Instagram Business Account id and the IG-scoped id — plus the value/currency pair when both resolve, and Meta's click-to-WhatsApp click id when this conversation has one.
- WhatsApp events specifically need that click id on every send — Graph rejects a WhatsApp business-messaging event without one. A conversation with no ad signal at all (no referral, or one that declares organic traffic — a post, a shortlink) is not sent and does not fail either: the step reports it was **skipped** with the reason, and does not page anyone, since an always-on workflow meeting an ordinary organic thread every run is expected, not a misconfiguration. A conversation whose referral DOES suggest ad traffic but carries no click id is different — that is attribution being lost — and the step fails.
- A price is sent only as a matched pair. Naming just a Value, or just a Currency, or one of the two failing to resolve to something valid, still sends the event — it goes out with no price, and the step succeeds with a note explaining exactly what was missing, visible in the run's **Activity** tab.
- The Graph call is made every time the step runs, whether or not Meta ends up counting it twice — de-duplication happens on Meta's side, not by Inchat skipping the send. A **Purchase** fired from a run that started because a deal reached a pipeline stage is keyed to that deal, so Meta folds a repeat of the same win (a correction, a re-open and re-win) into one count, within the week-long window Meta dedups on. Every other event, and Purchase from any other trigger, is keyed to this conversation and the UTC calendar day, so a repeat later the same UTC day is folded into one but a repeat the next UTC day counts again.

## When it fails

- This conversation's channel has no usable Conversions API dataset or token: the step fails with **Channel has no CAPI dataset/token configured.**
- The conversation has no channel at all: the step fails with **Conversation has no channel for CAPI.**
- A WhatsApp conversation whose referral suggests ad traffic carries no click-to-WhatsApp click id: the step fails, naming the ad id when one is known.
- Meta's Graph API refuses the call (an expired token, a misconfigured dataset, a Meta-side error): the step fails with **CAPI Graph call failed** and the reason Graph gave. This reason reaches the run's own **Activity** tab, not only Sentry.
- A failed event does not stop the run: the step is recorded failed and the flow moves straight to the next one.

## Limits

- It publishes even with nothing connected. The connection card blocks editing the fields in the drawer, but not saving or publishing the workflow — a step left this way fails every time it runs, with the reason shown on the run (see When it fails), until the channel is connected.
- An organic WhatsApp conversation — one that never started from a click-to-WhatsApp ad — can never send an event from this step: it is skipped by design, permanently, for that conversation.
- It reports a conversion; it does not read one back. There is no way for a later step to ask Meta whether the event was accepted beyond a failed step meaning Graph refused it outright.
- It sends the Graph call every run — de-duplication is Meta's, not a skip on Inchat's side, so a workflow that fires this step often still spends Graph API calls even on repeats Meta will fold together.

## Use cases

- Send **Purchase** with `{{deal.value}}` and `{{deal.currency}}` in a workflow on the **Deal Stage Changed** trigger, when the deal reaches a won stage, so the ad account that brought the lead sees the sale.
- Send **LeadSubmitted** as soon as a WhatsApp conversation starts from a click-to-WhatsApp ad, before anything else in the flow runs.

## Related

- [Move Deal to Stage](https://inchat.inseller.my/help/workflows/move-deal-to-stage)
- [HTTP Request](https://inchat.inseller.my/help/workflows/http-request)
- [Workflows: how a flow runs](https://inchat.inseller.my/help/workflows/workflows-overview)

---

Source files: `src/lib/workflows/ai-builder/spec.ts`, `src/lib/workflows/canvas-model.ts`, `src/components/workflows/WorkflowStepConfigDrawer.tsx`, `src/lib/workflows/capi-action.ts`, `src/lib/workflows/capi-events.ts`, `src/lib/workflows/connection-gates.ts`, `src/lib/workflows/engine.ts`, `src/lib/workflows/workflow-input-schema.ts`, `src/lib/attribution/dataset.ts`, `src/lib/attribution/hash.ts`, `src/lib/workflows/form-payload.ts`, `src/app/(app)/settings/channels/CapiDatasetForm.tsx`, `src/app/(app)/settings/channels/page.tsx`
