Concepts
- App — a registered application with its own APNs
.p8credentials and API keys. Push apps are provisioned by Grantiva — contact support to register one — and are read back over the org API rather than the dashboard, which has no push screen today. APNs credentials are stored AES-256-GCM encrypted and can be added or rotated after registration. - Channel — an opaque string your app chooses (
order:42:status,chat:<uuid>,broadcast). Grantiva assigns no meaning to channels; they’re created implicitly on first subscribe and matched exactly (no wildcards in v1). Max 255 printable characters. - Subscription — a device token subscribed to a channel. Three token types:
alert(standard push),liveactivity-start(push-to-start, rotates), andliveactivity-update(per-activity, requiresactivityID). - Event — a publish: an event name plus a push spec, fanned out to all subscribed tokens of the relevant type. A token subscribed to several published channels receives one push.
API keys
Each push app has two keys, issued once at creation (stored hashed — save them):
Keys are matched by SHA-256 hash and never stored or compared in plaintext. Subscription endpoints are rate-limited to 240 requests/min per key; exceeding it returns
429 with a Retry-After header.
Typical flow
- Device registers — your app obtains its APNs token and calls
POST /v1/apps/:appID/subscriptionswith the public key, a channel, and the token. - Backend publishes — when something happens, your server calls
POST /v1/apps/:appID/publishwith the secret key, the channel(s), and an alert or Live Activity spec. - Grantiva fans out — every subscribed device receives the push. Dead tokens (APNs
410 Unregistered/400 BadDeviceToken) are pruned automatically.
Live Activities
The publish API speaks Live Activities natively:start events route to push-to-start tokens, update/end to per-activity update tokens (optionally filtered by activityID). Grantiva sets the correct apns-push-type, topic (<bundleID>.push-type.liveactivity), and payload envelope (timestamp, event, content-state, attributes-type) for you.
Push-to-start tokens rotate — pass previousToken when re-subscribing and Grantiva cleans up the stale registrations.
Feedback push integration
The in-app feedback feature rides this service: pass optionalpushToken and pushEnvironment fields when filing a feature request or comment (POST /api/v1/feedback/features, POST /api/v1/feedback/features/:id/comments) and the device is auto-subscribed to that thread’s channel (feedback:feature:<id>). When an org admin replies from the dashboard, every subscribed device gets an alert push (event: feedback:admin-reply).
Link which push app delivers feedback pushes with PUT /api/v1/org/feedback-push-app (admin session, body { "pushAppID": "<uuid>" | null }). While unlinked, feedback push is a silent no-op and email notifications still fire.
The iOS SDK does not yet expose a push-token API for feedback calls — pass the fields at the REST level for now.
Org dashboard
GET /api/v1/org/push-apps— your org’s push apps with APNs status, subscription/channel counts, and key prefixes (never raw keys)GET /api/v1/org/push-apps/:appID— one app
API reference
- Subscriptions — device-facing subscribe/list/unsubscribe
- Publish — backend-facing event fan-out