Skip to content

Push Notifications API ​

Complete reference for the push notification endpoints. Push is delivered via Firebase Cloud Messaging (FCM) to Android, iOS, and web devices.

Authentication ​

All push endpoints require an API key with the SEND_PUSH scope in the X-API-Key header.


Connect Firebase Project ​

Save your Firebase service account credentials. MsGine uses these to send push notifications through your own FCM sender ID. If you skip this step, the shared MsGine sender is used.

Endpoint ​

PUT https://api.msgine.net/api/v1/developers/push/config

Request ​

bash
curl -X PUT https://api.msgine.net/api/v1/developers/push/config \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": "your-firebase-project-id",
    "clientEmail": "firebase-adminsdk@your-project.iam.gserviceaccount.com",
    "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----\n"
  }'

Parameters ​

ParameterTypeRequiredDescription
projectIdstringYesFirebase project ID
clientEmailstringYesService account email
privateKeystringYesService account private key (full PEM block)

How to get these values: Firebase Console → Project Settings → Service accounts → Generate new private key. Copy project_id, client_email, and private_key from the downloaded JSON.

Response ​

json
{
  "projectId": "your-firebase-project-id",
  "clientEmail": "firebase-adminsdk@your-project.iam.gserviceaccount.com",
  "isActive": true,
  "createdAt": "2026-05-28T10:00:00.000Z",
  "updatedAt": "2026-05-28T10:00:00.000Z"
}

Credentials are validated on save. An invalid private key returns 400 Bad Request.


Get Firebase Config ​

GET https://api.msgine.net/api/v1/developers/push/config

Returns the currently connected Firebase project. The private key is never returned.

json
{
  "projectId": "your-firebase-project-id",
  "clientEmail": "firebase-adminsdk@your-project.iam.gserviceaccount.com",
  "isActive": true,
  "createdAt": "2026-05-28T10:00:00.000Z",
  "updatedAt": "2026-05-28T10:00:00.000Z"
}

Returns null if no config is set.


Remove Firebase Config ​

DELETE https://api.msgine.net/api/v1/developers/push/config

Removes your Firebase credentials. Pushes fall back to the shared MsGine sender.


Register Device Token ​

Register an FCM device token for a user. Call this on every app launch — tokens can rotate.

Endpoint ​

POST https://api.msgine.net/api/v1/developers/push/device

Request ​

bash
curl -X POST https://api.msgine.net/api/v1/developers/push/device \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "fcm-token-from-firebase-sdk",
    "platform": "android",
    "externalUserId": "user_abc123"
  }'

Parameters ​

ParameterTypeRequiredDescription
tokenstringYesFCM registration token from Firebase SDK
platform"android" | "ios" | "web"YesDevice platform
externalUserIdstringNoYour own user identifier. Used when sending with externalUserIds.

Response ​

json
{
  "id": "uuid-...",
  "platform": "android",
  "isActive": true,
  "createdAt": "2026-05-28T10:00:00.000Z"
}

If the same token is re-registered (e.g. a different user logs in on the same device), it is reassigned automatically.


Remove Device Token ​

Deactivate a device token — call this on logout.

DELETE https://api.msgine.net/api/v1/developers/push/device
bash
curl -X DELETE https://api.msgine.net/api/v1/developers/push/device \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "token": "fcm-token-to-remove" }'

Send Push Notification ​

Endpoint ​

POST https://api.msgine.net/api/v1/developers/push

Targeting ​

GoalField to use
Send to specific users (by your own IDs)externalUserIds
Send to specific users (by MsGine UUIDs)userIds
Send to all devices on a topictopic
Broadcast to all registered devices(leave targeting fields empty)

Basic request ​

bash
curl -X POST https://api.msgine.net/api/v1/developers/push \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Your order shipped",
    "body": "Estimated arrival: tomorrow.",
    "externalUserIds": ["user_abc123", "user_def456"],
    "data": { "screen": "orders", "orderId": "ORD-999" }
  }'

Full request with all options ​

json
{
  "title": "Flash Sale",
  "body": "50% off everything — today only!",
  "type": "notification",
  "priority": "high",
  "ttl": 86400,
  "imageUrl": "https://cdn.example.com/banner.jpg",
  "collapseKey": "flash-sale",
  "topic": "promotions",
  "externalUserIds": ["user_1", "user_2"],
  "data": {
    "screen": "shop",
    "promo": "FLASH50"
  },
  "android": {
    "channelId": "promotions",
    "sound": "default",
    "color": "#4F46E5",
    "clickAction": "OPEN_PROMO"
  },
  "apns": {
    "badge": 1,
    "sound": "default",
    "category": "PROMO"
  },
  "webpush": {
    "icon": "https://cdn.example.com/icon.png",
    "link": "https://app.example.com/shop",
    "requireInteraction": true
  },
  "scheduledFor": "2026-06-01T09:00:00.000Z",
  "idempotencyKey": "campaign_june_push_001"
}

