> ## Documentation Index
> Fetch the complete documentation index at: https://codebeans-cb-notifylyst.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Subscribers

> Add back-in-stock sign-ups one at a time or in bulk, list and read them, cancel or re-send.

A **subscriber** is one back-in-stock sign-up: one contact waiting for one variant. The same
person waiting for three variants is three subscribers.

Sign-ups you add through the API follow exactly the same rules as sign-ups from your storefront or
the app's **Add customer signup**: the contact is checked, the variant must be in your store, the
sign-up is linked to the Shopify customer with that email or phone, and the
[`subscriber.created` webhook](https://codebeans-cb-notifylyst.mintlify.site/api/webhooks) and the Flow **New subscriber** trigger fire.

## The subscriber object

```json theme={"system"}
{
  "id": "6731f0c2a9e4b1d2c3f4a5b6",
  "channel": "email",
  "email": "shopper@example.com",
  "phone": null,
  "status": "waiting",
  "product_id": "8123456789012",
  "variant_id": "44012345678901",
  "product_title": "Linen Shirt",
  "variant_title": "M / Sand",
  "sku": "LS-M-SND",
  "quantity": 1,
  "customer_id": "7012345678901",
  "language": "en",
  "custom_fields": [ { "id": "size_note", "label": "Fit preference", "value": "Relaxed" } ],
  "created_at": "2026-11-12T09:30:00.000Z",
  "updated_at": "2026-11-12T09:30:00.000Z"
}
```

| Field | Notes |
| - | - |
| `channel` | `email`, `sms`, `webpush` or `whatsapp`. |
| `email` / `phone` | The contact. Web push sign-ups have neither — they belong to a browser. |
| `status` | See the table below. |
| `customer_id` | The Shopify customer with this email or phone, if there is one. |
| `custom_fields` | Answers to your [sign-up form fields](https://codebeans-cb-notifylyst.mintlify.site/app/guides/sign-up-form-fields.md). |

| `status` | Meaning |
| - | - |
| `waiting` | Waiting for the variant to come back in stock. |
| `queued` | The variant is back; the alert is being sent. |
| `paused_no_credit` | The alert is held because your allowance and wallet ran out. It goes out after a top-up. |
| `notified` | The alert was sent. |
| `cancelled` | Cancelled before it was sent. |
| `failed` | Sending failed. |
| `purchased` | The subscriber bought after being alerted. |

## List subscribers

`GET /api/v1/subscribers`

| Query | Example | Notes |
| - | - | - |
| `status` | `waiting` | One of the statuses above. |
| `channel` | `email` | `email`, `sms`, `webpush`, `whatsapp`. |
| `product_id` | `8123456789012` | |
| `variant_id` | `44012345678901` | |
| `email` | `shopper@example.com` | Exact match, not case-sensitive. |
| `phone` | `+14155550123` | Exact match, international format. |
| `created_from` / `created_to` | `2026-11-01` | Sign-up date range. |
| `limit` / `cursor` | `50` | See [Paging](https://codebeans-cb-notifylyst.mintlify.site/api/authentication.md#paging). |

```bash theme={"system"}
curl "https://cb-notifylyst.cblyst.com/api/v1/subscribers?variant_id=44012345678901&status=waiting" \
  -H "X-API-Key: nl_live_YOUR_KEY"
```

## Get one subscriber

`GET /api/v1/subscribers/{id}` returns `{ "data": { …subscriber } }`, or `404 not_found`.

## Add a sign-up

`POST /api/v1/subscribers`

| Field | Required | Notes |
| - | - | - |
| `variant_id` | Yes | The Shopify variant id (number, or `gid://shopify/ProductVariant/…`). |
| `email` | For email | The shopper's email. |
| `phone` | For SMS | A mobile number in international format (`+14155550123`), or a national number with `country_code`. |
| `country_code` | No | Two-letter country (`US`, `IN`) for a national `phone`. |
| `channel` | No | `email` or `sms`. Worked out from `email` / `phone` when left out. |
| `quantity` | No | How many they want, 1–9999. Default 1. |
| `language` | No | Locale for the alert, such as `fr` or `pt-BR`. Default `en`. |
| `created_at` | No | When they signed up, for moving history from another app. ISO 8601, not in the future. Default now. |
| `custom_fields` | No | Answers to your sign-up form fields, keyed by field id. Not required here, but types and dropdown options are checked. |

```bash theme={"system"}
curl -X POST "https://cb-notifylyst.cblyst.com/api/v1/subscribers" \
  -H "X-API-Key: nl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "9876543210",
    "country_code": "IN",
    "variant_id": "44012345678901",
    "quantity": 2
  }'
```

| Reply | When |
| - | - |
| `201` + `{ "data": { …subscriber } }` | Added. |
| `409 conflict`, `reason: "already_waiting"` | This contact is already waiting for this variant. Nothing was added. |
| `400 invalid_request` + `reason` | See the reasons below. |

> [!NOTE]
>
> Only `email` and `sms` sign-ups can be added. Web push needs the shopper's browser, and WhatsApp
> alerts are not being sent yet. SMS sign-ups need SMS switched on for your store.

Adding a sign-up never sends anything. The alert goes out when the variant is restocked, on your
usual delivery rules.

## Add sign-ups in bulk

`POST /api/v1/subscribers/bulk` with up to **250** items. Each item takes the same fields as a
single sign-up. One bad item never stops the others, and the whole call counts as one request
against your rate limit.

```bash theme={"system"}
curl -X POST "https://cb-notifylyst.cblyst.com/api/v1/subscribers/bulk" \
  -H "X-API-Key: nl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subscribers": [
      { "email": "ana@example.com", "variant_id": "44012345678901" },
      { "email": "ben@example.com", "variant_id": "44012345678901", "created_at": "2026-10-02T08:15:00Z" },
      { "email": "not-an-email", "variant_id": "44012345678901" }
    ]
  }'
```

```json theme={"system"}
{
  "summary": { "received": 3, "created": 2, "skipped": 0, "invalid": 1 },
  "results": [
    { "index": 0, "status": "created", "id": "6731f0c2…", "subscriber": { … } },
    { "index": 1, "status": "created", "id": "6731f0c3…", "subscriber": { … } },
    { "index": 2, "status": "invalid", "code": "invalid_email", "message": "email is not a valid address." }
  ]
}
```

`index` is the item's position in your `subscribers` array.

| `status` | `code` | Meaning |
| - | - | - |
| `skipped` | `already_waiting` | Already waiting for this variant. |
| `skipped` | `duplicate_in_request` | Same contact and variant as an earlier item in this call. |
| `invalid` | `invalid_email`, `invalid_phone`, `invalid_variant_id`, `invalid_quantity`, `invalid_created_at`, `invalid_language`, `invalid_channel` | A field is wrong. |
| `invalid` | `sms_not_active` | SMS is not switched on for your store. |
| `invalid` | `variant_not_found` | The variant is not in your store. |
| `invalid` | `invalid_custom_fields` | A form answer does not fit the field. |
| `invalid` | `not_saved` | Could not be saved. Retry that item. |

> [!TIP]
>
> Retrying is safe. If a call times out, send the same items again: anything already added comes back
> as `skipped / already_waiting` instead of being added twice.

More than 250? Split the list and send the parts one after another. To import a spreadsheet by hand,
use [Import sign-ups](https://codebeans-cb-notifylyst.mintlify.site/app/setup/import-signups.md) in the app instead.

## Cancel a sign-up

`POST /api/v1/subscribers/{id}/cancel` — stops a sign-up that is `waiting`, `queued` or
`paused_no_credit`, including follow-up messages already scheduled. Returns the updated subscriber.
Anything else returns `409 conflict` with its current `status`.

## Re-send an alert

`POST /api/v1/subscribers/{id}/resend` — sends the restock email for one **email** sign-up again.

> [!WARNING]
>
> This is a real send: it uses your allowance or wallet like any alert. It still respects opt-outs and
> blocked addresses. Cancelled and purchased sign-ups are not re-sent (`409 conflict`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.