# Northbeam Integration Northbeam attributes revenue to marketing channels by joining two data streams: **click/session data** from its pixel on your storefront, and **order data** from your commerce backend. This guide covers the OmniCart side — feeding accurate, timely order data to Northbeam. > Northbeam's ingestion formats evolve; treat the field mapping below as the OmniCart-side source of truth and confirm the destination format (Orders API, S3/CSV feed, or a supported connector) in Northbeam's current documentation with your Northbeam account team. ## Architecture ``` Storefront ──(Northbeam pixel: clicks, sessions, UTMs)──▶ Northbeam OmniCart ──(scheduled order feed: this guide)─────────▶ Northbeam ``` The pixel is installed on your storefront pages (outside the scope of this API guide). The order feed is a scheduled job you run: pull orders from OmniCart, map fields, push to Northbeam. ## Step 1 — Pull orders incrementally Use `GET /admin/orders` with an `updated_at` cursor so new orders *and* changes (refunds, cancellations) flow through. See [Pulling Orders Data](/tutorials/orders-data) for the full pagination pattern. ```bash curl -G 'https://your-store.omnicart.cc/admin/orders' \ -u "sk_YOUR_SECRET_KEY:" \ --data-urlencode 'limit=100' \ --data-urlencode 'order=updated_at' \ --data-urlencode 'updated_at[$gte]=2026-07-21T13:00:00Z' \ --data-urlencode 'fields=id,display_id,status,email,total,currency_code,created_at,updated_at,customer_id,sales_channel_id,*items' ``` A 15–60 minute cadence is typical. Northbeam models are recomputed periodically, so sub-minute freshness buys nothing. ## Step 2 — Map OmniCart fields to Northbeam's order schema | Northbeam concept | OmniCart source | Notes | |---|---|---| | Order ID | `id` (or `display_id` if you prefer human-readable) | Be consistent — this is the dedup key. Pick one and never switch. | | Purchase timestamp | `created_at` | ISO-8601 UTC. Send with explicit timezone. | | Revenue / order total | `total` | **Already decimal dollars** (`89.97` = $89.97). Do not divide by 100; convert only if Northbeam asks for cents. | | Currency | `currency_code` | | | Customer identifier | `email` (hash if required) or `customer_id` | Match whatever identifier your pixel captures so Northbeam can join sessions to orders. | | Order status | `status` | Send cancellations/refund updates so attributed revenue stays accurate — this is why the `updated_at` cursor matters. | | Line items | `items` (via `fields=*items`) | Titles, SKUs, quantities, unit prices (decimal) if you feed product-level data. | | Store / channel | `sales_channel_id` | Useful if you run multiple storefronts under one account. | ## Step 3 — Attribution identifiers Northbeam's join primarily happens on its own pixel/session IDs plus the customer identifier. If your storefront also writes click IDs or UTM parameters into the order at checkout, they appear in the order's `metadata` object — include any such fields in your feed as secondary join keys. Inspect a few of your own orders (`GET /admin/orders?fields=id,email,metadata`) to see which attribution keys your storefront captures. ## Step 4 — Deliver to Northbeam Push each mapped batch to the ingestion method your Northbeam plan supports (direct API or a scheduled file drop). Idempotency rule: always upsert by your chosen Order ID so re-running a window never double-counts revenue. ## Validation checklist - Pick one day, compare Northbeam's ingested order count and revenue against OmniCart: `GET /admin/metrics` with that day's range — cards `total_orders` and `total_revenue` (see [Metrics & Reports API](/tutorials/metrics-data)). - Revenue off by exactly 100×? You divided or multiplied a decimal total — OmniCart totals are dollars already. - Counts off by a few orders near midnight? Timezone mismatch — Northbeam dashboards may bucket days in a different zone than your query window. - Refunded orders still showing full revenue? Your feed isn't re-sending updated orders — switch the cursor from `created_at` to `updated_at`.