# Apple Push Notification Service (APNS) (/platform/integrations/push/apns)

Learn how to use the Apple Push Notification Service (APNS) provider to send push notifications using Novu

import { Tab, Tabs } from 'fumadocs-ui/components/tabs';

This guide explains how to configure and use the <a href="https://developer.apple.com/notifications/" target="_blank" rel="noopener noreferrer">Apple Push Notification Service (APNS)</a> with Novu to deliver push notifications to iOS devices. It outlines:

* The required setup in your Apple Developer account.
* The connection process in Novu.
* How to manage device tokens and message payloads.

## Configuring APNS with Novu

Before sending notifications, APNS must be configured with the correct credentials from your Apple Developer account. Novu uses these credentials to securely authenticate with Apple’s servers.

### Obtain APNS credentials

Apple provides two authentication options for connecting to APNS:

* A certificate-based `.p12` certificate
* A token-based `.p8` key

Novu supports both, but this guide focuses on the `.p8` token-based approach, which is recommended for most production setups.

To generate the required credentials, use an <a href="https://developer.apple.com/" target="_blank" rel="noopener noreferrer">Apple Developer account</a> with an [Admin role](https://appstoreconnect.apple.com/access/users). Follow <a href="https://developer.apple.com/help/account/keys/create-a-private-key" target="_blank" rel="noopener noreferrer">Apple’s official steps</a> to create and download a private `.p8` key.

The following identifiers are also needed for integration:

* <a href="https://developer.apple.com/help/account/keys/get-a-key-identifier/" target="_blank" rel="noopener noreferrer">**Key ID**</a>: A unique 10-character identifier for the authentication key.
* **Team ID**: This is found in your Apple Developer account.
* **Bundle ID**: The identifier for your app, which is available in the app info section.

### Add APNS credentials to Novu

Once the Apple credentials are available, you can add them in Novu’s Integration Store.

1. Log in to your Novu account.
2. On your dashboard, click **Integration Store**.
3. Click **Connect provider**.
4. Click the **Push** tab.
5. Select **APNS**.
6. In the APNS integration form, fill in the **Name** and **Identifier** fields.
7. In the **Delivery Provider Credentials** section, fill in the following fields:
   * **Private Key**: The content of your `.p8` file.
   * **Key ID**: Your 10-character Key ID.
   * **Team ID**: Your 10-character Team ID.
   * **Bundle ID**: Your app's Bundle ID.
     ![APNS Integration in Novu](/images/channels-and-providers/push/apns/apns-integration.png)
8. Click **Create Integration**.

## Sending notifications with APNS

After configuration, APNS can be used in any Novu workflow that includes a Push step. The process involves registering device tokens for subscribers and then triggering workflows to deliver messages.

### Registering subscriber device tokens

Each subscriber (user) must have one or more device tokens registered to receive push notifications. Tokens can be added or updated through Novu’s API using the [Update Subscriber Credentials](/api-reference/subscribers/update-provider-credentials) endpoint.

<Tabs items={['Node.js', 'cURL']}>
  <Tab value="Node.js">
    ```typescript
    import { Novu } from '@novu/api';
    import { ChatOrPushProviderEnum } from "@novu/api/models/components";

    const novu = new Novu({
      secretKey: "<NOVU_SECRET_KEY>",
      // Required if using EU region
      // serverURL: "[https://eu.api.novu.co](https://eu.api.novu.co)",
    });

    await novu.subscribers.credentials.update(
      {
        providerId: ChatOrPushProviderEnum.Apns,
        // Use integrationIdentifier to store device tokens for a specific integration
        integrationIdentifier: "string",
        credentials: {
          deviceTokens: ["token1", "token2", "token3"],
        },
      },
      "subscriberId"
    );
    ```
  </Tab>

  <Tab value="cURL">
    ```bash
    curl -L -X PUT 'https://api.novu.co/v1/subscribers/<SUBSCRIBER_ID>/credentials' \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -H 'Authorization: ApiKey <NOVU_SECRET_KEY>' \
    -d '{
      "providerId": "apns",
      "deviceTokens": ["token1", "token2"],
      "integrationIdentifier": "string"
    }'
    ```
  </Tab>
</Tabs>

### Triggering workflows

Once subscribers’ devices are registered, push notifications are delivered through [workflows that include a Push step](/platform/workflow/create-a-workflow). A workflow can be triggered using the Novu [SDK](/platform/sdks) or [API](/api-reference/events/trigger-event).

```typescript
import { Novu } from '@novu/api';

const novu = new Novu({
  secretKey: "<NOVU_SECRET_KEY>",
});

await novu.trigger({
  workflowId: "workflowId",
  to: {
    subscriberId: 'SUBSCRIBER_ID',
  },
  payload: {
    // Your payload data
  },
});
```

## Customizing notifications with overrides

Novu supports an `overrides` field that lets you attach APNS-specific payload parameters when triggering a workflow. This feature is useful for customizing the behavior or presentation of notifications, such as setting titles, bodies, or custom data fields.

The `overrides` field supports all <a href="https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification?language=objc" target="_blank" rel="noopener noreferrer">APNS Notification payload</a> values. Here is an example:

```typescript
import { Novu } from '@novu/api';

const novu = new Novu({
  secretKey: "<NOVU_SECRET_KEY>",
  // Required if using EU region
  // serverURL: "https://eu.api.novu.co",
});

await novu.trigger({
  workflowId: "workflowId",
  to: {
    subscriberId: "subscriberId",
  },
  payload: {
    abc: 'def', // If the notification is a data notification, then the payload is sent as the data
  },
  overrides: {
    apns: {
      payload: {
        aps: {
          notification: {
            title: 'Test',
            body: 'Test push',
          },
          data: {
            key: 'value',
          },
        },
      },
    },
  },
});
```
