notifly
IntegrationsPush providerUpdated

iOS push through APNs, sent from Notifly workflows.

Talk to Apple Push Notification service directly, with your own signing key. You connect APNs to Notifly with a .p8 key and your app's identifiers, register your users' device tokens, and the push steps of your Notifly workflows are delivered by Apple to your iOS app.

Notifly adds the parts APNs leaves to your backend: one trigger for push, in-app, email, SMS and chat; token bookkeeping per user; digest, delay and throttle steps; subscriber preferences checked before each send; and an activity feed with Apple's answer for every device.

What you need from Apple

These are the fields the dashboard asks for when you connect APNs, quoted from the create form.

FieldRequiredStoredNotes
Private KeyRequiredEncrypted at restA multi-line field: paste the whole file.
Key IDRequiredEncrypted at rest
Team IDRequiredAs entered
Bundle IDRequiredAs entered
ProductionOptionalAs entered
  • Private Key. The whole .p8 signing key, from its -----BEGIN PRIVATE KEY----- line to its -----END PRIVATE KEY----- line. Notifly signs its APNs requests with it.
  • Key ID and Team ID. The identifier of that key and of your Apple Developer team.
  • Bundle ID. Your app's bundle identifier, sent as the APNs topic of every notification.
  • Production. Off sends to the APNs sandbox, on sends to production.

Connect APNs in the dashboard

  1. Sign in at app.notifly.io, open Integration Store in the sidebar and choose Connect Provider.
  2. In the Connect Integration sheet, open the Push tab (or search across channels), find APNs and choose Connect.
  3. Pick the environment the integration belongs to. Development and Production keep separate integrations, so you can point each at a different APNs account or key.
  4. Fill in Delivery Provider Credentials with the fields in the table above, then choose Create Integration.

Register a device, then trigger a push

Tokens live on the subscriber, and registering one needs the APNs integration to exist in that environment. After that the trigger only names the user: Notifly sends to every APNs token they have registered.

Node.js · @notiflyio/api@0.1.26
// npm install @notiflyio/api@0.1.26
import { Notifly } from "@notiflyio/api";

const notifly = new Notifly({ security: { secretKey: process.env.NOTIFLY_SECRET_KEY } });

// When your iOS app sends its APNs device token to your backend:
await notifly.subscribers.credentials.registerToken({
  subscriberId: "user_123",
  providerId: "apns",
  registerSubscriberDeviceTokenRequestDto: { token: apnsDeviceToken },
});

// Later, whenever something happens:
await notifly.trigger({
  workflowId: "new-message",
  to: "user_123",
  payload: { from: "Ada", threadId: "t_981" },
});

Prefer plain HTTP? The same trigger is POST https://api.notifly.io/v1/events/trigger with an Authorization: ApiKey header and a body of { "name", "to", "payload" }.

What reaches APNs

  • A notification per token. Title and body from the push step, signed with your key and sent to your bundle ID's topic, one registered token at a time.
  • Your payload as custom keys. The trigger payload rides in the APNs payload, with Notifly's message id as __nvMessageId.
  • A collapse id. The Notifly message id, unless the trigger sets its own collapseId.
  • Clean token lists. Tokens APNs rejects as bad, unregistered, expired or for another topic are removed from the subscriber, on by default.
  • No token, no call. A subscriber with no APNs token is skipped and recorded in the activity feed.

What Notifly adds on top of APNs

Workflows around the send

One trigger runs a workflow: this provider’s step can sit beside in-app, email, SMS, push and chat steps, behind digest, delay and throttle steps.

Digest notifications →

Subscriber preferences, enforced at send

Before each step runs, the subscriber’s workflow and channel preferences are checked; an opted-out step is skipped and the reason is recorded.

An in-app Inbox next to it

The same workflow can write to the Notifly Inbox, a real-time in-app feed you embed with the React component or the JavaScript SDK.

React notification inbox →

Per-trigger provider parameters

Anything the trigger passes under overrides.providers.<provider id> is merged into the request Notifly sends to the provider, per workflow or per step.

Activity you can debug

Every message gets execution details in the activity feed, including the response or error the provider returned.

Secrets encrypted at rest

API keys, tokens and service accounts are stored encrypted with AES-256; new and re-saved credentials use authenticated AES-256-GCM. The table above marks which of this provider’s fields that covers.

Go deeper in the docs

Frequently asked questions

Which Apple credentials does Notifly need?

A token-based APNs signing key. Paste the contents of its .p8 file into Private Key (the form checks for the BEGIN PRIVATE KEY and END PRIVATE KEY lines), then add the key's Key ID, your Apple Developer Team ID and your app's bundle ID, which Notifly sends as the APNs topic. The Private Key and Key ID are stored encrypted at rest.

What does the Production switch do?

It picks Apple's environment. Switched off, which is the default, Notifly sends to the APNs sandbox; switched on, it sends to production. Because Development and Production are separate Notifly environments with separate integrations, you can connect APNs in each with the switch set to match.

What happens to device tokens APNs rejects?

When APNs refuses a token with the reason BadDeviceToken, Unregistered, ExpiredToken, DeviceTokenNotForTopic or TopicDisallowed, Notifly removes that token from the subscriber. This is on by default, so a token from a deleted app is not sent to again and needs no cleanup job.

Does each device get its own push?

Yes. Notifly sends one APNs notification per registered token and records each one in the activity feed with the token it went to, and a refused token records APNs's reason there, for example failed for reason: BadDeviceToken.

Can my app tell which Notifly message a push came from?

Yes. The trigger payload travels as custom keys in the APNs payload, with the Notifly message id under __nvMessageId. Notifly also uses that message id as the APNs collapse id unless the trigger passes its own collapseId.

Bring your provider account. Keep your sender reputation.

One POST /v1/events/trigger — email, SMS, push, in-app, and chat. 10,000 events a month, free.

Get started freeSee pricing