---
title: "Subscribers"
description: "People and devices in one app and environment."
canonical: https://docs.notifiable.sh/api/subscribers
source: https://docs.notifiable.sh/api/subscribers.md
---

# Subscribers

People and devices in one app and environment.

These routes are the public API. Send `Authorization: Bearer` with a workspace server API key. The key can act on every app in the workspace. A route that names an app uses that app id. `environment` is `development` or `production`.

## `GET /api/v1/public/apps/{app}/environments/{environment}/subscribers`

The subscribers were listed.

Path

- `app` — App id in this workspace.
- `environment` — development or production.

Query

- `search` (string)
- `platform` (`iOS`, `Android`, `Web`)
- `push` (`enabled`, `denied`, `not_determined`)
- `page` (integer)
- `per_page` (`10`, `25`, `50`)

Responses

- `200` `SUBSCRIBERS_LISTED` — The subscribers were listed.
  - `page` (integer, required)
  - `per_page` (integer, required)
  - `total` (integer, required)
- `401` `INVALID_API_KEY` — The API key is invalid.
- `404` `APP_NOT_FOUND` — The app could not be found.
- `422` `VALIDATION_FAILED` — The request contains invalid fields.
- `429` `RATE_LIMIT_EXCEEDED` — Too many requests. Please try again later.
- `500` `SERVER_ERROR` — Something went wrong. Please try again.

## `POST /api/v1/public/apps/{app}/environments/{environment}/subscribers`

The subscriber was saved.

Path

- `app` — App id in this workspace.
- `environment` — `development` or `production`.

Body

- `device_id` (string, required) — Stable id of this install. Required on save. The same id in this app and environment updates the existing subscriber.
- `platform` (`ios`, `android`, `web`, required)
- `sdk` (`expo`, `react-native`, `flutter`, `swift`, `kotlin`, `web`, required) — Client package: expo, react-native, flutter, swift, kotlin, or web. Required on save.
- `permission` (`granted`, `denied`, `not_determined`, required)
- `provider` (optional)
- `token` (string, optional) — Push token. Required on save when permission is granted. On update, required only when the subscriber has no token yet. A token already stored for another device in this environment moves to this device.
- `external_id` (string, optional) — Your user id. Omit to leave it unchanged. Send null to clear it.
- `anonymous_id` (string, optional) — Id for a guest who is not signed in. Omit to leave it unchanged. Send null to clear it.
- `email` (email, optional) — Email address. Omit to leave it unchanged. Send null to clear it.
- `first_name` (string, optional) — Given name. Omit to leave it unchanged. Send null to clear it.
- `last_name` (string, optional) — Family name. Omit to leave it unchanged. Send null to clear it.
- `device_model` (string, optional) — Device model, such as iPhone 16. Omit to leave it unchanged.
- `device_manufacturer` (string, optional) — Device manufacturer, such as Apple. Omit to leave it unchanged.
- `device_ip` (string, optional) — Device IP address. Omit to leave it unchanged.
- `os_version` (string, optional) — Operating system version. Omit to leave it unchanged.
- `app_version` (string, optional) — Your app version. Omit to leave it unchanged.
- `sdk_version` (string, optional) — Notifiable package version. Omit to leave it unchanged.
- `locale` (string, optional) — Locale, such as en-US. Omit to leave it unchanged.
- `language` (string, optional) — Language, such as en. Omit to leave it unchanged.
- `timezone` (string, optional) — Timezone, such as Africa/Casablanca. Omit to leave it unchanged.
- `country_code` (string, optional) — ISO 3166-1 alpha-2 country code. Stored in uppercase. Omit to leave it unchanged.
- `attributes` (array of string, optional) — Object of properties, up to 20 keys. A value is text, a number, a boolean, or one nested object of those. Keys are at most 40 characters. Omit to leave them unchanged. Send an empty object to clear them.
- `tags` (array of string, optional) — List of up to 20 labels. Each label is at most 80 characters. Omit to leave them unchanged.
- `prompted` (boolean, optional) — Send true after the SDK has asked for permission again. Clears the pending prompt even when permission is unchanged.
- `notifications_enabled` (boolean, optional)

Responses

- `201` `SUBSCRIBER_SAVED` — The subscriber was saved.
- `200` `SUBSCRIBER_SAVED` — The subscriber was saved.
- `401` `INVALID_API_KEY` — The API key is invalid.
- `403` `SUBSCRIBER_LIMIT_REACHED` — This workspace has reached its subscriber limit.
- `404` `APP_NOT_FOUND` — The app could not be found.
- `422` `VALIDATION_FAILED` — The request contains invalid fields.
- `429` `RATE_LIMIT_EXCEEDED` — Too many requests. Please try again later.
- `500` `SERVER_ERROR` — Something went wrong. Please try again.

## `POST /api/v1/public/apps/{app}/environments/{environment}/subscribers/bulk`

The subscribers were updated.

Path

- `app` — App id in this workspace.
- `environment` — `development` or `production`.

Body

- `action` (`subscribe`, `unsubscribe`, `delete`, `prompt`, `prompt_denied`, required)
- `ids` (array of uuid, optional)

