Billing and limits
Plans, monthly API requests, retention, what happens without an active subscription, and every API limit.
Plans
You pay for API requests from the SDKs, not for notifications sent. Every plan starts with a 3-day free trial: you add a payment method at checkout and nothing is charged during the trial. Each organization gets one trial; an organization that already had a subscription checks out without one.
| Starter | Growth | Scale | |
|---|---|---|---|
| Monthly price | $12 | $29 | $99 |
| Yearly price | $120 ($10/mo) | $288 ($24/mo) | $984 ($82/mo) |
| API requests per month | 500,000 | 5,000,000 | 30,000,000 |
| Typical users | ≈ 1,250 | ≈ 12,500 | ≈ 75,000 |
| Projects | 1 | 5 | Unlimited |
| Retention | 30 days | 90 days | 365 days |
| Highlights | Web and mobile SDKs; broadcasts and user targeting | Realtime updates; tags and segments; localization and templates; scheduled notifications | Everything in Growth; priority support |
Yearly billing saves about two months per year.
Plan features
Starter sends to everyone and to specific users, in one language and right away. The rest needs the Growth plan and up (custom plans include everything):
| Feature | What Starter can't send |
|---|---|
| Tags and segments | a tags or segment audience; creating or updating a segment |
| Localization | contents in more than one locale |
| Templates | {{ … }} in a title, body or action label |
| Scheduling | a publishAt more than a minute ahead |
| Realtime | a connection to GET /v1/client/realtime |
The API answers these with 403 forbidden, and the dashboard shows them locked. Drafts,
expiry and segment previews work on every plan. After a downgrade, notifications you
already saved keep their audience, languages and schedule: only the fields you change are
checked, so you can still edit the rest or cancel them.
API requests
Plans limit the client API requests the SDKs make per calendar month (UTC), counted across all projects of your organization:
- feed polls (
GET /v1/client/feed), including304 Not Modifiedreplies; - realtime connections (
GET /v1/client/realtime), one per connection; their messages don't count, the feed requests they trigger do; - actions (
POST /v1/client/actions): read, unread, archive, unarchive, click, read all, seen all; - profile syncs (
POST /v1/client/profile), sent only when the SDK'suserprofile changed.
Server API calls with a secret key don't count, and neither do CORS preflights or
rejected requests: unknown publishable keys, invalid or expired user tokens, origins the
project doesn't allow, 402 without an active subscription, and feed polls answered with
429 over the limit.
A typical user makes about 400 requests a month, which is how the "typical users" row
above is estimated. The estimate assumes polling every minute (poll(60_000)),
backing off to every 5 minutes while nothing changes; tabs share one poller and hidden apps
don't poll. A longer interval lowers usage proportionally, and without polling the SDKs
only fetch when users open or return to your app.
Realtime usually costs less than polling: opening the connection counts as one request, its messages and pings don't, and each change it reports costs one feed request. Reconnects count again, and a broadcast makes every connected user refetch, not only its recipients (see Request usage). Realtime is included in the Growth and Scale plans and in custom plans.
The dashboard shows the current month's requests against your plan on the project overview and Billing pages. Every request is counted exactly, and the dashboard shows the count within about 10 seconds.
Over the limit
Nothing breaks. Actions and profile syncs keep working, and each user's feed refreshes every
10 minutes instead of on every poll until the month resets (or within minutes of an
upgrade or a request pack purchase). Other feed polls get 429 rate_limited with a Retry-After header, the
number of seconds until that user's next refresh (RFC 9110 delay-seconds, exposed to
browsers with Access-Control-Expose-Headers). The SDKs keep showing the notifications
they have and retry after that delay. New realtime connections are refused meanwhile, and
the SDKs try again every 10 minutes.
Request packs
Owners and admins can buy a pack of your plan from the Billing page, through a one-time Stripe checkout: the plan's monthly requests for the plan's monthly price. Custom plans can have their own pack. Packs are never bought automatically.
| Plan | Pack |
|---|---|
| Starter | 500,000 requests for $12 |
| Growth | 5,000,000 requests for $29 |
| Scale | 30,000,000 requests for $99 |
- Availability. You can buy packs while your organization has an active plan, including during the trial.
- Credit. Requests come out of your plan first, then credit, then this month's packs. Whatever is left of your packs at the end of the month carries over to the next months as credit.
- Over the limit. When your plan, credit and packs run out, feeds refresh every 10 minutes as above until the month resets, you buy a pack or you upgrade.
Monthly active users
The dashboard also shows monthly active users (project users whose SDK made a request during the calendar month, across all projects) for reference. Plans don't limit them.
Retention
Feeds show notifications published within your plan's retention window: 30, 90 or 365 days, or the window of your custom plan. Older notifications disappear from feeds (and from unread counts) but stay in your history until they are 365 days old, or as old as your custom plan's window if that is longer, when a daily job deletes them. Upgrading extends the window within a few minutes, for notifications that still exist. Without an active, trialing or past-due subscription, feeds use the smallest plan's window (30 days).
Stripe
Billing runs on Stripe Managed Payments. Link, Stripe's checkout and wallet, is the merchant of record: purchases show as "Sold through Link", and Link handles sales tax, VAT and GST, fraud prevention, disputes and support for your transactions. Subscriptions are per organization.
- Prices. List prices are in USD; checkout shows them in your local currency where available and adds tax. You can pay with cards, Apple Pay, Google Pay, Link and, depending on your country, local payment methods.
- Managing your subscription. Owners and admins start, switch and cancel plans from the dashboard's Billing page. Payment & invoices opens the Stripe customer portal for payment methods, billing address and invoices. You can also manage all of this on link.com. Custom plans are changed through support.
- Canceling takes effect at the end of the current billing period (or trial); until then you keep your plan and can resume it.
- Plan changes apply immediately, and the prorated difference goes on your next invoice. Switching between monthly and annual billing starts a new billing period and is charged right away.
- Receipts and refunds. Link emails your receipts and invoices (PDFs attached) and
refund notices. Charges show on your card statement as
LINK.COM* NOTIFICATIONSTREAM. For refunds, contact Link support or us.
Without an active subscription
Access depends on the subscription status: trialing, active and past_due (while a
failed payment is being retried) have full access. In any other state (no subscription,
canceled, unpaid, paused):
- Server write endpoints (
POST,PUT,PATCH,DELETEwith a secret key) return402 payment_required. Segment previews still work. - Server read endpoints (
GET) keep working, so you can still export your data. - Client endpoints used by the SDKs return
402 payment_required, with no grace period beyond the payment retries. The SDKs show an empty feed and stop polling (and close realtime connections), so your app keeps working but your users see no notifications. - Feeds read through the server API fall back to the smallest plan's retention (30 days).
A new or renewed subscription unlocks the API within about 30 seconds of Stripe confirming it.
{
"error": {
"code": "payment_required",
"message": "This organization has no active subscription. Start or renew one at https://notificationstream.com."
}
}API limits
Requests
Server endpoints have no request quotas. Client endpoints count towards the
monthly API requests of your plan; over the limit, feed polls return
429 rate_limited. Treat 429 like a temporary failure: keep what you have and retry
after the Retry-After header (seconds, or an HTTP date). The official SDKs already do.
{
"error": {
"code": "rate_limited",
"message": "This project reached its monthly request limit, so feeds refresh every 10 minutes. Keep showing the feed you have and retry after `Retry-After` seconds."
}
}Notifications
| Field | Limit |
|---|---|
contents | 1 to 50 locales |
title | 1 to 200 characters |
body | up to 2,000 characters |
actionLabel | up to 60 characters |
| Locale keys | BCP 47, 2 to 35 characters |
audience.userIds | 1 to 1,000 user ids |
audience.tags | 1 to 20 tags |
category | 1 to 64 characters |
actionUrl, imageUrl | up to 2,048 characters, http(s) or a path starting with / |
data | any JSON object, up to 8 KB serialized |
idempotencyKey / Idempotency-Key | 1 to 255 characters |
Project users
| Field | Limit |
|---|---|
userId | 1 to 255 characters |
email | valid email, up to 320 characters |
name | up to 200 characters |
avatarUrl | like actionUrl |
timezone | up to 64 characters |
attributes | up to 100 keys; keys 1 to 64 characters |
| Attribute values | string (up to 1,024 characters), number, boolean, null or a list of up to 100 strings (each up to 256) |
tags | up to 100 per project user; each 1 to 64 characters of letters, digits, _, -, :, . |
Segments
| Field | Limit |
|---|---|
| Conditions | up to 50 in total |
| Nesting | 3 levels of groups |
name | 1 to 100 characters |
description | up to 500 characters |
Feeds and lists
| Limit | |
|---|---|
Feed page size (limit) | 1 to 50, default 20 |
| Notification and project user list page size | 1 to 100, default 50 |
Client action ids | up to 100 per request |
| Broadcast candidates per feed | the newest 500 broadcasts of the project |
| Direct notifications per feed | all within the retention window |
Feed counts (unreadCount, unseenCount) | cover the newest 100 notifications, so at most 100 |
User token lifetime (exp) | at most 7 days ahead |
| Signing keys per project | 2 |
Project settings
| Setting | Limit |
|---|---|
| Allowed origins | up to 50 |
| Theme colors | up to 64 characters each; radius 0 to 32 |