REST API
Base URL: https://nesh.kkweb.io/api/v1/projects/<projectId>
Subscribe
Called by the SDK after the browser issues a push subscription. CORS-enabled, no auth.
POST /api/v1/projects/<projectId>
Content-Type: application/json
{
"endpoint": "https://fcm.googleapis.com/...",
"keys": { "p256dh": "...", "auth": "..." },
"userId": "alice" // optional
}
→ 201 { "ok": true }Rate limited 60 / minute per IP × project × action. The endpoint also enforces the free-tier subscriber cap on new endpoints (existing endpoints can always update).
Unsubscribe
DELETE /api/v1/projects/<projectId>?endpoint=<urlencoded-endpoint>
→ 200 { "ok": true }Send notification
Server-to-server. Use the Bearer token from the project's API key card (format nesh_sk_…). Synchronous — the response includes delivery counts.
POST /api/v1/projects/<projectId>/notifications
Authorization: Bearer nesh_sk_…
Content-Type: application/json
{
"title": "Hello",
"body": "From the API",
"url": "https://example.com",
"icon": "https://example.com/icon-192.png",
"image": "https://example.com/hero.jpg",
"badge": "https://example.com/badge-72.png",
"userIds": ["alice", "bob"] // optional — omit to broadcast
}
→ 201 {
"id": "uuid",
"attempted": 12,
"delivered": 11,
"removed": 1,
"failed": 0
}Subject to the monthly send cap (10,000 / project / UTC month on the free tier). Returns 429 when reached.
Track event (SDK / SW)
Service Workers POST shown / clicked beacons here automatically when the SDK is v0.6+. You shouldn't normally call this from your code.
POST /api/v1/projects/<projectId>/notifications/<notificationId>/events
Content-Type: application/json
{ "type": "shown" } // or "clicked"
→ 200 { "ok": true }