Responses

- `200` `SUBSCRIBERS_UPDATED` — The subscribers were updated.
  - `action` (string, required)
- `401` `INVALID_API_KEY` — The API key is invalid.
- `404` `APP_NOT_FOUND` — The app could not be found.
- `422` `VALIDATION_FAILED` — The request contains invalid fields.
- `429` `RATE_LIMIT_EXCEEDED` — Too many requests. Please try again later.
- `500` `SERVER_ERROR` — Something went wrong. Please try again.

## `DELETE /api/v1/public/apps/{app}/environments/{environment}/subscribers/{subscriber}`

The subscriber was deleted.

Path

- `app` — App id in this workspace.
- `environment` — `development` or `production`.
- `subscriber` — Subscriber id.

Responses

- `200` `SUBSCRIBER_DELETED` — The subscriber was deleted.
  - `id` (string, required)
- `401` `INVALID_API_KEY` — The API key is invalid.
- `404` `APP_NOT_FOUND` — The app could not be found.
- `429` `RATE_LIMIT_EXCEEDED` — Too many requests. Please try again later.
- `500` `SERVER_ERROR` — Something went wrong. Please try again.

## `GET /api/v1/public/apps/{app}/environments/{environment}/subscribers/{subscriber}`

The subscriber was found.

Path

- `app` — App id in this workspace.
- `environment` — `development` or `production`.
- `subscriber` — Subscriber id.

Responses

- `200` `SUBSCRIBER_FETCHED` — The subscriber was found.
- `401` `INVALID_API_KEY` — The API key is invalid.
- `404` `SUBSCRIBER_NOT_FOUND` — The subscriber could not be found.
- `429` `RATE_LIMIT_EXCEEDED` — Too many requests. Please try again later.
- `500` `SERVER_ERROR` — Something went wrong. Please try again.

## `PATCH /api/v1/public/apps/{app}/environments/{environment}/subscribers/{subscriber}`

The subscriber was updated.

Path

- `app` — App id in this workspace.
- `environment` — `development` or `production`.
- `subscriber` — Subscriber id.

Body

- `device_id` (string, required) — Stable id of this install. Required on save. The same id in this app and environment updates the existing subscriber.
- `platform` (`ios`, `android`, `web`, required)
- `sdk` (`expo`, `react-native`, `flutter`, `swift`, `kotlin`, `web`, required) — Client package: expo, react-native, flutter, swift, kotlin, or web. Required on save.
- `permission` (`granted`, `denied`, `not_determined`, required)
- `provider` (optional)
- `token` (string, optional) — Push token. Required on save when permission is granted. On update, required only when the subscriber has no token yet. A token already stored for another device in this environment moves to this device.
- `external_id` (string, optional) — Your user id. Omit to leave it unchanged. Send null to clear it.
- `anonymous_id` (string, optional) — Id for a guest who is not signed in. Omit to leave it unchanged. Send null to clear it.
- `email` (email, optional) — Email address. Omit to leave it unchanged. Send null to clear it.
- `first_name` (string, optional) — Given name. Omit to leave it unchanged. Send null to clear it.
- `last_name` (string, optional) — Family name. Omit to leave it unchanged. Send null to clear it.
- `device_model` (string, optional) — Device model, such as iPhone 16. Omit to leave it unchanged.
- `device_manufacturer` (string, optional) — Device manufacturer, such as Apple. Omit to leave it unchanged.
- `device_ip` (string, optional) — Device IP address. Omit to leave it unchanged.
- `os_version` (string, optional) — Operating system version. Omit to leave it unchanged.
- `app_version` (string, optional) — Your app version. Omit to leave it unchanged.
- `sdk_version` (string, optional) — Notifiable package version. Omit to leave it unchanged.
- `locale` (string, optional) — Locale, such as en-US. Omit to leave it unchanged.
- `language` (string, optional) — Language, such as en. Omit to leave it unchanged.
- `timezone` (string, optional) — Timezone, such as Africa/Casablanca. Omit to leave it unchanged.
- `country_code` (string, optional) — ISO 3166-1 alpha-2 country code. Stored in uppercase. Omit to leave it unchanged.
- `attributes` (array of string, optional) — Object of properties, up to 20 keys. A value is text, a number, a boolean, or one nested object of those. Keys are at most 40 characters. Omit to leave them unchanged. Send an empty object to clear them.
- `tags` (array of string, optional) — List of up to 20 labels. Each label is at most 80 characters. Omit to leave them unchanged.
- `prompted` (boolean, optional) — Send true after the SDK has asked for permission again. Clears the pending prompt even when permission is unchanged.
- `notifications_enabled` (boolean, optional)

Responses

- `200` `SUBSCRIBER_UPDATED` — The subscriber was updated.
- `401` `INVALID_API_KEY` — The API key is invalid.
- `404` `SUBSCRIBER_NOT_FOUND` — The subscriber could not be found.
- `422` `VALIDATION_FAILED` — The request contains invalid fields.
- `429` `RATE_LIMIT_EXCEEDED` — Too many requests. Please try again later.
- `500` `SERVER_ERROR` — Something went wrong. Please try again.
