Choose an SDK
All SDKs expose two paths. The scoped API-token client uses one Dashboard Authorization key (PushNow_...) for account reads, source reads, history, logs and direct /v2/messages notification sends according to its scopes. The backend encrypts token sends with the same-account sender key saved by a signed-in Web or app client. The E2EE sender path still supports local sender authorization, local content encryption and encrypted attachment upload. The source packages are in the repository; no registry publication is assumed by these instructions.
| Language | Repository directory | Runtime | Guide |
|---|---|---|---|
| TypeScript / JavaScript | sdk/typescript |
Modern browser with WebCrypto, or Node.js 22+ | TypeScript and npm |
| Python | sdk/python |
Python 3.10+ and Node.js 22+ | Python |
| Go | sdk/go |
Go 1.22+ and Node.js 22+ | Go |
| Java | sdk/java |
Java 11+ and Node.js 22+ | Java |
Python, Go and Java are subprocess bindings to a bundled, pinned JavaScript HPKE runtime. They are not native cryptographic implementations and their compiled artifacts do not embed Node. Deploy runtime/ and its installed dependencies alongside your service.
One key, scoped capabilities
Create an API token in Dashboard and select scopes. Use account:read for getAccount / account, sources:read for source listing, send:write for sendMessage, history:read for history, history:write for state changes and deletion, logs:read for delivery logs, or all for every scoped token helper. The same key is sent as Authorization: Bearer <PushNow_...>.
This token path is best for integrations and simple webhook-style messages. sendMessage submits title/body to /v2/messages; PushNow encrypts it server-side with the same account's saved sender key.
Authorization is separate from E2EE login
Sign in and initialize the account in the iOS app first. The SDK's authorization flow does not register users or sign them in with email/password. It creates a sender key pair and asks your trusted device to approve it.
The recommended flow starts authorization with an account access token from a signed-in app or trusted dashboard session, then completes approval on the trusted phone. The token only authorizes the setup request; it is not enough to encrypt messages.
SDK authorization now uses the account Access Token flow only. The token starts an account-bound authorization, and the signed-in trusted app still approves the sender before the SDK receives a reusable encrypted config.
The resulting configuration includes api_url, user_id, source_id, source_key, identity_public_key, sender_private_key and the certified archive public record. Keep it secret. A scoped API token can call scoped HTTP endpoints and send with send:write; use this sender configuration only when you need client-side envelope encryption or attachment encryption.
Options differ by language
| Behavior | TypeScript | Python / Java | Go |
|---|---|---|---|
| All devices | Omit deviceIds |
Omit deviceIds |
DeviceIDs: nil |
| Selected devices | deviceIds: [id] |
deviceIds list/JSON array |
Pointer to a slice of IDs |
| Inbox-only | inboxOnly: true or deviceIds: [] |
pushEnabled: false or empty deviceIds |
PushEnabled points to false, or pointer to empty IDs |
| Schedule | scheduledAt option |
scheduledAt input |
ScheduledAt |
| Images | image file input |
images file list |
Images |
| Sound | MessageOptions.sound |
sound input |
Sound pointer |
Device targeting never limits shared account history. Scheduling is within 30 days and does not hide the saved message until the due time. See Content and Scheduling.
All sound inputs use the enum default | silent | chime; omission preserves default behavior. Sound is public routing metadata, while message content remains HPKE-encrypted and files remain AES-GCM-encrypted. Silent still requests a visible alert; chime uses the new app's bundled asset, not an arbitrary filename or upload. iOS settings and Focus/DND apply, with no critical-alert guarantee. This sound contract is being implemented; migration, deployment and audible-device verification are pending. See sound modes and rollout status.
Retries and logging
Prepare once and retry the exact envelope. The TypeScript SDK currently keeps an in-memory account/source binding on the prepared object; serialized outbox import is not supported there. Keep the original prepared object for retries. The CLI and Python/Go/Java bindings provide durable encrypted outbox workflows.
Use SDK request metadata callbacks or log accessors for diagnostics. They intentionally expose method, endpoint template, status and elapsed time rather than tokens or payloads. These local traces are separate from the account's delivery logs.
Successful SDK submission is API acceptance, not confirmation that a device displayed the alert.