Skip to content

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.created and account.updatedOmnisendContactSyncWorkflow
    • order.placedOmnisendOrderEventWorkflow
    • order.status_changedOmnisendOrderEventWorkflow, only for the statuses shipped, delivered, cancelled, and refunded
    • cart.line_addedOmnisendCartEventWorkflow
  • Temporal workflowsOmnisendContactSyncWorkflow, OmnisendOrderEventWorkflow, and OmnisendCartEventWorkflow, 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 the vectis-main task queue.
  • GraphQL queryomnisendTrackingConfig(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

  1. 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-main task queue.
  2. 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.
  3. 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}.
  4. 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, plus commerceMode/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 status nonSubscribed — the sync does not opt anyone into marketing.
  • Commerce-mode tags. With commerce_mode_tags on, contacts are tagged b2b/wholesale, b2c/retail, or hybrid/b2b/b2c according to the channel.
  • Order events are sent to POST /v5/events with eventVersion: "v2" and a deterministic eventID of vectis-order-{order_number}. Order status maps to the Omnisend event name: placed/confirmed/awaiting_fulfillmentplaced order, shipped/deliveredfulfilled order, cancelled/refundedcancelled order. Orders without an email address are skipped.
  • Cart events are sent as added product to cart with eventID vectis-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 cart value), 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-After header (falling back to a 2s-per-attempt backoff), with a 30-second request timeout. Contact calls authenticate with Authorization: Omnisend-API-Key … and pin Omnisend-Version: 2026-03-15; event calls use the X-API-KEY header.
  • 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}, with add in place of the line item id when the event carries none).