ReachBellDocs

Subscribers API

The Subscribers API is how you manage the devices that receive your pushes. Most of these routes are called by the SDK on your behalf — the ones you'll touch from your own backend are identify and tag.

All routes require authentication. Use x-api-key for server-to-server calls, or a JWT plus x-org-id for dashboard reads. See Authentication for the details.

Register a subscriber

POST /subscribers

The SDK calls this for you when a visitor accepts the opt-in prompt. You rarely call this directly. If you do, the body must include the push subscription endpoint, the encryption keys, and the project ID.

curl -X POST https://api.reachbell.com/subscribers \
  -H "x-api-key: rb_live_yourkey" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId":  "proj_01HX2...",
    "endpoint":   "https://fcm.googleapis.com/fcm/send/...",
    "p256dh":     "BNc...",
    "auth":       "tZk...",
    "userAgent":  "Mozilla/5.0 ..."
  }'

Success:

{
  "id":        "sub_01HX3...",
  "token":     "tok_01HX3...",
  "projectId": "proj_01HX2...",
  "status":    "active"
}

A duplicate registration of the same endpoint returns 409 Conflict with the existing subscriber.

Identify a subscriber

POST /subscribers/identify

Link a ReachBell subscriber to your own internal user ID. After identifying, you can target by externalId instead of having to track the subscriber token yourself.

curl -X POST https://api.reachbell.com/subscribers/identify \
  -H "x-api-key: rb_live_yourkey" \
  -H "Content-Type: application/json" \
  -d '{
    "token":      "tok_01HX3...",
    "externalId": "user_42"
  }'

Success:

{
  "id":         "sub_01HX3...",
  "token":      "tok_01HX3...",
  "externalId": "user_42",
  "updatedAt":  "2026-06-12T09:14:00.000Z"
}

Call identify as soon as the user signs in on your site. Without an externalId you can only address the subscriber by their opaque token, and you lose the link if they switch devices.

Tag a subscriber

POST /subscribers/tag

Tags are free-form labels you attach to a subscriber. Segments use them as filters. Common patterns: lifecycle stage (trial, paid), product interest (shoes, bags), or behavior (abandoned-cart).

curl -X POST https://api.reachbell.com/subscribers/tag \
  -H "x-api-key: rb_live_yourkey" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "tok_01HX3...",
    "tags":  ["premium", "newsletter"]
  }'

Success:

{
  "id":   "sub_01HX3...",
  "tags": ["premium", "newsletter"]
}

Tags are additive — calling tag again appends. To remove a tag, call POST /subscribers/untag with the same body shape.

List subscribers for a project

GET /subscribers/project/:projectId

Returns a paginated list of subscribers. Supports filters via query string.

curl "https://api.reachbell.com/subscribers/project/proj_01HX2...?page=1&pageSize=50&platform=desktop&country=US" \
  -H "x-api-key: rb_live_yourkey"

Common filters: platform, country, browser, os, tag, status, createdAfter, createdBefore.

Success:

{
  "data": [
    {
      "id":         "sub_01HX3...",
      "token":      "tok_01HX3...",
      "externalId": "user_42",
      "platform":   "desktop",
      "country":    "US",
      "city":       "San Francisco",
      "tags":       ["premium"],
      "status":     "active",
      "createdAt":  "2026-05-21T12:00:00.000Z"
    }
  ],
  "page":     1,
  "pageSize": 50,
  "total":    14823
}

Errors:

{
  "statusCode": 404,
  "message":    "Project not found",
  "requestId":  "req_01HX4..."
}

Subscriber analytics

GET /subscribers/analytics/project/:projectId

Returns a breakdown of your subscriber base by country, platform, browser, OS, device, and city. The dashboard's audience charts are powered by this endpoint.

curl https://api.reachbell.com/subscribers/analytics/project/proj_01HX2... \
  -H "x-api-key: rb_live_yourkey"

Success:

{
  "country":  [{ "key": "US", "count": 8412 }, { "key": "DE", "count": 1903 }],
  "platform": [{ "key": "desktop", "count": 9100 }, { "key": "mobile", "count": 5723 }],
  "browser":  [{ "key": "Chrome", "count": 11402 }, { "key": "Safari", "count": 2412 }],
  "os":       [{ "key": "macOS", "count": 4982 }, { "key": "Windows", "count": 4118 }],
  "device":   [{ "key": "iPhone", "count": 3812 }, { "key": "Pixel", "count": 1241 }],
  "city":     [{ "key": "San Francisco", "count": 1203 }, { "key": "Berlin", "count": 892 }]
}

Analytics are computed live from the subscribers table — there's no aggregation delay, but on very large projects (>500k subscribers) the request can take a second or two. Cache the response if you're rendering it on a public page.

What's next?