GET/v1/devices

List/search devices (sk_ with devices:read). Filters q, status, platform, externalUserId; paginated.

Key: sk_

Parameters

NameInTypeDescription
appIdquerystring
qquerystring
statusquery"active" | "pending_credential" | "invalid" | "unsubscribed"
platformquery"android" | "ios" | "web"
externalUserIdquerystring
pagequeryinteger
perPagequeryinteger

Responses: 200403

curl -X GET "https://api.pushtifly.com/v1/devices" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

POST/v1/devices

Register or update a device (upsert by token). pk_ or sk_ with devices:write.

Key: pk_ / sk_

The provider is detected from the token format (FCM or APNs). Huawei phones: provider "hms" with the Push Kit token.
Browsers: platform "web" and subscription
(PushSubscription.toJSON()); its endpoint acts as the token. Errors: 2004 platform not enabled in the app,
2005 token inconsistent with platform/provider, 2006 Expo token, 2012 time zone. If the app has no credential for
the provider, the device stays pending_credential (meta.warnings explains it) and becomes active once it is uploaded.

Body

FieldTypeDescription
appIdstring
tokenstringFCM registration token, Firebase Installation ID (22 characters), APNs token (hexadecimal) or Huawei Push Kit token (with provider hms). Not sent on web: subscription is sent instead. · max. 512 characters
platform"android" | "ios" | "web"
provider"fcm" | "apns" | "webpush" | "hms"Optional: detected from the format. Required for Huawei (hms), whose token cannot be told apart by its format.
subscriptionobjectWeb only: the browser's PushSubscription.toJSON(). The endpoint must belong to a known Web Push service (https).
subscription.endpointstringmax. 512 characters
subscription.keysobject
environment"sandbox" | "production" | "auto"
frameworkstring
sdkNamestring
sdkVersionstring
capabilities"images" | "actions" | "open_tracking" | "foreground_display" | "deep_links" | "carousel"[]
externalUserIdstring
languagestring
timezonestring
countrystring
appVersionstring
osVersionstring
deviceModelstring
notificationsEnabledboolean
tagsobject

Responses: 200201422

curl -X POST "https://api.pushtifly.com/v1/devices" \
  -H "Authorization: Bearer pk_test_YOUR_PUBLIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "token": "DEVICE_FCM_OR_APNS_TOKEN",
  "platform": "android",
  "environment": "auto",
  "externalUserId": "customer-123",
  "language": "en",
  "timezone": "America/New_York",
  "appVersion": "2.4.0",
  "notificationsEnabled": true,
  "tags": {
    "plan": "gold",
    "city": "boston"
  }
}'

GET/v1/devices/by-user/{externalUserId}

Devices of an external user (sk_)

Key: sk_

Parameters

NameInTypeDescription
externalUserId*pathstring

Responses: 200

curl -X GET "https://api.pushtifly.com/v1/devices/by-user/customer-123" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

GET/v1/web-push/key

The app's public VAPID key (Web Push), for PushManager.subscribe(). pk_ or sk_; 5001 if the app has no keys

Key: pk_ / sk_

Parameters

NameInTypeDescription
appIdquerystring

Responses: 200422

curl -X GET "https://api.pushtifly.com/v1/web-push/key" \
  -H "Authorization: Bearer pk_test_YOUR_PUBLIC_KEY"

GET/v1/devices/{token}

Details (with tags and topics). sk_.

Key: sk_

Parameters

NameInTypeDescription
token*pathstringURL-encoded token or the device id (required on web: the token is a URL)

Responses: 200404

curl -X GET "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

PATCH/v1/devices/{token}

Update attributes (language, time zone, versions, notificationsEnabled…)

Key: sk_

Parameters

NameInTypeDescription
token*pathstringURL-encoded token or the device id (required on web: the token is a URL)

Body

FieldTypeDescription
appIdstring
tokenstringFCM registration token, Firebase Installation ID (22 characters), APNs token (hexadecimal) or Huawei Push Kit token (with provider hms). Not sent on web: subscription is sent instead. · max. 512 characters
platform"android" | "ios" | "web"
provider"fcm" | "apns" | "webpush" | "hms"Optional: detected from the format. Required for Huawei (hms), whose token cannot be told apart by its format.
subscriptionobjectWeb only: the browser's PushSubscription.toJSON(). The endpoint must belong to a known Web Push service (https).
subscription.endpointstringmax. 512 characters
subscription.keysobject
environment"sandbox" | "production" | "auto"
frameworkstring
sdkNamestring
sdkVersionstring
capabilities"images" | "actions" | "open_tracking" | "foreground_display" | "deep_links" | "carousel"[]
externalUserIdstring
languagestring
timezonestring
countrystring
appVersionstring
osVersionstring
deviceModelstring
notificationsEnabledboolean
tagsobject

Responses: 200

curl -X PATCH "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "language": "es",
  "notificationsEnabled": false,
  "tags": {
    "plan": "platinum"
  }
}'

DELETE/v1/devices/{token}

Unsubscribe (status unsubscribed; registering again reactivates it)

Key: sk_

Parameters

NameInTypeDescription
token*pathstringURL-encoded token or the device id (required on web: the token is a URL)

Responses: 200

curl -X DELETE "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

POST/v1/devices/{token}/identify

Link externalUserId

Key: sk_

Parameters

NameInTypeDescription
token*pathstring

Body

FieldTypeDescription
externalUserId*stringmax. 191 characters

Responses: 200

curl -X POST "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN/identify" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "externalUserId": "customer-123"
}'

POST/v1/devices/{token}/logout

Unlink externalUserId

Key: sk_

Parameters

NameInTypeDescription
token*pathstring

Responses: 200

curl -X POST "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN/logout" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

PUT/v1/devices/{token}/tags

Merge tags (null deletes a key) or replace them all with replace=true. Maximum 50.

Key: sk_

Parameters

NameInTypeDescription
token*pathstring

Body

FieldTypeDescription
tagsobject
replaceboolean

Responses: 200

curl -X PUT "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN/tags" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "tags": {
    "plan": "gold",
    "last_purchase": "2026-10-01"
  }
}'

POST/v1/devices/{token}/topics/{topic}

Subscribe to a topic (created if it doesn't exist)

Key: sk_

Parameters

NameInTypeDescription
token*pathstring
topic*pathstring

Responses: 200

curl -X POST "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN/topics/offers" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

DELETE/v1/devices/{token}/topics/{topic}

Unsubscribe

Key: sk_

Parameters

NameInTypeDescription
token*pathstring
topic*pathstring

Responses: 200

curl -X DELETE "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN/topics/offers" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"

POST/v1/devices/{token}/pair

Mark as a test device with the 6-digit code from the panel (2008 if it is invalid or expired)

Key: sk_

Parameters

NameInTypeDescription
token*pathstring

Body

FieldTypeDescription
code*string

Responses: 200422

curl -X POST "https://api.pushtifly.com/v1/devices/DEVICE_TOKEN/pair" \
  -H "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "code": "482913"
}'