Revenue attribution
Which campaign, automation step or A/B version an order followed — last touch, within a window — and where SendBeam shows what your email earned.
Opens and clicks say whether an email was read. Revenue says whether it worked. Once your store sends SendBeam its orders, each order is credited to the campaign or automation email that preceded it, and the figure appears wherever you would look for it: on the campaign, on the automation step, on each version of an A/B test, and added up across every workspace on your account. Nothing has to be configured — an order that arrives is attributed as it arrives.
How an order reaches SendBeam
Orders come in as order_placed events on the
e-commerce events endpoint — the same call that fires the
Order placed trigger. A Shopify store posts them from its own
Order creation webhook; anything else (n8n, Zapier, your own code) posts the
shape below with an API key that has the E-commerce events permission.
curl -X POST https://sendbeam.io/api/v1/ecommerce/events \
-H "x-api-key: sb_live_XXXXXXXX_..." \
-H "Content-Type: application/json" \
-d '{
"type": "order_placed",
"email": "[email protected]",
"external_id": "1001",
"value": 84.50,
"currency": "GBP",
"placed_at": "2026-09-22T10:14:00Z"
}' Three fields matter for revenue, on top of the event itself:
external_id(ororder_id) — the order's id in your store. This is what makes an order an order rather than an event: with it, the order is stored once, a retried delivery is a no-op, and it can be attributed. Without it the event still fires your automations and moveslifetime_value, but nothing is stored and nothing is attributed. Shopify's webhook always carries one; if you post events yourself, include it. The WordPress plugin reports WooCommerce orders without an id at present, so those fire your automations and updatelifetime_valuebut are not counted as revenue; to count them today, post the order with its id from your own code or an automation tool.valueandcurrency— the order total in the store's own currency. Also required: an order without a total is not stored. The currency stays with the order; see Currencies.placed_at— when the order was placed. The windows below are measured back from this moment; it defaults to the time the event arrives.
The order is recorded against the contact whose email address it carries. If nobody with that address is in the workspace yet, a contact is created for them, the same way any other store event creates one. If the address is on your suppression list, or the workspace is at its contact cap, the event is acknowledged but nothing is stored — the response says which. An order whose contact never received an eligible email is stored but credited to nothing, and appears in no revenue figure.
What counts
Attribution is last touch, within a window: the most recent email to that contact that they engaged with shortly before ordering gets the credit. Precisely:
- An email the contact clicked within the 7 days before the order wins. If they clicked more than one, the most recent click wins.
- Failing that, an email the contact opened within the 1 day before the order wins — the most recent open.
- A click always beats an open, even when the open happened later. Clicking is the stronger signal.
- A campaign send and an automation send are both eligible. An automation's email is credited to the step that sent it, so a flow with three emails shows which one sells.
- Transactional and notification emails — a receipt, a password reset, a form notification — are never credited. A receipt did not earn the order it is a receipt for.
- For a campaign with an A/B test, the version the contact received is recorded with the order, so the test can be judged on what each version earned.
An order is settled once and never re-attributed. An order with no eligible email in the window is recorded as unattributed and stays that way. An order counts at the total your store sent with it: there is no event yet for a refund or a cancellation, so the figures are gross — see What this is not.
Where the figure appears
- The campaign page — a Revenue tile beside Sent, Opened and
Clicked, with the number of orders under it. The same figure is in
GET /api/v1/campaigns/{id}/reportasrevenue, withby_currencylisting each currency separately. - The automation page — each Send email step shows what it earned and how many orders, so you can read down a flow and see where the money is.
- A/B tests — each version's box shows its revenue and orders alongside its open and click rates. When you set a test up, the winner can be chosen by revenue per recipient instead of opens or clicks: the version whose test recipients spent the most, per person, goes to everyone else. A revenue test with no orders by the time the wait is up is a tie, and a tie goes to A.
- Insights — Account → Insights adds it up across every workspace on the account for the last 30 days, with a column per workspace, so an agency can read what email earned across all its client stores.
- Segments — segments can be built on buying too: whether someone has ordered, and how recently.
Each of these appears only once an order has actually been attributed. A workspace without a store, or one whose orders have not followed any email yet, shows no revenue figure at all — rather than a zero that would claim its email earned nothing.
Currencies
Amounts are never converted and never added across currencies. A store selling
in pounds and one selling in euros have no common total without an exchange rate and a date, and
inventing one would give you a confident number that is simply wrong. Where a figure covers
more than one currency — an account whose workspaces sell in different currencies, or a store
that takes several — the largest is shown as the headline and the others are listed beside it.
The order count covers them all. In the API, total is the largest currency and
by_currency has every one.
What this is not
- Not a causal claim. Last touch within a window is an attribution rule, not proof.
- Not anonymous tracking. An order is credited only when the buyer's email address is a contact who received an email — there is no cookie, pixel or session stitching behind it.
- Not adjustable yet. The 7-day click and 1-day open windows are fixed; every campaign and every workspace is measured the same way, which is what makes the figures comparable.
- Not net of refunds. There is no event yet for a refund or a cancellation, so an order that is later refunded or cancelled in your store stays in the figure at the total it was sent with.
- Not retroactive. An order that arrived without an
external_idbefore your integration sent one was never stored, and cannot be attributed later.