Skip to content
Fluxer API

Push notifications

A Web Push registration gets each notification as an RFC 8291 encrypted record. Your client generates a P-256 key pair and an auth secret, registers the public key and decrypts each record with the private key. These routes need a user session token.

A registration is Web Push when token is an endpoint URL sent with both keys, and raw when token is a vendor device token sent with no keys.

FormtokenKeys
Web PushA publicly routable endpoint URLencryption_key and auth_secret
RawA vendor device tokenNeither

platform is one of these values.

PlatformTransport
android_fcmFirebase Cloud Messaging
ios_apnsApple Push Notification service
ios_apns_voipApple PushKit, for incoming calls on iOS
android_unified_pushUnifiedPush

android_unified_push and ios_apns_voip only accept Web Push. An iOS device that answers calls registers both ios_apns and ios_apns_voip, each with its own key pair.

FieldTypeDescription
device_idstringThe registration ID, 32 lowercase hexadecimal characters

Registering again with the same platform, app_id, provider_environment and token replaces the registration and returns the same device_id.

POST/v1/users/@me/mobile-devices

Stores a push registration and returns its device registration object. Web Push endpoints must be https URLs on public hosts.

FieldTypeDescription
platformstringThe platform of the device
tokenstringThe endpoint URL, or the vendor token on a raw registration (1-4096 characters)
encryption_key?stringThe base64url P-256 public key, Web Push only (1-1024 characters)
auth_secret?stringThe base64url auth secret, Web Push only (1-1024 characters)
app_id?stringThe client build, such as stable, beta or canary (default stable)
provider_environment?stringproduction or development, used by APNs only
user_agent?stringA user agent string describing the device (1-1024 characters)

When provider_environment is omitted, it defaults to production on ios_apns and ios_apns_voip and stays empty on other platforms. To get thread and forum new post notifications on this device, send the channel_threads client capability with the request.

StatusBodyCondition
200device registration objectThe registration was stored
400error responseINVALID_FORM_BODY when the body matches neither form
400error responseURL_NOT_PUBLICLY_ROUTABLE on token when the endpoint is a private or reserved address

The rate limit is 20 requests per minute, on the user:push:subscribe bucket.

POST/v1/users/@me/mobile-devices/unregister

Removes the registration that matches platform, token, app_id and provider_environment, and returns 200 even when none matches.

FieldTypeDescription
platformstringThe platform sent at registration
tokenstringThe token sent at registration (1-4096 characters)
app_id?stringThe client build sent at registration (default stable)
provider_environment?stringThe environment sent at registration
FieldTypeDescription
successbooleanAlways true
StatusBodyCondition
200response bodyThe registration was removed, or there was none

The rate limit is 40 requests per minute, on the user:push:unsubscribe bucket.

Fluxer posts one aes128gcm record to a Web Push endpoint for each notification. A raw registration gets an unencrypted APNs or FCM message instead. A record has at most 2713 bytes of JSON. When a notification is too large, Fluxer leaves out media and icons and shortens the body text, and your client has to handle those fields being missing.

Fluxer sets these Web Push headers on each record.

HeaderValue
TTL86400 on a notification and a clear, and 0 on a call ring
Urgencyhigh on a notification and a call ring, and low on a clear

Each payload is one of these kinds.

KindHow to recognize itWhat to do
NotificationAny other payloadShow it, using title, body, icon and image_url, and open data.url when tapped
ClearTop-level type is notification_clear and action is clear_channelDismiss what you showed for data.channel_id
Call ringTop-level type is call_ringSee Call ring

When an endpoint answers 404 or 410, Fluxer removes the registration. It retries a 429 or 5xx response and keeps the registration.

Only ios_apns_voip registrations and Web Push android_fcm registrations get call rings, and an ios_apns_voip registration gets nothing else. A call ring payload has these fields under data.

FieldTypeDescription
typestringAlways call_ring
channel_idstringThe private channel the call is in
message_idstringThe call message, which identifies the call
target_user_idstringThe account being rung
started_at_msintegerWhen the ring started, in milliseconds since the Unix epoch
expires_at_msintegerWhen the ring ends, in milliseconds since the Unix epoch
caller_id?stringThe account placing the call
caller_name?stringThe name to show for the caller
caller_avatar_url?stringAn image URL for the caller

caller_id and caller_name are sent together or not at all, and caller_avatar_url can be missing even when they are present. Ring until expires_at_ms even when they are missing. Fluxer sends no push when a call ends, and your client learns that from the Gateway connection.

iOS ends an app that gets a PushKit push without reporting a call to CallKit. Report a call for every PushKit push before you decrypt it, and end the call right away in any of these cases.

CaseCause
The record does not decryptThe registered keys no longer match your key pair
type is not call_ringThe push is not a call ring
The Gateway reports no live call for channel_idThe call ended before the ring arrived

Use message_id to build the CallKit call UUID, so every push for the same call maps to one CallKit call.

Discard the record and show nothing. Fluxer can't tell that decryption failed, and your client has to unregister and register again with its current keys.