Omnisend¶
Omnisend email & SMS marketing automation. The extension pushes contacts, order events, and cart events from Vectis to the Omnisend REST API so that Omnisend can drive segmentation, campaigns, and abandoned-cart automation. It is event-driven: platform events fan out to Temporal workflows that deliver the data, and per-channel configuration lets B2B (wholesale) and B2C (retail) channels use separate Omnisend brands.
At a glance
| Extension id | omnisend |
| Category | marketing |
| Version | 0.1.0 |
| Provides | Event subscriptions (5), Temporal workflows (3), GraphQL query, admin page tab |
| External account | Omnisend — API Key + Brand ID (required) |
What It Provides¶
- Event subscriptions — on activation the extension subscribes to five event-bus topics (priority 80) and starts a Temporal workflow for each occurrence:
account.createdandaccount.updated→OmnisendContactSyncWorkfloworder.placed→OmnisendOrderEventWorkfloworder.status_changed→OmnisendOrderEventWorkflow, only for the statusesshipped,delivered,cancelled, andrefundedcart.line_added→OmnisendCartEventWorkflow
- Temporal workflows —
OmnisendContactSyncWorkflow,OmnisendOrderEventWorkflow, andOmnisendCartEventWorkflow, each wrapping a single activity (sync_contact_to_omnisend,send_order_event_to_omnisend,send_cart_event_to_omnisend). Workflows and activities self-register with the Temporal worker and run on thevectis-maintask queue. - GraphQL query —
omnisendTrackingConfig(channelId: ID!)returns{ enabled, brandId, jsTrackingEnabled }for the given channel, so a storefront can decide whether to emit the Omnisend JS tracking snippet with the channel's brand id (see the GraphQL reference). The extension is read-only over GraphQL — it contributes no mutations. - Admin page tab — an Omnisend tab contributed to the Marketing > Email Campaigns page (
/marketing/email); see Extension Tabs in the Marketing guide.
Setup¶
- Once installed (or dev-linked in development), the extension is discovered at startup. The Temporal worker must be running, since all pushes to Omnisend execute as workflows on the
vectis-maintask queue. - Enable the extension for each channel that should sync from Settings > Extensions (per-channel activation via
ChannelExtension). Activities read their configuration from the per-channel record, so a B2B and a B2C channel can point at different Omnisend brands. - In the channel's configuration form, enter the Omnisend API Key and Brand ID (both required), and optionally set the Storefront base URL — when present, cart events include an abandoned-checkout URL of the form
{storefront_url}/cart/{cart_id}. - Leave the sync toggles (Sync contacts, Sync order events, Sync cart events) on, or disable individual streams; each activity checks its toggle and skips when disabled.
Configuration Reference¶
| Key | Type | Required | Secret | Description |
|---|---|---|---|---|
api_key |
string | Yes | Yes | API Key |
brand_id |
string | Yes | No | Brand ID |
sync_contacts |
boolean | No | No | Sync contacts; defaults to on |
sync_orders |
boolean | No | No | Sync order events; defaults to on |
sync_carts |
boolean | No | No | Sync cart events; defaults to on |
js_tracking_enabled |
boolean | No | No | Enable JS tracking snippet; defaults to on |
commerce_mode_tags |
boolean | No | No | Auto-tag contacts with B2B/B2C; defaults to on |
storefront_url |
string | No | No | Storefront base URL; defaults to empty |
Permissions¶
marketing.omnisend.manage
The permission is upserted at boot from the manifest; assigning it to roles is manual.
Operational Notes¶
- Contact sync shape depends on the channel's commerce mode. On B2B and hybrid channels, every employee of the account is synced as a contact with company-level custom properties (
vectisAccountId,companyName,accountStatus,taxExempt,creditHoldStatus,spendingLimit,isAccountOwner, pluscommerceMode/channelCode). On B2C channels the customer is synced with name, phone, and channel properties only. - Contacts are created as
nonSubscribed. Email (and phone, when present) identifiers are pushed with channel statusnonSubscribed— the sync does not opt anyone into marketing. - Commerce-mode tags. With
commerce_mode_tagson, contacts are taggedb2b/wholesale,b2c/retail, orhybrid/b2b/b2caccording to the channel. - Order events are sent to
POST /v5/eventswitheventVersion: "v2"and a deterministiceventIDofvectis-order-{order_number}. Order status maps to the Omnisend event name:placed/confirmed/awaiting_fulfillment→ placed order,shipped/delivered→ fulfilled order,cancelled/refunded→ cancelled order. Orders without an email address are skipped. - Cart events are sent as added product to cart with
eventIDvectis-cart-{cart_id}. The contact email is resolved from the cart's employee or customer; anonymous carts (no email) are skipped. Cart line items carry variant ids and unit prices (per-line quantities are not sent — they only feed the summed cartvalue), while product titles, images, and URLs are sent empty. - Skip conditions are logged, not errored. Activities return a skip result when the extension is not enabled/configured for the channel, the relevant sync toggle is off, the entity is missing, or no email can be resolved.
- Rate limiting. The API client retries HTTP 429 responses up to 3 attempts, honoring the
Retry-Afterheader (falling back to a 2s-per-attempt backoff), with a 30-second request timeout. Contact calls authenticate withAuthorization: Omnisend-API-Key …and pinOmnisend-Version: 2026-03-15; event calls use theX-API-KEYheader. - Retries. Workflow activities run with a Temporal retry policy of up to 5 attempts (10s initial interval, 5m cap) and a 2-minute per-attempt timeout. Workflow ids are deterministic (
omnisend-contact-sync-{account_id},omnisend-order-event-{order_id},omnisend-order-status-{order_id}-{status},omnisend-cart-event-{cart_id}-{line_item_id}, withaddin place of the line item id when the event carries none).