Segment
Server-side event delivery to Segment via the official @segment/analytics-node SDK. Implements the full Segment Spec surface (track, identify, group, page, and screen) with automatic identity deduplication and graceful shutdown via closeAndFlush().
Segment is a server destination in the walkerOS flow:
Receives events server-side from the collector, resolves identity and consent context, and forwards them to Segment for routing to 400+ downstream destinations.
Installation
npm install @walkeros/server-destination-segment- Integrated
- Bundled
import { startFlow } from '@walkeros/collector';
import { destinationSegment } from '@walkeros/server-destination-segment';
await startFlow({
destinations: {
segment: {
code: destinationSegment,
config: {
settings: {
writeKey: 'YOUR_SEGMENT_WRITE_KEY',
},
},
},
},
});Add to your flow.json destinations:
"destinations": {
"segment": {
"package": "@walkeros/server-destination-segment",
"config": {
"settings": {
"writeKey": "YOUR_SEGMENT_WRITE_KEY"
}
}
}
}Configuration
This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
writeKey | string | Segment source write key. Find it in your Segment workspace under Connections > Sources > Settings > API Keys. | |
userId | string | walkerOS mapping value path to resolve userId from each event (like user.id). | |
anonymousId | string | walkerOS mapping value path to resolve anonymousId from each event (like user.session). | |
host | string | Base URL of Segment API. Set to https://events.eu1.segmentapis.com for EU endpoint. | |
path | string | API path route (like /v1/batch). | |
flushAt | integer | Events the SDK sends in one request. Each push and each config.batch batch flushes the SDK and waits until Segment delivered its calls. Default: 15. | |
flushInterval | integer | Max milliseconds before auto-flush. Default: 10000. | |
maxRetries | integer | Retries the SDK makes for a failed request. Default: as many as fit config.timeout with the SDK's backoff (one at the 10 s default, two from 24 s). A value set here wins. | |
httpRequestTimeout | integer | Time one request may take, in milliseconds. Default: a quarter of config.timeout (2500 at the 10 s default). A value set here wins. | |
disable | boolean | Completely disable the SDK (no-ops all calls). Default: false. | |
identify | any | Destination-level identity mapping. Resolves to { traits } object. Fires identify() on the first push and re-fires when values change. | |
group | any | Destination-level group mapping. Resolves to { groupId, traits }. Fires group() on the first push and re-fires on change. | |
consent | Record<string, string> | Mapping from walkerOS consent keys to Segment categoryPreferences keys. Example: { "marketing": "Advertising", "analytics": "Analytics" }. | |
integrations | Record<string, any> | Enable/disable downstream Segment destinations. Example: { "All": true, "Mixpanel": false }. |
Mapping
Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
| Property | Type | Description | More |
|---|---|---|---|
identify | any | Per-event identity mapping. Resolves to { userId?, traits? }. Use with rule-level silent: true on login/identify events. | |
group | any | Per-event group assignment. Resolves to { groupId, traits? }. Use with rule-level silent: true on company/team events. | |
page | any | Per-event page call. Resolves to { category?, name?, properties? } or true for minimal page(). Use with silent: true. | |
screen | any | Per-event screen call (mobile backends). Resolves to { category?, name?, properties? } or true for minimal screen(). Use with silent: true. |
Examples
Anonymous only
When no userId is resolved Segment accepts a track call keyed solely by anonymousId.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"session": "s3ss10n"
},
"nested": [],
"consent": {
"functional": true
},
"id": "ev1700000107",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000107,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.track({
"messageId": "ev1700000107",
"anonymousId": "s3ss10n",
"event": "product view",
"properties": {},
"timestamp": {}
})Group company
A company update fires Segment analytics.group with groupId and group traits for account-level tracking.
{
"name": "company update",
"data": {
"company_id": "comp-456",
"company_name": "Acme",
"industry": "tech",
"employees": 50
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "ev1700000104",
"trigger": "test",
"entity": "company",
"action": "update",
"timestamp": 1700000104,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"group": {
"map": {
"groupId": "data.company_id",
"traits": {
"map": {
"name": "data.company_name",
"industry": "data.industry",
"employees": "data.employees"
}
}
}
}
}
}analytics.group({
"messageId": "ev1700000104-group",
"userId": "us3r",
"anonymousId": "s3ss10n",
"groupId": "comp-456",
"traits": {
"name": "Acme",
"industry": "tech",
"employees": 50
},
"timestamp": {}
})Consent forwarding
Walker consent keys are mapped to Segment categoryPreferences on the analytics context for downstream filtering.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [],
"consent": {
"analytics": true,
"marketing": true
},
"id": "ev1700000108",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000108,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.track({
"messageId": "ev1700000108",
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "product view",
"properties": {},
"timestamp": {},
"context": {
"consent": {
"categoryPreferences": {
"Analytics": true,
"Advertising": true
}
}
}
})Default track
A walker event becomes a Segment analytics.track call with userId and anonymousId resolved from the event.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [],
"consent": {
"functional": true
},
"id": "ev1700000100",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000100,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.track({
"messageId": "ev1700000100",
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "product view",
"properties": {},
"timestamp": {}
})Destination identify
Destination-level identify fires Segment analytics.identify with traits on the first push only, then the track call follows.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n",
"email": "user@example.com"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "ev1700000102",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000102,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}analytics.identify({
"messageId": "ev1700000102-identify",
"userId": "us3r",
"anonymousId": "s3ss10n",
"traits": {
"email": "user@example.com"
},
"timestamp": {}
});
analytics.track({
"messageId": "ev1700000102",
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "page view",
"properties": {},
"timestamp": {}
})Renamed event
A mapping renames the event so the Segment track call uses Segment's canonical 'Order Completed' name.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"value": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "ev1700000101",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000101,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "Order Completed"
}analytics.track({
"messageId": "ev1700000101",
"userId": "us3r",
"anonymousId": "s3ss10n",
"event": "Order Completed",
"properties": {},
"timestamp": {}
})Page view
A page view fires Segment analytics.page with category, name, and properties instead of a generic track.
{
"name": "page view",
"data": {
"category": "docs",
"title": "Getting Started",
"section": "tutorials"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "ev1700000105",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000105,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"page": {
"map": {
"category": "data.category",
"name": "data.title",
"properties": {
"map": {
"section": "data.section"
}
}
}
}
}
}analytics.page({
"messageId": "ev1700000105-page",
"userId": "us3r",
"anonymousId": "s3ss10n",
"category": "docs",
"name": "Getting Started",
"properties": {
"section": "tutorials"
},
"timestamp": {}
})Screen view
A screen view fires Segment analytics.screen with name, category, and properties for mobile app tracking.
{
"name": "screen view",
"data": {
"screen_name": "Welcome",
"section": "onboarding",
"build": "1.2.3"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "ev1700000106",
"trigger": "test",
"entity": "screen",
"action": "view",
"timestamp": 1700000106,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"screen": {
"map": {
"name": "data.screen_name",
"category": "data.section",
"properties": {
"map": {
"build": "data.build"
}
}
}
}
}
}analytics.screen({
"messageId": "ev1700000106-screen",
"userId": "us3r",
"anonymousId": "s3ss10n",
"name": "Welcome",
"category": "onboarding",
"properties": {
"build": "1.2.3"
},
"timestamp": {}
})User login identify
A user login fires only Segment analytics.identify with the userId and traits, skipping the track.
{
"name": "user login",
"data": {
"user_id": "new-user-123",
"email": "user@acme.com",
"name": "Jane Doe",
"plan": "premium"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "ev1700000103",
"trigger": "test",
"entity": "user",
"action": "login",
"timestamp": 1700000103,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"identify": {
"map": {
"userId": "data.user_id",
"traits": {
"map": {
"email": "data.email",
"name": "data.name",
"plan": "data.plan"
}
}
}
}
}
}analytics.identify({
"messageId": "ev1700000103-identify",
"userId": "new-user-123",
"anonymousId": "s3ss10n",
"traits": {
"email": "user@acme.com",
"name": "Jane Doe",
"plan": "premium"
},
"timestamp": {}
})Identity is resolved automatically from each event: userId defaults to user.id and anonymousId defaults to user.session. At least one must be present for a call to be sent. Override these paths in settings to match your event structure.
Batching and delivery
This destination batches by default: config.batch sends after 15 events or 10 seconds, and each event keeps its own outcome. Set config.batch: { size: 1 } to send each event at once. How batching, retries, deduplication and acknowledgement work for the server SDK destinations is described in Server SDK destinations.
An event without userId or anonymousId fails with missing-input.