> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Building an integration with OneSignal: partner guide

> Build, verify, and launch a OneSignal partner integration. Covers the APIs for messaging, user sync, custom events, event streams, and the identity lifecycle every partner must follow.

Build a OneSignal integration to embed messaging in your platform, sync user data, or trigger messages on behalf of mutual customers. Use this page to pick the right APIs for your use case, follow the [identity lifecycle](#identity-lifecycle) (the most common source of partner bugs), and verify your integration before submitting it for partner verification.

## Benefits of integrating with OneSignal

As a OneSignal partner, you'll gain valuable benefits aligned with your integration success and engagement:

* **Visibility and recognition:** Showcase your integration through a verified listing in the OneSignal Partner Directory, with opportunities for increased exposure and "featured" listings as your partnership grows.
* **Enhanced collaboration:** Participate in joint co-marketing activities, co-selling initiatives, and access comprehensive training to maximize integration adoption.
* **Strategic support:** Gain direct access to our dedicated support and technical teams, with additional levels of support unlocked based on partnership milestones.
* **Growth opportunities:** Access progressively advanced partner benefits such as dedicated documentation pages, enterprise sandbox accounts, and prioritized marketing opportunities as you expand your customer base and reach specific partnership milestones.

***

## Getting started

To start developing your integration, create a free account at [onesignal.com](https://onesignal.com). To join the partner program or to request premium features for integration development and testing, reach out through [partners.onesignal.com](https://partners.onesignal.com) or email `bd@onesignal.com`.

### Requirement: `OneSignal-Usage` header

To join the partner program, you must include the `OneSignal-Usage` header in all API requests. This header lets OneSignal identify your integration, provide better support, and track adoption across mutual customers.

**Format:**

```http theme={null}
OneSignal-Usage: <YourCompany> | Partner Integration
```

Replace `<YourCompany>` with your company or platform name. For example, if your company is Acme, use `Acme | Partner Integration`.

<Warning>
  **Common mistake:** Using only your company name (for example, `Acme`) without the ` | Partner Integration` suffix. The full format with the suffix and exact spacing is required.
</Warning>

### Submit your integration for verification

Once your integration is ready, complete the [Partner Validation Request form](https://form.asana.com/?k=SHmysllCA1c9RVCtynG8Zg\&d=780103692902078) to open a request ticket with the Partnerships team.

Verification formally recognizes your integration on OneSignal's side, enabling full access to the Integration Partner Program. Before submitting, run through the [end-to-end verification checklist](#verify-your-integration-end-to-end).

***

## Partner architecture patterns

Most OneSignal partner integrations fall into one of three architectural patterns. Identify which one you are building before deciding how to handle identity, Subscription creation, and event timing.

| Pattern                    | Examples                                                    | Where External ID is set                                                                       | What your integration writes                            |
| -------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| **Server-side webhook**    | Attribution platforms, marketing automation tools           | Customer's app, via the OneSignal SDK                                                          | Aliases, tags, custom events (after External ID exists) |
| **CDP-style sync**         | Segment, RudderStack, mParticle                             | Your sync calls [Create user](/reference/create-user) with `external_id` from upstream sources | Users, aliases, tags, email and SMS Subscriptions       |
| **SDK extension or embed** | Mobile BI tools that wrap or coexist with the OneSignal SDK | Your wrapper sets External ID through the OneSignal SDK                                        | Tags, custom events, messages                           |

<Note>
  Regardless of pattern, the OneSignal SDK is the source of truth for push and web Subscriptions when it is installed in the customer's app. Server-side Subscription creation is intended for email and SMS only.
</Note>

***

## Common integration use cases

Pick the use cases relevant to your platform. Each links to the guide and API reference you need. Before writing any user data, review the [Identity lifecycle](#identity-lifecycle).

### Create and identify users

OneSignal's mobile and web SDKs create Users (with OneSignal IDs) and Subscriptions (with Subscription IDs) as end users interact with the customer's app. Partner integrations can attach context to these Users by syncing the customer's External ID and, optionally, custom aliases keyed off it.

<Columns cols={2}>
  <Card title="Users" icon="user" href="./users">
    How Users are created, stored, and identified by their External ID.
  </Card>

  <Card title="Subscriptions" icon="address-book" href="./subscriptions">
    How Subscriptions are created, stored, and marked as subscribed or unsubscribed.
  </Card>

  <Card title="Aliases" icon="fingerprint" href="./aliases">
    How custom aliases identify Users across platforms and devices.
  </Card>
</Columns>

<Warning>
  Set custom aliases only after the External ID exists. Aliases written to an anonymous user cannot be merged later. See [Identity lifecycle](#identity-lifecycle).
</Warning>

### Sync user attributes

Sync user properties (profile data, preferences, behavior) as Tags so customers can segment audiences and personalize messages.

<Columns cols={2}>
  <Card title="Tags" icon="tags" href="./add-user-data-tags">
    Add custom properties to Users for personalization and segmentation.
  </Card>

  <Card title="Update user API" icon="pen-to-square" href="/reference/update-user">
    Set tags and other properties on an existing User via the external\_id or other alias.
  </Card>
</Columns>

### Send custom events

Send important user actions to OneSignal to trigger Journeys in real time, or use them for delays, segmentation, and personalization.

<Columns cols={2}>
  <Card title="Custom events" icon="bolt" href="./custom-events">
    Track User actions to trigger Journeys, personalization, and analytics.
  </Card>

  <Card title="Create custom events API" icon="plus" href="/reference/create-custom-events">
    Send custom events to OneSignal programmatically.
  </Card>
</Columns>

### Send messages

Send push, email, SMS, and Live Activities messages on behalf of mutual customers, directly from your platform. Use `external_id` or an `alias_id` to target individual users (for example, transactional messages), or use segments and filters to target groups. Always pass an [`idempotency_key`](/reference/idempotent-notification-requests) and reuse it on retries to avoid duplicate sends.

<Columns cols={2}>
  <Card title="Create message API" icon="paper-plane" href="/reference/create-message">
    Send push, email, SMS, and Live Activities messages on behalf of mutual customers.
  </Card>

  <Card title="Live Activities" icon="tower-broadcast" href="./live-activities">
    Push real-time updates on behalf of customers.
  </Card>
</Columns>

### Manage templates

Sync and manage email, SMS/RCS, and push templates in OneSignal so customers can build campaigns directly from your platform.

<Columns cols={2}>
  <Card title="Templates" icon="clone" href="./templates">
    Learn about message templates.
  </Card>

  <Card title="Create template API" icon="plus" href="/reference/create-template">
    Create templates for push, email and SMS messages programmatically.
  </Card>
</Columns>

### Capture event streams

Stream real-time engagement data (sends, clicks, opens, bounces, unsubscribes) from OneSignal to your warehouse for downstream analytics and automation.

<Columns cols={2}>
  <Card title="Event Streams" icon="satellite-dish" href="./event-streams">
    Stream real-time message events to your warehouse using the event names in this glossary.
  </Card>

  <Card title="Analytics overview" icon="chart-line" href="./analytics-overview">
    Measure message performance, user engagement, and conversions in OneSignal.
  </Card>
</Columns>

### Embed OneSignal in your platform

Embed OneSignal with per-customer App IDs so customers can onboard without leaving your product.

<Columns cols={2}>
  <Card title="Apps and Organizations" icon="building" href="./apps-organizations">
    Provision per-customer App IDs and manage many Apps under one Organization.
  </Card>

  <Card title="Developer hub" icon="plug" href="./developers">
    SDK setup, API reference, and the identity model used when integrating OneSignal.
  </Card>
</Columns>

***

## Identity lifecycle

OneSignal's identity model is sequenced. Calls made in the wrong order can attach data to anonymous users that cannot be merged with the identified user later, breaking multi-channel sync.

<Steps>
  <Step title="The OneSignal SDK creates an anonymous user">
    When a customer's app launches with the OneSignal SDK installed, the SDK creates an anonymous **User** with a OneSignal ID and a **Subscription** with a Subscription ID. At this point, no External ID is set.
  </Step>

  <Step title="The customer's app sets the External ID">
    When the customer's app identifies the end user (for example, on login or signup), it should call `OneSignal.login(externalId)`. This promotes the anonymous user to an identified user. If a user with that External ID already exists, the current anonymous OneSignal ID is replaced by the existing user's OneSignal ID, and the Subscription is reassigned to that user.

    This is the **earliest point** at which it is safe for a partner integration to attach data to that user.
  </Step>

  <Step title="The partner integration writes user data">
    Once the External ID is set, your integration can safely:

    * Attach aliases: [Create or update alias](/reference/create-alias)
    * Add tags: [Update user](/reference/update-user)
    * Send custom events: [Create custom events](/reference/create-custom-events) keyed by External ID
    * Send messages: [Create message](/reference/create-message) with `include_aliases.external_id`
  </Step>
</Steps>

<Warning>
  **Common mistake:** Webhook-driven integrations that fire on install, session, or event callbacks often arrive **before** the customer's app has called `OneSignal.login()`. Do not attach aliases or tags inside an install handler. Buffer the data until you observe an External ID, or trigger writes from a later callback that includes one.
</Warning>

**Example:**

<Tabs>
  <Tab title="Correct: External ID set first">
    1. A user exists with Subscription ID: `SUB1`, OneSignal ID: `OSID1`, and External ID: `EIDA`.
    2. The user downloads the app on another device. The SDK creates a new anonymous User and a new Subscription with Subscription ID: `SUB2` and OneSignal ID: `OSID2`.
    3. The user logs into the app with `OneSignal.login("EIDA")`. This identifies the anonymous user.
    4. `OSID2` is discarded and `SUB2` is moved to `OSID1` with `EIDA`.
    5. User `OSID1` with `EIDA` now has 2 Subscriptions: `SUB1` and `SUB2`.
  </Tab>

  <Tab title="Incorrect: Alias written first">
    1. A user opens the app. The SDK creates Subscription `SUB1` with OneSignal ID `OSID1`. No External ID is set.
    2. A partner server-side callback fires and posts to [Create user](/reference/create-user) with `adjust_id: "abc"` and the existing push token.
    3. OneSignal creates `OSID2` to hold the new alias and moves `SUB1` from `OSID1` onto `OSID2`. `OSID1` is now orphaned.
    4. The customer's app launches again. The SDK has no record of `OSID2` and creates `OSID3`. `SUB1` is moved again.
    5. The user is now spread across multiple OneSignal IDs, with the partner's alias bound to an anonymous one that cannot be merged later.
  </Tab>
</Tabs>

If your integration writes an alias **before** the External ID is set:

* The alias is bound to an anonymous, orphaned user that cannot be merged with the identified user later
* Subscriptions created under the alias get moved to a new OneSignal ID
* Messages targeted by your alias may fail to deliver

***

## API endpoint reference

Use this matrix to map integration operations to the correct endpoint and its preconditions.

| Operation                                                          | Endpoint                                                                                                | Precondition                                                                                                    |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Identify the user when the OneSignal SDK is installed              | `OneSignal.login(externalId)` in the customer's app                                                     | The customer's app integrates the OneSignal SDK.                                                                |
| Create or upsert a user from a server-side integration (CDP-style) | [`POST /apps/{app_id}/users`](/reference/create-user)                                                   | Pass `external_id` in the request. Use this only when the OneSignal SDK is not installed in the customer's app. |
| Add or update an alias on an existing user                         | [`PATCH /apps/{app_id}/users/by/{alias_label}/{alias_id}/identity`](/reference/create-alias)            | External ID is set.                                                                                             |
| Update tags or other user properties                               | [`PATCH /apps/{app_id}/users/by/{alias_label}/{alias_id}`](/reference/update-user)                      | External ID is set.                                                                                             |
| Add an email or SMS Subscription to a user                         | [`POST /apps/{app_id}/users/by/{alias_label}/{alias_id}/subscriptions`](/reference/create-subscription) | External ID is set. Push Subscriptions should be created by the SDK.                                            |
| Send a message to one user                                         | [`POST /notifications`](/reference/create-message) with `include_aliases.external_id`                   | External ID is set. Reuse [`idempotency_key`](/reference/idempotent-notification-requests) on retries.          |
| Send a message to a group                                          | [`POST /notifications`](/reference/create-message) with `included_segments` or `filters`                | None.                                                                                                           |
| Record a custom event                                              | [`POST /apps/{app_id}/custom_events`](/reference/create-custom-events)                                  | External ID is set. Reuse [`idempotency_key`](/reference/idempotent-notification-requests) on retries.          |

See the [API reference](/reference/rest-api-overview) for full parameter and response details.

***

## Verify your integration end-to-end

Before submitting your integration for partner verification, confirm each of the following on a test app:

<Steps>
  <Step title="The end user appears with a non-anonymous External ID">
    In **Audience > Users**, find the test user and confirm their identity shows your customer's External ID, not just an anonymous OneSignal ID.
  </Step>

  <Step title="Aliases attach to the identified user">
    Confirm any partner-specific aliases (for example, `integration_id`) appear under the same User as the External ID, not under a separate anonymous user.
  </Step>

  <Step title="Subscriptions link to one User">
    If the user has multiple channels (push, email, SMS), confirm all Subscriptions appear under one User. Multiple Users per person indicates an identity-sequencing issue. See [Identity lifecycle](#identity-lifecycle).
  </Step>

  <Step title="Tags and properties write successfully">
    Confirm tags written by your integration appear on the User's profile in the dashboard.
  </Step>

  <Step title="A test message reaches the test device">
    Send a test message using `include_aliases.external_id` and confirm it delivers to the test user's Subscription.
  </Step>

  <Step title="Retry behavior is correct">
    Trigger a controlled retry on a test endpoint and confirm your integration honors the `Retry-After` header and reuses the same `idempotency_key` on `POST /notifications` retries.
  </Step>
</Steps>

### Common integration mistakes

Avoid these patterns when building a OneSignal integration. Each one is a regression seen in real partner code.

**Writing aliases or tags before the External ID is set**

Aliases and tags attach to whichever User OneSignal can match (typically an anonymous one) and cannot be re-linked to the identified user later. Always require an External ID before writing identity data. See [Identity lifecycle](#identity-lifecycle) for the correct sequence.

**Treating the OneSignal ID as a stable customer identifier**

OneSignal IDs are internal and can change when users merge. Use the External ID as your stable cross-system identifier.

**Creating push Subscriptions server-side when the OneSignal SDK is installed**

The OneSignal SDK is the source of truth for push and web Subscriptions. Server-side Subscription creation is intended for email and SMS Subscriptions. Creating push Subscriptions via API when the SDK is installed produces duplicate or orphaned records.

**Writing the same field via both the SDK and the API**

Pick one writer per field. Concurrent writes from the SDK and a server-side integration create race conditions that overwrite each other unpredictably.

***

## FAQ

### Is the `OneSignal-Usage` header required, or only recommended?

It is required for the partner program. Without the header, OneSignal cannot attribute API traffic to your integration, which blocks partner verification, usage reporting, and prioritized support.

### Do I need a paid OneSignal plan to develop an integration?

No. You can build and test an integration on a free OneSignal account. Contact `bd@onesignal.com` if you need access to premium features for development or testing.

### What's the difference between using the OneSignal API and joining the partner program?

Any developer can call the OneSignal API. The partner program adds verified directory listing, co-marketing and co-selling opportunities, dedicated technical support, and progressively unlocked benefits as your integration grows. See [Benefits of integrating with OneSignal](#benefits-of-integrating-with-onesignal).

### How long does partner verification take?

Verification timing depends on the complexity of your integration and the Partnerships team's review queue. Submit the [Partner Validation Request form](https://form.asana.com/?k=SHmysllCA1c9RVCtynG8Zg\&d=780103692902078) when your integration is feature-complete. The Partnerships team responds in order of submission and the timeline depends on the complexity of the integration and the current review queue.

### Can I use one OneSignal app to serve multiple customers?

No. Each end customer should have their own OneSignal App ID so that data, subscriptions, and messages stay isolated. If you're embedding OneSignal in your platform, see [Apps and Organizations](./apps-organizations) for how to provision per-customer App IDs under one Organization.

***

## Related pages

<Columns cols={2}>
  <Card title="Partner integration user migration guide" icon="arrow-right-arrow-left" href="./partner-integration-user-migration-guide">
    Migrate an existing integration from the legacy Player API to the v2 User-based API.
  </Card>

  <Card title="Users" icon="user" href="./users">
    The identity model every partner integration depends on.
  </Card>

  <Card title="REST API overview" icon="code" href="/reference/rest-api-overview">
    Authentication, retries, idempotency, and base URLs for all REST API calls.
  </Card>

  <Card title="Apps and Organizations" icon="building" href="./apps-organizations">
    Provision per-customer App IDs and manage many Apps under one Organization.
  </Card>
</Columns>