Parameters ​

ParameterTypeRequiredDescription
titlestringYesNotification title (max 100 chars)
bodystringYesNotification body (max 500 chars)
type"notification" | "data" | "both"Nonotification = visible banner. data = silent background payload. Default: notification
priority"high" | "normal"Nohigh wakes the device immediately. Default: high
ttlnumberNoMessage TTL in seconds (max 2419200 = 28 days). If device is offline past TTL, message is discarded.
imageUrlstringNoImage URL shown in the notification body
collapseKeystringNoReplaces pending undelivered notifications with the same key on the device
dataRecord<string, string>NoSilent key-value payload delivered to the app
topicstringNoFCM topic (broadcast to all subscribed devices)
externalUserIdsstring[]NoYour own user identifiers
userIdsstring[]NoMsGine user UUIDs
scheduledForstring (ISO 8601)NoSchedule a future send
idempotencyKeystringNoPrevents duplicate sends (max 64 chars)
androidAndroidConfigNoAndroid-specific overrides
apnsApnsConfigNoiOS-specific overrides
webpushWebPushConfigNoWeb Push overrides

AndroidConfig ​

FieldTypeDescription
channelIdstringNotification channel (required for Android 8.0+)
soundstringSound file name
clickActionstringIntent action when notification is tapped
colorstringAccent color in #RRGGBB
iconstringDrawable resource name
priority"min" | "low" | "default" | "high" | "max"Notification display priority

ApnsConfig ​

FieldTypeDescription
badgenumberApp icon badge count (0 = clear)
soundstringSound file name or "default"
contentAvailablebooleanSilent background notification
mutableContentbooleanAllow notification service extension to modify before display
categorystringAction category identifier
threadIdstringThread ID for grouping notifications

WebPushConfig ​

FieldTypeDescription
iconstringNotification icon URL
linkstringURL to open on click
badgestringBadge image URL
requireInteractionbooleanKeep notification visible until dismissed

Response ​

json
{
  "id": "uuid-...",
  "channel": "push",
  "title": "Your order shipped",
  "body": "Estimated arrival: tomorrow.",
  "status": "pending",
  "sandbox": false,
  "recipientCount": 2,
  "scheduledAt": null,
  "createdAt": "2026-05-28T10:00:00.000Z"
}

Status values ​

StatusMeaning
pendingQueued for delivery
sentAll recipients delivered successfully
partialSome recipients delivered, some failed
failedAll recipients failed

Confirm Delivery or Open ​

Report when a notification is received or tapped. Updates deliveredAt, openedAt, and deliveryConfirmedCount on the notification record.

Endpoint ​

POST https://api.msgine.net/api/v1/developers/push/delivery
bash
curl -X POST https://api.msgine.net/api/v1/developers/push/delivery \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "notificationId": "uuid-from-send-response",
    "event": "delivered"
  }'

Parameters ​

ParameterTypeRequiredDescription
notificationIdstringYesUUID returned by the send endpoint
event"delivered" | "opened"Yesdelivered = device received it. opened = user tapped it.

Get Push History ​

GET https://api.msgine.net/api/v1/developers/push/history?page=1&limit=20

Response ​

json
{
  "notifications": [
    {
      "id": "uuid-...",
      "channel": "push",
      "title": "Your order shipped",
      "body": "Estimated arrival: tomorrow.",
      "recipientCount": 2,
      "successCount": 2,
      "failureCount": 0,
      "deliveryConfirmedCount": 1,
      "status": "sent",
      "sentAt": "2026-05-28T10:00:05.000Z",
      "deliveredAt": "2026-05-28T10:00:06.000Z",
      "openedAt": null,
      "createdAt": "2026-05-28T10:00:00.000Z"
    }
  ],
  "total": 47,
  "page": 1,
  "pages": 3
}

Sandbox mode ​

API keys with environment: "sandbox" skip actual FCM delivery. The notification is saved with status: "sent" and sandbox: true immediately. Use this for testing without sending real notifications.


Webhook events ​

Configure webhooks at PUT /developers/webhooks to receive push delivery events on your server:

EventWhen
push.sentAll recipients delivered
push.partialSome delivered, some failed
push.failedAll failed

Event payload:

json
{
  "eventType": "push.sent",
  "channel": "push",
  "messageId": "uuid-...",
  "data": {
    "title": "Your order shipped",
    "body": "Estimated arrival: tomorrow.",
    "successCount": 2,
    "failureCount": 0,
    "recipientCount": 2
  }
}

Error responses ​

CodeReason
400No active devices found, FCM not configured, or invalid credentials
401Missing or invalid API key
403API key lacks SEND_PUSH scope
404Notification not found (delivery confirm)
429Rate limit exceeded

Released under the MIT License.