Devices and users
A device is one push destination: an APNs token, FCM token, or browser Push subscription. A user groups one or more devices under your stable external_user_id so the same person can be reached across platforms.
Register or refresh a device#
POST /v1/devices/register creates or refreshes a registration. It is the only device endpoint intended for routine use from an SDK.
| Field | Required | Rules |
|---|---|---|
platform |
yes | ios, android, or web |
push_token |
yes | Provider token or JSON browser subscription, up to 2,048 characters |
external_user_id |
no | Your user ID, up to 190 characters |
identity_token |
when required | ES256 JWT issued by your backend, up to 8,192 characters |
app_version |
no | Up to 50 characters |
device_model |
no | Up to 120 characters |
os_version |
no | Up to 50 characters |
locale |
no | Up to 20 characters |
timezone |
no | IANA timezone, up to 64 characters |
tags |
no | Object of scalar values; keys may use letters, numbers, dots, _, and - |
Tag values are stored as strings. A JSON null tag value becomes an empty string. Use stable, non-sensitive segmentation facts such as plan, region, or feature cohort; avoid putting secrets or unnecessary personal data in tags.
{
"platform": "android",
"push_token": "fcm-token",
"external_user_id": "account_912",
"app_version": "4.8.1",
"device_model": "Google Pixel 10",
"os_version": "17",
"locale": "en-GB",
"timezone": "Europe/London",
"tags": {
"plan": "unlimited",
"beta.checkout": true
}
}
Browse devices#
GET /v1/devices?page=1&limit=50&platform=ios&enabled=1
GET /v1/devices/{device_id}
The list can be filtered by exact platform and enabled values. Results include platform metadata, status, last-seen time, creation time, and any associated external user ID. Provider tokens are never returned.
Disable a device#
DELETE /v1/devices/{device_id}
Deletion disables and invalidates the registration; it does not expose or delete the provider token directly. Use this on logout or unsubscribe if that device should stop receiving pushes. A second delete returns 404 because the device is already inactive.
The SDK logout/unsubscribe helpers call this endpoint and clear the locally stored HoneyNotify device ID.
Inspect a user#
External IDs are URL path values and should be URL-encoded by your HTTP client.
GET /v1/users/{external_user_id}
The response contains the user profile, aliases, and all associated devices. Internal database IDs and app IDs are not exposed.
Update user attributes#
PATCH /v1/users/{external_user_id}
Content-Type: application/json
{
"locale": "fr-FR",
"timezone": "Europe/Paris",
"tags": {
"plan": "pro",
"region": "eu"
},
"properties": {
"first_name": "Morgan",
"renewal_date": "2026-11-18"
}
}
tags and properties are replaced with the supplied objects; they are not deep-merged. Send the complete state you want to retain. Properties can provide template values such as {{ properties.first_name }}.
Aliases#
Aliases let another identifier resolve to the same user. A label may contain letters, numbers, dots, underscores, and dashes and is limited to 80 characters; its value is limited to 190 characters.
POST /v1/users/account_912/aliases
{"label":"crm_id","value":"contact_88320"}
To remove exactly that alias, send the same label and value in a DELETE request body.
DELETE /v1/users/account_912/aliases
Content-Type: application/json
{"label":"crm_id","value":"contact_88320"}
Delete a user#
DELETE /v1/users/{external_user_id}
This disables the user's devices and removes the subscriber record. Treat it as a destructive privacy action. If the user's active app later registers the same provider token again, a new association can be created, so coordinate deletion with the client and your own account lifecycle.
Recommended lifecycle#
- Register anonymously when push permission and a token are available.
- On login, issue a verified identity token and call the SDK's identify/register method.
- Refresh registration after token, app-version, locale, timezone, or tag changes.
- Track engagement using the stored HoneyNotify
device_id. - On logout, disable the device before clearing local identity.
Migrate existing devices#
Company owners can open an app in the HoneyNotify dashboard, select Device migration, choose the previous provider, download the example CSV, and upload subscribed iOS and Android push subscriptions.
Supported sources are OneSignal, Airship, Amazon SNS, Azure Notification Hubs, Batch, Braze, CleverTap, Customer.io, Expo, Firebase, Iterable, Klaviyo, Kumulos, Pusher Beams, Pushwoosh, and WonderPush. Every source accepts the normalised HoneyNotify template. Native OneSignal exports are also recognised directly; exports from other providers may need their columns mapped to the template.
The upload stages each source subscription in a separate migration lookup table; it does not create an active HoneyNotify device. When the updated app later registers the same APNs or FCM token and platform through the normal HoneyNotify SDK, registration claims that migration record. UUID source IDs carry forward as the HoneyNotify device_id; other source ID formats receive a stable, provider-scoped HoneyNotify UUID. The original provider and source ID remain stored as migration provenance.
The HoneyNotify SDK does not need the old provider ID and customers do not need to add it to their application code.
If no migration record matches the connecting device's token and platform, registration follows the normal path: HoneyNotify creates a new device with a new HoneyNotify UUID. An unrelated or stale CSV row therefore cannot prevent new devices from registering.
The template columns are:
| Column | Required | Description |
|---|---|---|
source_device_id |
yes | Device, installation, registration, endpoint, Subscription, or Player ID from the previous provider |
push_token |
yes | Current APNs or FCM token |
platform |
yes | ios or android |
external_user_id |
no | Customer's stable user identifier |
subscribed |
no | Defaults to true; false rows are skipped |
app_version |
no | Last known application version |
device_model |
no | Last known device model |
os_version |
no | Last known operating-system version |
locale |
no | Last known locale |
timezone |
no | IANA timezone; invalid/numeric offsets are ignored |
tags_json |
no | JSON object containing user tags |
Common heading aliases are recognised for device IDs, push tokens, platforms, external users, subscription status, app and OS versions, device models, locale, timezone, and tags. Direct legacy OneSignal exports are also recognised when they use id, identifier, device_type, external_user_id, invalid_identifier, notification_types, game_version, device_os, and tags headings. Numeric device types 0 and 1 are interpreted as iOS and Android respectively.
Only company owners can download the template or upload a migration. Imports are transactional: a validation or ownership conflict changes no rows. They record an audit event and import history, skip unsubscribed/invalid rows, and store token hashes rather than raw imported push tokens. The organisation's active-device limit is enforced when a staged device actually connects and becomes active.
Configure HoneyNotify with the same APNs application/environment and Firebase project used for the exported tokens. A token that rotated before its first HoneyNotify registration cannot be matched automatically; that installation registers as a new HoneyNotify device.
