Data model
Account hierarchy
Active Reach uses a four-layer account model. The 2026-05-26 revision made Location (outlet) a first-class attribute of a workspace rather than a separate tenant.
Organization (brand portfolio holder, usually one brand)
└── Workspace (brand-tenant; one per brand)
├── Location[] (outlet — per-store ops, per-outlet overrides)
└── Property[] (SDK install — web app / mobile app / kiosk)| Layer | Maps to | What lives here |
|---|---|---|
| Organization | Brand portfolio holder | Brand identity, billing entity, subscription, agency relationships |
| Workspace | Brand-tenant (one per brand) | Cross-outlet data: contacts, segments, channels, journeys, in-app, campaigns, ads, loyalty program |
| Location | An outlet (store) | Per-outlet overrides: local hours, manager phone, payment merchant, inventory, per-outlet channel sender mapping |
| Property | An SDK install (web app / mobile app / kiosk) | In-app + push surfaces, per-property metrics |
workspace_id and location_id are distinct dimensions — never aliased. workspace_id is required on every tenant-scoped row; location_id is nullable (brand-tier rows = NULL; outlet-scoped rows stamp both).
Multi-brand operators run Agency mode: one Agency org → N Client orgs linked via agency_clients (1:N). The Agency org itself has no workspaces.
Customer URLs are subdomain-scoped to the brand with the outlet on the path: slug.actii.me/{outlet-code}/{page}.
Admin URLs are path-scoped to the brand with the outlet in query state: actii.me/dashboard/{brand}/{page}?location=loc_X.
Five operational objects
Five objects form the backbone of campaign execution. Understanding their relationships helps you design integrations and debug issues.
Contact
A person your business communicates with.
| Field | Description |
|---|---|
id | System-generated unique ID |
user_id | Your application’s user ID (set via identify()) |
anonymous_id | SDK-generated ID (before identification) |
email | Primary email address |
phone | Primary phone number (E.164 format) |
properties | Key-value pairs — standard (name, city, plan) and custom (any field you set) |
segments | Array of segment IDs the contact currently belongs to |
created_at | When the contact was first seen |
last_active_at | When the contact last fired an event |
Identity resolution: Contacts are deduplicated by user_id (highest priority), then email, then phone. When a match is found, records merge — properties combine (latest wins), event histories unify.
Event
Something a contact did.
| Field | Description |
|---|---|
type | track, identify, page, group, or alias |
event | Event name (for track type, e.g., order_completed) |
user_id / anonymous_id | Who did it |
properties | Arbitrary key-value data describing the event |
context | Device, browser, location, UTM metadata |
timestamp | When it happened |
Events are immutable — once ingested, they can’t be modified. They power segmentation, journey triggers, analytics, and attribution.
Campaign
A message sent to a segment through one or more channels.
| Field | Description |
|---|---|
id | Unique campaign ID |
name | Human-readable name |
status | draft, scheduled, sending, paused, completed |
segments | Target audience (array of segment IDs) |
channels | Which channels to use (email, whatsapp, sms, etc.) |
content | Per-channel message content |
schedule | When to send (immediate, scheduled, recurring, STO) |
conversion_goal | Optional event name + tracking window for attribution |
Journey
A multi-step automation defined as a directed acyclic graph of nodes and edges.
| Field | Description |
|---|---|
id | Unique journey ID |
name | Human-readable name |
status | draft, published, paused, completed |
nodes | Array of node objects (trigger, wait, send, branch, split, exit) |
edges | Array of connections between nodes |
version | Incremented on each edit |
See Journey graph schema for the full node/edge format.
Segment
A dynamic group of contacts defined by rules.
| Field | Description |
|---|---|
id | Unique segment ID |
name | Human-readable name |
conditions | Array of filter conditions (property checks, event checks, engagement checks) |
logic | How conditions combine (AND or OR) |
member_count | Current number of matching contacts (updated in real-time) |
How they connect
Contact → fires Events → matches Segments → enters Journeys → receives Campaigns
↓
Analytics (aggregation, funnels, attribution)Every downstream system (campaigns, journeys, analytics) reads from the same event stream. There’s no separate “marketing database” — events are the single source of truth.
What’s next
- Journey graph schema — the canonical node/edge format
- Event schema — the five event types in detail
- Workspace / org boundary — in-tenant write-scope semantics and inheritance patterns