API concepts

Base URL: https://api.litepush.dev. All endpoints accept and return JSON unless otherwise stated.

This section is a reference, not a tutorial. If you're integrating for the first time, start with Getting started instead. Each endpoint path has its own page in the sidebar — this page covers the shared concepts they all build on.

Glossary

Quick glossary so the field names across the endpoint pages make sense.

TermWhat it isWhere it comes from
ProjectA namespace that owns subscribers, broadcasts, groups, and keys. One project per site/app you push to.You create it in the dashboard.
Project IDPublic identifier — looks like prj_01HXM.... Safe to expose in browser code.Dashboard → Project overview.
API keySecret server-to-server token — looks like lpk_live_*. Shown once at project creation; we only store its SHA-256 hash.Dashboard → Project overview (or rotate via Settings).
VAPID public keyPublic half of the keypair used to sign push messages. Safe to embed in your <script> tag. Rotating the keypair (Settings → Rotate VAPID keys) invalidates every active subscription — subscribers must re-opt in with the new key.Generated automatically per project.
SubscriberOne browser that opted in to your project's pushes. Identified internally by sub_*.Created when the SDK calls POST /v1/subscribe.
Endpoint URLThe push gateway URL the browser handed back when the user opted in (FCM / Mozilla / Apple). Stable per browser install.PushSubscription.endpoint from the Web Push API.
p256dh / auth keysEncryption material from the browser's PushSubscription. Required to encrypt the push payload.PushSubscription.getKey('p256dh') / getKey('auth').
external_idYour own user ID, optionally attached to a subscriber. Lets you target one user across multiple devices.Your application.
BroadcastOne send operation — fan-out to all/group/user subscribers. Identified by bdc_*.Created by POST /v1/send or the dashboard's broadcast form.
GroupA named segment within a project. A subscriber can be in any number of groups. Identified by grp_*.Created via dashboard or POST /v1/groups.

Authentication

LitePush uses two auth styles depending on whether the caller is your server or a browser.

Server-to-server — Bearer token

Server endpoints (anything you call from your backend) require your API key in the Authorization header:

Authorization: Bearer lpk_live_xxxxxxxx

Endpoints requiring Bearer auth: GET /v1/me, POST /v1/send, all /v1/broadcasts* (read, list, cancel), all /v1/groups/*, all /v1/subscribers/*.

A missing, malformed, or revoked key returns 401 invalid_api_key.

Browser — Project query parameter

Three endpoints are called from a browser (the SDK and the service worker): /v1/subscribe, /v1/unsubscribe, /v1/events. These can't carry your secret API key — anyone would see it in DevTools — so they identify the project by its public ID instead:

?project=prj_xxxxxxxx

Or as a header (the SDK uses the header automatically):

X-LitePush-Project: prj_xxxxxxxx

http://localhost origins are not accepted by the API. If you're developing against the endpoint, tunnel your dev server through Cloudflare Tunnel or ngrok and register the tunnel's HTTPS hostname as your project's origin.

Project IDs are public by design — they ship in your client-side <script> tag and are visible in DevTools, like a publishable key, and that's fine: they're meant to be public. The only real secret is your API key (the lpk_live_… Bearer token) — keep that server-side, and rotate it from the dashboard if it ever leaks.

If you have a use case for server-side authoritative subscribe (seeding subscribers from your backend rather than from a real browser) — there isn't a Bearer-authed equivalent of /v1/subscribe today. Email support@litepush.dev and tell us your shape.

Quick reference

MethodPathAuthPurpose
POST/v1/subscribeProjectRegister a browser's push subscription
POST/v1/unsubscribeProjectSoft-unsubscribe a browser
POST/v1/eventsProjectService-worker click/dismiss beacon (SDK-internal)
GET/v1/meBearerVerify your API key, get project identity
POST/v1/sendBearerTrigger a broadcast (immediate, or scheduled via scheduled_at)
GET/v1/broadcastsBearerList the project's broadcasts (paginated)
GET/v1/broadcasts/:idBearerRead one broadcast — status + delivered/failed counts
DELETE/v1/broadcasts/:idBearerCancel a not-yet-fired scheduled broadcast
GET/v1/groupsBearerList groups in this project
POST/v1/groupsBearerCreate a group
PATCH/v1/groups/:idBearerRename a group or edit its description
DELETE/v1/groups/:idBearerDelete a group (memberships cascade, subscribers stay)
POST/v1/groups/:id/subscribersBearerAdd subscribers to a group
DELETE/v1/groups/:id/subscribers/:sidBearerRemove a subscriber from a group
DELETE/v1/subscribers/by-endpointBearerGDPR erasure by push endpoint URL
DELETE/v1/subscribers/by-external-id/:eidBearerGDPR erasure by external_id
GET/v1/subscribers/exportBearerGDPR portability — download CSV
GET/healthNoneService health probe

Error format

Every error response uses the same envelope so your code can branch on error.code:

{
  "error": {
    "code": "monthly_push_limit_reached",
    "message": "Project would exceed the hobby plan cap of 200,000 pushes/month. This broadcast would add ~5,000."
  }
}
  • code is a stable machine-parsable identifier. Treat it as your contract.
  • message is human-readable and may change between releases. Show it in dashboards / debug pages, but don't string-match it in code.

Rate limits

Each project is capped at 600 requests/minute across all /v1/* endpoints.

On overage you get:

HTTP/1.1 429 Too Many Requests
Retry-After: 60

{ "error": { "code": "rate_limited", "message": "Project is over its per-minute API quota." } }

If you're consistently hitting this, you're almost certainly fan-outing from client-side code that should be batched into a server-side cron — email support@litepush.dev and we'll help architect a fix.

Status codes used

CodeMeaning
200OK
201Created (subscribe, group create)
202Accepted (send, events beacon) — work continues async
400Bad request — invalid body, missing required param
401Auth failure — missing / invalid Bearer token
403Plan-cap or permission failure (see error.code)
404Resource not found (project, group, etc.)
409Conflict (e.g. group name taken)
429Rate limited
5xxServer-side issue — please retry with exponential backoff