Managing your audience
Your audience — who you can notify and where to reach them — is managed over the tenant-scoped REST API.
| Action | Endpoint |
|---|---|
| Identify / upsert a subscriber | PUT /v1/subscribers/:externalId |
| Delete a subscriber | DELETE /v1/subscribers/:externalId |
| Subscribe to a topic | PUT /v1/subscribers/:externalId/subscriptions/:topicKey |
| Unsubscribe | DELETE /v1/subscribers/:externalId/subscriptions/:topicKey |
| Create / update a topic | PUT /v1/topics/:key |
| Delete a topic | DELETE /v1/topics/:key |
:externalId is your user id — palumb never mints subscriber ids.
Identify a subscriber
Section titled “Identify a subscriber”PUT /v1/subscribers/:externalId creates or updates a subscriber. It’s
idempotent, so call it whenever your user’s contact details change:
curl -sS -X PUT http://localhost:3000/v1/subscribers/cust_1 \ -H "Authorization: Bearer $PALUMB_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "contacts": { "email": ["cust1@example.com"] }, "locale": "en", "attributes": { "plan": "pro" } }'Contact merge rules
Section titled “Contact merge rules”contacts is a per-kind map, and the upsert merges it kind by kind:
| You send | Result for that kind |
|---|---|
| A non-empty list | Overwrites the addresses |
An empty list [] | Clears the kind |
| Omit the kind | Survives unchanged |
So adding a phone number doesn’t disturb an existing email:
curl -sS -X PUT http://localhost:3000/v1/subscribers/cust_1 \ -H "Authorization: Bearer $PALUMB_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "contacts": { "sms": ["+391234567"] } }' # email kept; sms addedlocale and attributes follow the same “provided overwrites, omitted keeps”
rule. The contacts kinds line up with channel kinds —
delivery reads the address from contacts[kind].
Topics & subscriptions
Section titled “Topics & subscriptions”A topic groups subscribers so a single trigger can fan out to all of them. You can create one explicitly:
curl -sS -X PUT http://localhost:3000/v1/topics/oncall \ -H "Authorization: Bearer $PALUMB_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "name": "On-call engineers" }'…or just subscribe someone — the topic is created implicitly on first
subscribe if it doesn’t exist yet (an implicit create never clobbers a name you
set explicitly):
curl -sS -X PUT http://localhost:3000/v1/subscribers/cust_1/subscriptions/oncall \ -H "Authorization: Bearer $PALUMB_API_KEY"Re-subscribing is a no-op (the subscriber↔topic pair is unique). Unsubscribe with
the matching DELETE. A topic trigger
then expands the topic to its subscribers, deduplicated, and starts one run
each.
Lifecycle & cascade
Section titled “Lifecycle & cascade”-
Delete a subscriber — removes its subscriptions too (database-level cascade):
Terminal window curl -sS -X DELETE http://localhost:3000/v1/subscribers/cust_1 \-H "Authorization: Bearer $PALUMB_API_KEY" -
Delete a topic — guarded. If any subscriber is still on it, the delete is rejected with
409; unsubscribe everyone first. This keeps you from silently orphaning subscriptions.Terminal window curl -sS -X DELETE http://localhost:3000/v1/topics/oncall \-H "Authorization: Bearer $PALUMB_API_KEY"