# RudderStack integration

<Aside type="caution" icon="setting" title="Developer assistance needed">
 You'll need help from your development team to set up the integration. Share this guide with them.
</Aside>

[RudderStack](https://www.rudderstack.com/) is a customer data platform that collects events from your apps, websites, servers, and warehouses and forwards them to other tools. With the Pushwoosh destination in RudderStack, the data you already collect there reaches Pushwoosh without extra code in your app:

* Track events become Pushwoosh [events](/product/audience-data-and-segmentation/events/). Use them to build segments and to start or branch [customer journeys](/product/customer-journey/pushwoosh-journey-overview).
* Identify traits become user-specific [tags](/product/audience-data-and-segmentation/user-data-tags/tags/). Use them to target and personalize push notifications, in-app messages, and emails.

<Aside type="note" title="Private beta">
The Pushwoosh destination in RudderStack is in private beta. To enable it for your RudderStack workspace, contact [RudderStack support](mailto:support@rudderstack.com). The destination works only for Pushwoosh accounts hosted on `app.pushwoosh.com`. If you're not sure where your account is hosted, contact your Customer Success Manager or support.
</Aside>

## Before you start

The destination matches all data by User ID, so check these prerequisites first:

* The [Pushwoosh SDK](/developer/first-steps/integrate-pushwoosh-sdk) is integrated in your app.
* Your app calls [`setUserId`](/developer/first-steps/collecting-user-ids/) with the same value that RudderStack sends as `userId`. Pushwoosh links incoming events and traits to users by this value.
* Each user's device is registered with this User ID before RudderStack sends `identify` calls for the user. Traits for a User ID that Pushwoosh doesn't know yet are dropped.
* You have access to **Settings** → **API Access** in Pushwoosh to create an API token.
* You have a RudderStack workspace with at least one source that sends `track` or `identify` calls.

## Set up the Pushwoosh destination in RudderStack

Setup takes two values from Pushwoosh, the application code and a Device API token, and one destination in RudderStack.

### Get the application code and a Device API token

1. In Pushwoosh, open the application you want to send data to.
2. Copy the application code. It's shown below the application name in the top-left corner and looks like `XXXXX-XXXXX`.
3. Go to **Settings** → **API Access** and click **Generate New Token**.
4. In **Token type**, choose `device`.
5. In **Name**, enter a name for the token, for example `RudderStack`.
6. Click **Generate**.
7. In the token list, click the three-dot menu next to the new token and choose **Edit token…**.
8. Under **Applications**, select the application from step 1 and click **Save**.
9. Copy the token value from the token list.

A [Device API token](/developer/api-reference/api-access-token/#device-api-token) is enough for the destination. You don't need a Server API token.

### Add the destination in RudderStack

1. In the RudderStack dashboard, go to **Collect** → **Destinations**.
2. Click **New destination**.
3. Select **Pushwoosh** from the list.
4. Enter a name for the destination and click **Continue**.
5. Select the sources you want to send to Pushwoosh.
6. In **Application Code**, paste the application code.
7. In **API Token**, paste the Device API token.
8. Finish the setup to save the destination.

RudderStack sends data to Pushwoosh in cloud mode, from RudderStack's servers, for every supported source type.

For the RudderStack side of the setup, see the [Pushwoosh destination guide](https://www.rudderstack.com/docs/destinations/streaming-destinations/pushwoosh/setup-guide/) in the RudderStack documentation.

## What data RudderStack sends to Pushwoosh

The destination supports two call types, `track` and `identify`. RudderStack rejects any other call type, such as `page`, `screen`, `group`, or `alias`, for this destination.

Every call must have a `userId`. RudderStack doesn't send calls without it, because Pushwoosh can't attribute an anonymous call to a user.

### Track calls become Pushwoosh events

Each `track` call becomes a Pushwoosh event with the same name as the RudderStack event:

| RudderStack field | Pushwoosh |
| --- | --- |
| `event` | Event name |
| `properties` | Event attributes |
| `userId` | User ID |
| `timestamp` (or `originalTimestamp`) | Time of the event |
| `context.device.id` | Device ID, if present |
| `context.device.type` or `context.os.name` | Platform: `android`, `ios`, or `web` for everything else |

If the event or an attribute doesn't exist in the application yet, Pushwoosh creates it automatically.

Pushwoosh drops the whole event without an error, and RudderStack reports it as delivered, if any of these is true:

* The call has more than 100 properties.
* A property value is longer than 10 KB.
* The event name is longer than 255 characters.
* The event is new, and its name is longer than 128 characters or contains control characters.

An event keeps up to 100 attributes. Once an event has 100 known attributes, Pushwoosh still records new calls, but new property names aren't added as attributes.

Nested objects in `properties` arrive as JSON strings, and properties with a `null` value are dropped.

### Identify calls become user-specific tags

Each `identify` call sets its traits as tags on the user with the given `userId`. Traits come from `traits`, or from `context.traits` when `traits` is empty.

* **Only user-specific tags are written.** If tag auto-creation is enabled for your account, a trait with a new name creates a [user-specific tag](/product/audience-data-and-segmentation/user-data-tags/tags/#tag-scope-general-vs-user-specific). If a **General** tag with the same name already exists, Pushwoosh skips that trait without an error.
* **A value must match the tag type.** If a tag already exists and the trait value doesn't fit its type, such as text for an Integer tag, Pushwoosh skips that trait without an error.
* **The user must already exist in Pushwoosh.** Tags are applied only if the Pushwoosh SDK has registered a device with `setUserId` set to the same `userId`. Traits for an unknown user are dropped without an error.
* **Identity and contact traits aren't copied to tags.** `email`, `phone`, `firstName`, `lastName`, `name`, `address`, `id`, `userId`, and `anonymousId` are never sent as tags. An `identify` call that has only these traits fails with `No traits left to send as Pushwoosh tags`.
* **An empty value clears the tag.** A trait with an empty string or an empty list deletes the user's current value of that tag.
* **Nested objects arrive as JSON strings.** Traits with a `null` value are dropped.

<Aside type="caution" title="Older calls can overwrite newer values">
Each `identify` call overwrites the current tag values, and the last delivered call wins. If RudderStack delivers an older `identify` after a newer one, for example when it retries or replays data, the tags keep the older values.
</Aside>

### What the destination doesn't do

* It doesn't register devices or email addresses. Devices come from the Pushwoosh SDK.
* It doesn't delete users. RudderStack user deletion requests aren't supported for this destination.

## Check that the integration works

After the destination is saved, send a test `track` and `identify` call from a source with a `userId` that already has a device in Pushwoosh.

* **Events:** in Pushwoosh, go to **Audience** → **Events**, open the event, and check that it's counted.
* **Tags:** go to **Audience** → **User Explorer**, find the user by User ID, and check the tag values.

Delivery errors for each call are shown in the RudderStack **Live Events** view of the destination.

## Troubleshooting

### Track calls fail with unauthorized

The API token doesn't match the application code. Check that the token belongs to the same Pushwoosh account as the application and has access to it.

`identify` calls don't check the token, so they keep succeeding with a wrong token. Use a `track` call to test the token.

### Calls fail with application not found or application code is not valid

The application code is wrong, or the account isn't hosted on `app.pushwoosh.com`. `track` calls fail with `application not found`, and `identify` calls fail with `application code is not valid`. Check the code in the Pushwoosh Control Panel. If the code is right, contact your Customer Success Manager or support.

### Calls fail with Missing required value from userId

The call has no `userId`. Anonymous calls aren't sent to Pushwoosh. Call `identify` in your RudderStack source after the user signs in, so later calls carry the `userId`.

### Calls fail with Invalid enum value

The call type isn't `track` or `identify`. Pushwoosh accepts only these two types. Don't connect sources that send only `page`, `screen`, `group`, or `alias` calls, or ignore these errors.

### Identify calls fail with No traits left to send as Pushwoosh tags

All traits in the call are identity or contact traits, such as `email` or `phone`, which are never copied to tags. Add at least one other trait or skip the call.

### Identify calls succeed but tags don't appear

Check these in order:

1. A device with this User ID is registered in Pushwoosh. Search for the user in **Audience** → **User Explorer**.
2. The app calls `setUserId` with exactly the same value RudderStack sends as `userId`.
3. The tag with this name is **User-specific**. A trait for an existing **General** tag is skipped. Change the tag scope or rename the trait.
4. The trait value matches the type of the existing tag.
5. The trait isn't one of the identity or contact traits that are never copied, such as `email` or `phone`.