> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# RudderStack

<!-- -->

[Server](#)[ ](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/rudderstack)

<!-- -->

[Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/server/destinations/rudderstack)[ ](https://www.npmjs.com/package/@walkeros/server-destination-rudderstack)

<!-- -->

[Package](https://www.npmjs.com/package/@walkeros/server-destination-rudderstack)

<!-- -->

Beta

Server-side event delivery to [RudderStack](https://rudderstack.com/) via the official [`@rudderstack/rudder-sdk-node`](https://www.npmjs.com/package/@rudderstack/rudder-sdk-node) SDK. Implements the full Segment Spec surface (`track`, `identify`, `group`, `page`, `screen`, and `alias`) with automatic identity deduplication and graceful shutdown via `flush()`.

<!-- -->

Where this fits

RudderStack is a **server destination** in the walkerOS flow:

Receives events server-side from the collector, resolves identity, and forwards them to RudderStack's data plane for routing to downstream destinations.

## Installation[​](#installation "Direct link to Installation")

```
npm install @walkeros/server-destination-rudderstack
```

* Integrated
* Bundled

```
import { startFlow } from '@walkeros/collector';
import { destinationRudderStack } from '@walkeros/server-destination-rudderstack';

await startFlow({
  destinations: {
    rudderstack: {
      code: destinationRudderStack,
      config: {
        settings: {
          writeKey: 'YOUR_RUDDERSTACK_WRITE_KEY',
          dataPlaneUrl: 'https://your-data-plane.rudderstack.com',
        },
      },
    },
  },
});
```

Add to your `flow.json` destinations:

```
"destinations": {
  "rudderstack": {
    "package": "@walkeros/server-destination-rudderstack",
    "config": {
      "settings": {
        "writeKey": "YOUR_RUDDERSTACK_WRITE_KEY",
        "dataPlaneUrl": "https://your-data-plane.rudderstack.com"
      }
    }
  }
}
```

[See bundled mode setup](https://www.walkeros.io/docs/getting-started/modes/bundled.md) | [CLI reference](https://www.walkeros.io/docs/apps/cli.md)

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->destination<!-- --> uses the standard <!-- -->destination<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [destination<!-- --> configuration](https://www.walkeros.io/docs/destinations.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to Settings")

| Property               | Type                  | Description                                                                                                                            | More |
| ---------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| `writeKey*`            | `string`              | RudderStack source write key. Find it in the RudderStack dashboard under Sources > Setup.                                              |      |
| `dataPlaneUrl*`        | `string`              | RudderStack data plane URL. Required. Example: https\://your-data-plane.rudderstack.com                                                |      |
| `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).                                                |      |
| `path`                 | `string`              | API path route (like /v1/batch).                                                                                                       |      |
| `flushAt`              | `integer`             | Events to enqueue before flushing a batch. Default: 20.                                                                                |      |
| `flushInterval`        | `integer`             | Max milliseconds before auto-flush. Default: 10000.                                                                                    |      |
| `maxQueueSize`         | `integer`             | Maximum batch payload size in bytes. Default: 460800 (\~500KB).                                                                        |      |
| `maxInternalQueueSize` | `integer`             | Maximum in-memory queue length. Default: 20000.                                                                                        |      |
| `logLevel`             | `string`              | SDK log level: 'info', 'debug', 'error', or 'silly'. Default: 'info'.                                                                  |      |
| `retryCount`           | `integer`             | Retry attempts for failed batches. Default: 3.                                                                                         |      |
| `enable`               | `boolean`             | Set to false to no-op all SDK calls. Default: true.                                                                                    |      |
| `gzip`                 | `boolean`             | Enable gzip compression for requests. Default: true.                                                                                   |      |
| `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.              |      |
| `integrations`         | `Record<string, any>` | Enable/disable downstream RudderStack destinations. Example: { "All": true, "Mixpanel": false }.                                       |      |

\* Required fields

## Mapping[​](#mapping "Direct link to Mapping")

Per-event rules under `config.mapping`. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

| 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 { name, properties? } or true for minimal page(). RudderStack requires name (falls back to empty string). Use with silent: true.                       |      |
| `screen`   | `any` | Per-event screen call (mobile backends). Resolves to { name, properties? } or true for minimal screen(). RudderStack requires name (falls back to empty string). Use with silent: true. |      |
| `alias`    | `any` | Per-event alias call. Resolves to { previousId }. Links anonymous user to identified user. Use with rule-level silent: true.                                                            |      |

## Examples

### Alias user

An identity merge fires analytics.alias to link a previous anonymous id to the newly registered user id.

Event

```
{
  "name": "identity merge",
  "data": {
    "anonymous_id": "anonymous-123"
  },
  "context": {
    "dev": [
      "test",
      1
    ]
  },
  "globals": {
    "lang": "elb"
  },
  "custom": {
    "completely": "random"
  },
  "user": {
    "id": "registered-456",
    "session": "s3ss10n"
  },
  "nested": [
    {
      "entity": "child",
      "data": {
        "is": "subordinated"
      }
    }
  ],
  "consent": {
    "functional": true
  },
  "id": "02e3e8e63f3ca6c7",
  "trigger": "test",
  "entity": "identity",
  "action": "merge",
  "timestamp": 1700000107,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "silent": true,
  "settings": {
    "alias": {
      "map": {
        "previousId": "data.anonymous_id"
      }
    }
  }
}
```

Out

```
analytics.alias({
  "userId": "registered-456",
  "previousId": "anonymous-123",
  "timestamp": {}
})
```

### Anonymous only

When no userId is resolved RudderStack accepts the track call keyed solely by anonymousId.

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": {
    "session": "s3ss10n"
  },
  "nested": [],
  "consent": {
    "functional": true
  },
  "id": "f0fca2d2664a8fff",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000108,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```
analytics.track({
  "anonymousId": "s3ss10n",
  "event": "product view",
  "properties": {},
  "timestamp": {}
})
```

### Group company

A company update fires analytics.group with the groupId and group traits for B2B account tracking.

Event

```
{
  "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": "b4da203dee2492be",
  "trigger": "test",
  "entity": "company",
  "action": "update",
  "timestamp": 1700000104,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "silent": true,
  "settings": {
    "group": {
      "map": {
        "groupId": "data.company_id",
        "traits": {
          "map": {
            "name": "data.company_name",
            "industry": "data.industry",
            "employees": "data.employees"
          }
        }
      }
    }
  }
}
```

Out

```
analytics.group({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "groupId": "comp-456",
  "traits": {
    "name": "Acme",
    "industry": "tech",
    "employees": 50
  },
  "timestamp": {}
})
```

### Default track

A walker event becomes a RudderStack analytics.track call with userId and anonymousId resolved from the event.

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": "fc6c20e12e4cc0bb",
  "trigger": "load",
  "entity": "product",
  "action": "view",
  "timestamp": 1700000100,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```
analytics.track({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "event": "product view",
  "properties": {},
  "timestamp": {}
})
```

### Destination identify

Destination-level identify fires analytics.identify with traits on the first push only, then the track call follows.

Event

```
{
  "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": "6b06a6a98c12a76b",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000102,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Out

```
analytics.identify({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "traits": {
    "email": "user@example.com"
  },
  "timestamp": {}
});

analytics.track({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "event": "page view",
  "properties": {},
  "timestamp": {}
})
```

### Renamed event

A mapping renames the event so the RudderStack track call uses a canonical name such as Order Completed.

Event

```
{
  "name": "order complete",
  "data": {
    "id": "0rd3r1d",
    "currency": "EUR",
    "shipping": 5.22,
    "taxes": 73.76,
    "total": 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": "ddb63b472238450e",
  "trigger": "load",
  "entity": "order",
  "action": "complete",
  "timestamp": 1700000101,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "name": "Order Completed"
}
```

Out

```
analytics.track({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "event": "Order Completed",
  "properties": {},
  "timestamp": {}
})
```

### Page view

A page view fires analytics.page with a resolved page name and properties instead of a generic track.

Event

```
{
  "name": "page view",
  "data": {
    "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": "774bf62936039b29",
  "trigger": "load",
  "entity": "page",
  "action": "view",
  "timestamp": 1700000105,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "silent": true,
  "settings": {
    "page": {
      "map": {
        "name": "data.title",
        "properties": {
          "map": {
            "section": "data.section"
          }
        }
      }
    }
  }
}
```

Out

```
analytics.page({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "name": "Getting Started",
  "properties": {
    "section": "tutorials"
  },
  "timestamp": {}
})
```

### Screen view

A screen view from a mobile app backend fires analytics.screen with a screen name and properties.

Event

```
{
  "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": "4ec3cc3b9a29c72b",
  "trigger": "test",
  "entity": "screen",
  "action": "view",
  "timestamp": 1700000106,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "silent": true,
  "settings": {
    "screen": {
      "map": {
        "name": "data.screen_name",
        "properties": {
          "map": {
            "build": "data.build"
          }
        }
      }
    }
  }
}
```

Out

```
analytics.screen({
  "userId": "us3r",
  "anonymousId": "s3ss10n",
  "name": "Welcome",
  "properties": {
    "build": "1.2.3"
  },
  "timestamp": {}
})
```

### User login identify

A user login fires only an analytics.identify call with the resolved userId and traits, skipping the track.

Event

```
{
  "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": "0e593f4f7bc38009",
  "trigger": "test",
  "entity": "user",
  "action": "login",
  "timestamp": 1700000103,
  "timing": 3.14,
  "source": {
    "count": 1,
    "trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
    "type": "collector",
    "schema": "4"
  }
}
```

Mapping

```
{
  "silent": true,
  "settings": {
    "identify": {
      "map": {
        "userId": "data.user_id",
        "traits": {
          "map": {
            "email": "data.email",
            "name": "data.name",
            "plan": "data.plan"
          }
        }
      }
    }
  }
}
```

Out

```
analytics.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.

## Alias support[​](#alias-support "Direct link to Alias support")

Unlike Segment, RudderStack also supports per-event `alias()` calls, useful for linking an anonymous identity to an identified user after signup or login. Configure via `mapping.settings.alias` with a `previousId` field.
