---
title: "Register a push device"
method: POST
path: "/push/devices"
tags: ["Push"]
---

# Register a push device

`POST /push/devices`

## Request

- Base URL: `https://api.sequenzy.com/api/v1`
- URL: `https://api.sequenzy.com/api/v1/push/devices`
- Auth: HTTP bearer

Registers or refreshes a device, typically from your app backend after the app receives its APNs or FCM token. Re-registering a known token reactivates it, refreshes its metadata and moves it to the given contact. An unknown email becomes a contact quietly (no lists, no contact_added sequences). Each contact keeps at most 20 active devices; the least recently seen are retired. Returns 201 for a new token and 200 for an existing one. Requires the subscribers:write scope.

## Request body

- object
  - `platform` 'ios' | 'android' | 'web', required
  - `token` string, required: iOS: the hex APNs device token. Android: the FCM registration token. Web: the PushSubscription endpoint (also send keys).
  - `keys` object: Web only. PushSubscription.toJSON().keys.
    - `p256dh` string
    - `auth` string
  - `email` string: Contact to link. Created quietly when new.
  - `subscriberId` string: Existing subscriber to link instead of email.
  - `deviceName` string
  - `appVersion` string
  - `osVersion` string
  - `locale` string
  - `timezone` string: IANA timezone.

## Response `200`

Device already known and updated

- object
  - `success` boolean
  - `created` boolean
  - `device` PushDevice
    - `id` string
    - `subscriberId` string, nullable: Linked contact, or null for anonymous browsers.
    - `platform` 'web' | 'ios' | 'android'
    - `status` 'active' | 'invalid' | 'unsubscribed'
    - `invalidReason` string, nullable: Why the push service rejected the token, for invalid devices.
    - `source` 'web_sdk' | 'mobile_sdk' | 'api': web_sdk for browsers, mobile_sdk for devices the iOS, Android, React Native and Flutter SDKs registered, api for devices registered with a secret key.
    - `deviceName` string, nullable
    - `userAgent` string, nullable
    - `appVersion` string, nullable
    - `osVersion` string, nullable
    - `locale` string, nullable
    - `timezone` string, nullable
    - `tokenPreview` string: Last characters of the token.
    - `lastSeenAt` string, date-time
    - `createdAt` string, date-time
  - `message` string

## Other responses

- `201`: Device registered
- `400`: Validation error
- `401`: Unauthorized
- `403`: Missing subscribers:write scope
- `404`: Subscriber not found
- `500`: Server error

## Changes

- **2026-10-20** `54f67ac2d016`: 2 warning
  - added the new `mobile_sdk` enum value to the `device/source` response property for the response status `200`
  - added the new `mobile_sdk` enum value to the `device/source` response property for the response status `201`
- **2026-10-16** `db3873ca3d4d`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/sequenzy/apis/sequenzy-api/changes/push/devices/post.md)

---

[API](https://skmtc.dev/sequenzy/apis/sequenzy-api.md) - [All operations](https://skmtc.dev/sequenzy/apis/sequenzy-api/llms.txt) - [OpenAPI document](https://skmtc.dev/sequenzy/apis/sequenzy-api/revisions/3d816357b738?raw)
