E-commerce events
Cart Abandoned, Product Viewed and Order Placed as native SendBeam automation triggers — one endpoint, fed by the WooCommerce plugin, a Shopify webhook, or your own code.
POST /api/v1/ecommerce/events turns what happens in your store into three
automation triggers: Cart abandoned,
Product viewed and Order placed. A store posts one normalised
event; SendBeam matches or creates the contact by email (exactly the same rules as everywhere
else a contact comes from an external event — a bounced, complained or deleted address is never
resubscribed by this) and fires any automation built on the matching trigger, at once, the same
way a form submission or a tag does.
The three triggers
- Order placed — the reliable one. Every order fires it, and also adds the
order's value to the contact's
lifetime_valuecustom field (see below). - Cart abandoned — best effort, from every source. Nothing can prove a cart was truly abandoned rather than completed a minute later somewhere else; this is a heuristic, not a guarantee, and it only ever fires for a cart where the store already knew an email address.
- Product viewed — only ever fires for a KNOWN contact. There is no anonymous visitor tracking behind this: if the store has no email for the visitor at view time, nothing is sent, on purpose.
The endpoint
Authenticate with an API key carrying the E-commerce events permission
(ecommerce:write) — create one under Settings → API
keys — in the x-api-key header, same as every other /api/v1/*
write. The body:
{ "type": "cart_abandoned" | "product_viewed" | "order_placed",
"email": "[email protected]",
"name": "Jane Doe", // optional
"value": 84.50, // optional — order/cart total
"currency": "GBP" // optional
} A successful call answers with what happened — nothing is ever silently dropped:
{ "ok": true, "processed": true, "contact_id": "...", "contact_created": false,
"enrolled": true, "lifetime_value": 214.30 }
When the address is suppressed, or the workspace's contact cap is reached, the call still
answers 200 (your store's checkout hook should never fail because of our
suppression list) with { "ok": true, "processed": false, "reason": "suppressed" | "contact_limit" }.
WooCommerce
Use the official SendBeam plugin. Once its API key is set (Settings → SendBeam, with the E-commerce events permission), turn on each event under Settings → SendBeam → E-commerce events:
- Order placed fires from WooCommerce's own order-processed hook — reliable, on by default once enabled.
- Product viewed fires from the product page for a logged-in customer, or one known from an earlier step in the same session; otherwise nothing is sent.
- Cart abandoned is a wp-cron heuristic: adding to cart is timestamped, and if no order follows within a window you set (60 minutes by default) it fires once — only when WooCommerce already knows the shopper's email. This is the same honest limitation every dedicated cart-recovery plugin has; WooCommerce core has no real "abandoned cart" event to hook.
Shopify
No app, and no Shopify Partner / app-store listing — you wire this up directly from your own store. In Shopify Admin, go to Settings → Notifications → Webhooks, choose JSON format, and create a webhook for each topic you want:
| Shopify topic | SendBeam trigger |
|---|---|
Order creation / Order payment | Order placed |
Checkout creation / Checkout update | Cart abandoned (best effort — see below) |
Use the same URL for every topic, with your workspace id (shown on Settings → E-commerce) in the query string:
https://sendbeam.io/api/v1/ecommerce/events?tenant=<your-workspace-id>
Shopify shows a webhook signing secret the first time you create a webhook on
the store. Paste it into Settings → E-commerce; every delivery's
X-Shopify-Hmac-SHA256 header is then verified against it (HMAC-SHA256 over the raw
body) before anything is processed. No secret saved means Shopify-signed events are refused —
there is no unsigned fallback for this path.
checkouts/create and checkouts/update fire on an incomplete
checkout, not a confirmed abandonment — completeness and timing vary by Shopify plan, same
honest caveat as WooCommerce's cart_abandoned. There is no Shopify webhook topic for
"a product page was viewed" — Shopify does not emit one — so Product viewed cannot be
fed from Shopify at all.
Building an actual Shopify app with an App Store listing is a separate future step that needs the account owner's own Shopify Partner account — this endpoint is what you can use today without one.
Anything else (n8n, Zapier, your own code)
Post the normalised shape directly with your API key:
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]",
"name": "Jane Doe",
"value": 84.50,
"currency": "GBP"
}' Lifetime value
Every order_placed event adds value to the contact's
lifetime_value custom field — created automatically as a Number field the first
time an order arrives, and always INCREASED, never overwritten, so two orders add up. Use it in
a segment, a merge tag, or a condition step the same as any other Number field. The same
increment mechanism is available generally: the Set Field
step has an Increase by mode for building your own running counters.
What this is not
- Not a Shopify app — no App Store listing, no OAuth install flow. A merchant wires the webhook up themselves, today, with the steps above.
- Not anonymous behavioural tracking — Product viewed and Cart abandoned only ever fire for a contact the store already has an email for.
- Cart abandoned is always a heuristic. Treat it as "probably didn't finish", not as proof.