# Send conversions to Meta

> Send the leads that became jobs, and the sales they turned into, to a Meta dataset as Conversions API events, matched to each person by hashed details.

A push to Meta sends events to one of your business's datasets through Meta's Conversions API: a lead from a Meta lead form that became a quote, then a booked job, then a won one, or an invoice paid. Meta matches each event to the person it was about, from details sanda hashes before they leave, and credits the ad that brought them, so Meta sees which leads turn into work, not only which ones fill in a form.

A push to Meta is set up like any other [push](https://docs.sanda-os.com.au/streams/out): you connect once, choose the dataset, and choose the sanda value for each part of an event. Each run sends only the events Meta hasn't had yet.

:::note
Meta conversions is on the **Push** tab once sending events to Meta is switched on for your console. If **Choose a destination** doesn't list it, ask sanda support.
:::

## What it sends

Each row of the push is one event:

- **Its name and time**: a stage of your own, such as **Lead**, **Quote sent** or **Job won**, or one of Meta's standard events, such as **Purchase**, and when it happened.
- **Where it happened**: from your CRM or job system, in store, on a phone call, by email, in a chat, or somewhere else.
- **Who it was about**: an email address, a phone number, your own customer ID, the lead's ID from a Meta lead form, the click and browser cookies your website kept, a name, a suburb, a state, a postcode and a country. Meta matches the person on any of them.
- **What it was worth**, as a value and a currency, when you send one.

Events from your website belong to the Meta Pixel on the website, which sees the browser they came from. A warehouse doesn't have that, so a push never sends a website event, and **Where these happened** doesn't offer it.

### Lead stages from your job system

When **Where these happened** is **From your CRM or job system**, each event is sent the way Meta takes stages of a lead (Meta calls this Conversion Leads): marked as coming from a CRM, with the name you give under **Your CRM or job system**. Map **Meta lead ID** to the lead's ID from the Meta lead form it came in on, and Meta ties every stage to the lead, and the lead to its ad. A lead that didn't come in through Meta has no such ID, so map the person's email or phone as well, which Meta matches instead.

## Before you start

- **A dataset in Meta's Events Manager.** Meta also calls it a pixel. Note its ID: the editor lists the datasets your connection can reach, and you can always type the ID instead.
- **Someone who manages it.** The person who connects Meta signs in through Meta's business sign-in and chooses which of the business's assets sanda may use. They need to be able to manage the dataset, and sanda needs to be allowed to manage ads or the business, which is what Meta asks of a partner sending events for a business.
- **Your customers' agreement.** The push asks you to confirm that the people in it agreed to their details being used to measure your ads. sanda sends what you choose, and your privacy notice is what makes it true.
- **Your stages in your semantic fluid**: a row per event, with an ID that stays the same for each stage of each job, and the time it happened. See [the semantic fluid](https://docs.sanda-os.com.au/semantic-fluid).

## Connect Meta

:::steps
1. **Open Push.** In the console, go to **Data · Streams** and open the **Push** tab.
2. **Start connecting.** Under **Choose a destination**, press the **Meta conversions** card. Once a connection is made, the card opens a new push on it instead.
3. **Sign in to Meta.** Meta asks which business to connect and which of its assets to share. Share the dataset the push will send to.
4. **Check the connection.** You land back in a new push, with a note naming the connection. The connection is listed under **Connected**.
:::

A connection Meta makes for a business (a system user's) never ends. One made for a person lasts about 60 days, and in its last week its row under **Connected** says the day it ends, so you can connect it again before then. Connecting the same Meta account again keeps every push on it.

**Disconnect** forgets sanda's token and leaves sanda's app in place at Meta, so the confirmation says where to remove it there: under **Connected apps** in your business's settings, or under **Business Integrations** in your own settings if you connected as yourself.

## Create the push

Press the **Meta conversions** card once a connection is made, or **New push**, choosing **Meta conversions** under **Destination** when the editor asks. The editor has the same sections as every push (see [create a push](https://docs.sanda-os.com.au/streams/create-a-stream-out)); these are Meta's.

### Where it writes

| Field | What to choose |
|---|---|
| **Meta connection** | The connection the events go through. |
| **Dataset (pixel)** | The dataset that gets the events. The list holds the datasets your business owns, the ones clients share with it, and those of the ad accounts it reaches. If yours isn't listed, press **Type the ID instead** and type its ID from Events Manager. When you save, sanda asks Meta for the dataset through the connection, refuses one the connection can't reach, and keeps its name. |

### What it sends

Each part of an event, with the sanda value it comes from. A part that can be the same on every event offers **A fixed value instead**.

| Part | What it holds |
|---|---|
| **Event ID** (required) | An ID that stays the same for this stage of this job, such as the job ID and the stage together. Meta tells one event from another by its ID and its name. |
| **Event name** (required) | Starts as the fixed value **Lead**. A stage such as **Job won**, or a standard event such as **Purchase**. Give it a column of stage names to send several stages from one push. |
| **Event time** (required) | When the stage was reached. A date with no time counts as the end of that day, in the push's **Time zone**. |
| **Value** | What the event was worth. A **Purchase** needs a value and a currency. |
| **Currency** | Starts as the fixed value **AUD**. |
| **City**, **State**, **Country** | Sent with the details below to help Meta match the person. **Country** starts as the fixed value **AU**. |
| **Order ID** | For an event in store: Meta tells in-store events apart by their order ID, and sanda sends the event ID in its place when a row has none. |

Then, under **At least one of these, so Meta can match each event**: **Email**, **Phone**, **Your customer ID**, **Meta lead ID**, **Click ID cookie (fbc)**, **Browser ID cookie (fbp)**, **First name**, **Last name** and **Postcode**. A name counts only with a postcode. A row with none of them isn't sent.

### How it sends

| Setting | What it does |
|---|---|
| **Where these happened** | Where every event in the push took place. Choose one: there is no default. |
| **Your CRM or job system** | Only for **From your CRM or job system**: the name Meta shows for where these stages come from. Starts as sanda. |
| **Country for numbers without one** | Australia or New Zealand: how a phone number written without its country code, such as 0412 345 678, is read. |
| **These customers agreed to their details being used to measure your ads** | Tick it to save the push. |
| **Time zone** | The time zone your job and invoice times are recorded in. sanda reads a time without one, and a date, in it. |

### Which rows

A push to Meta needs a condition on **Event time** under **Which rows**, such as `last_7_days`, and won't save without one. Meta takes nothing older than 7 days, so a push without one would read more rows on every run until it read more than one push may (see [editions and limits](https://docs.sanda-os.com.au/streams/out#editions-and-limits)) and couldn't run at all.

## What each run does

- **It sends each event once.** An event Meta has taken is never sent again, even after its row changes, because Meta would count it twice. An event that leaves the push's rows is remembered for 14 days, so one that comes back is not sent again either.
- **It sends nothing older than Meta takes.** Meta refuses a whole request if any event in it is more than 7 days old, so sanda counts an event **too old to send** once it is within 60 minutes of that, and checks again just before each request. Too old is not a refusal, so it doesn't make the run partial.
- **It waits for an event timed in the future.** The run counts it as **left for a later run**.
- **It sends at most 10,000 events a run**, the oldest first, in requests of up to 1,000. The rest wait for the next run.
- **It finds the event Meta refuses.** Meta takes a request whole or not at all, and doesn't say which event it refused. So sanda splits a refused request in halves, and halves again, until it finds the event, which is listed under the run with Meta's own words and Meta's trace ID. Every other event in the request is sent. If the search runs out of tries, the events it didn't reach are sent again on the next run, and the run says so.
- **It tells a fault in one event from a fault in all of them.** When both halves are refused in the same words as the whole request, sanda sends one event from each half on its own. If Meta refuses both in those words too, the fault is in something every event shares, such as a fixed value, and the run fails with Meta's words (below). If Meta takes either, the search goes on, so two events with the same mistake are each refused and the rest are sent.

A detail Meta can't use, such as an email address that isn't one or a cookie in the wrong form, is left out of that event, which is sent with the rest. The run says how many were left out, and never quotes them. A number that is a business's rather than a person's (a 13, 1300 or 1800 number) is left out without a word.

### Held events

An event Meta refuses 3 runs in a row is held, and sanda stops sending it. While any are held, the push has **Try held events again**, which sends them once more as they stand now. Saving a change to where the push writes or what it sends also releases them. See [held records](https://docs.sanda-os.com.au/streams/runs#held-records).

### Events sent twice

sanda sends each event once. If Meta takes a request but doesn't answer in time, sanda can't tell it was taken, so the step that tries again sends it again, with the same event ID and name, and the same order ID for an event in store. Meta may count those events twice.

### When Meta says it received fewer

Meta answers each request with how many events it received. When that is fewer than sanda sent, the run says so, with Meta's trace ID. Meta's **Diagnostics** in Events Manager say which events, and why.

## Personal details

Every detail about a person is hashed with SHA-256 before it leaves sanda, after it is written the way Meta asks: an email address trimmed and in lower case; a phone number as digits with its country code and no leading zero; a name, a suburb or a state in lower case with only its letters; a postcode in lower case with no spaces or dashes; a country as its two-letter code; your own customer ID trimmed and in lower case. Meta receives the hash, never the detail. The push's mapping marks those parts **hashed**, and the preview shows the start of the hash.

**Meta lead ID**, **Click ID cookie (fbc)** and **Browser ID cookie (fbp)** are IDs Meta made, which Meta takes as they are, so they are sent unhashed.

The tick box under **How it sends** is your statement, and Meta has nowhere to record it. Untick it and the push won't save; your privacy notice is where your customers agree.

## Data Meta must never get

Meta is an advertising network. A push to it checks where everything it reads came from, through every view and model built on what a pull landed, and refuses data from a source whose terms forbid sending it to one. See [what a push never does](https://docs.sanda-os.com.au/streams/out#what-a-push-never-does).

## Change a push

- **A new dataset** starts the push over: every event in its rows is sent again, as new events. The old ones stay in Meta. The editor warns before you save it.
- **A new event name**, fixed or from a column, makes each event it renames a new event: it is sent again under its new name, and the one under the old name stays in Meta. An event whose name stays the same isn't sent again, so moving from the fixed name **Lead** to a column of stage names sends only the stages that aren't **Lead**. An event given back a name it was sent under in the last 14 days isn't sent again either.
- **Event ID** can't take another sanda value once Meta has taken any event, because Meta would count every one of them again. Make a new push instead.
- **Another Meta connection** doesn't start the push over: the events live in the dataset, not in the connection that sent them.

## If something goes wrong

### If Connect fails

You land back on **Push** with a sentence saying what happened, and nothing is connected.

| What happened | What to do |
|---|---|
| Meta stops before you can allow sanda | Meta hasn't approved sanda's app for this deployment yet. Ask sanda support. |
| You declined, or unticked a permission | Connect again and allow everything Meta asks. Without managing ads or the business, the connection is listed as one to connect again, and the editor won't use it. |
| The note says the connection no longer shares everything a push uses | You connected again and didn't share a dataset a push sends to. Connect again and share it. |
| Connecting isn't switched on for this workspace yet | Ask sanda support. |

### If a run fails or stops

| The run says | What to do |
|---|---|
| Meta no longer accepts sanda's connection | The token ended or was removed. Press **Connect again** beside the connection under **Connected**. The pushes on it wait, and the first run after catches up. |
| Meta says sanda may not send events to this dataset | Connect again as someone who manages the dataset, and share it. |
| Meta can't find the dataset, or this connection can't send to it | Choose the dataset again in the push, or connect as someone who manages it. |
| Meta is limiting how fast sanda can send for now | Nothing to do: what went is recorded, and the next run carries on. Meta's own estimate of how long, when it gives one, is in the sentence. |
| Meta says sanda has nearly used what it may send for this business | Nothing to do: sanda stopped before using all of it, so your business's own ad tools still have room. What went is recorded, and the next run carries on. |
| Meta has paused sanda for a policy check | Nothing to do: the next run carries on. |
| Meta refused the request, in Meta's words | Meta refused the whole request, and an event from each half on its own, in the same words, so the fault is in what every event shares rather than in one event. Check the push's settings and fixed values against Meta's words, and ask sanda support with the trace ID if it isn't clear. |
| Meta no longer accepts the version of its API this deployment uses, or wants a proof this deployment didn't send | Ask sanda support. |
| An event refused in Meta's words | That event as it stands. Fix the row it came from; a changed event is sent again on the next run. |
| Meta takes a Purchase only with a value and a currency | Map **Value** and **Currency**, or send the stage under another name. |

:::links
- [Push](https://docs.sanda-os.com.au/streams/out): What a push is, and what it never does.
- [Create a push](https://docs.sanda-os.com.au/streams/create-a-stream-out): The editor's sections, the preview and the first run.
- [Runs](https://docs.sanda-os.com.au/streams/runs): What each run did, and why an event was refused or held.
:::
