BNotify icon
bnotify.com Console FAQ Contact Open Console
Server · Backend API

Send notifications from your backend

Use this HTTP API when your own server should send a BNotify notification — for example after an order, a payment, or any event in your backend. The mobile SDK only registers the device and displays the message. Your server decides when to send.

Copy the URL and key from Console

Open BNotify Console → Settings. Use Webhooks as the request URL and API Key as apiToken in the JSON body. Do not hard-code another project’s key.

Method POST Body JSON Auth apiToken in body Target tokens array

When to use this API

You want to…Use
Compose and send from the BNotify dashboardConsole campaigns (no code)
Send from your server when something happens in your productThis Backend API
Register a phone and show the notificationAndroid, iOS, or Flutter SDK

Typical flow: the app SDK returns a device token → your app uploads that token to your server → your server POSTs this API with those tokens when it is time to notify.

Where to get the URL and API key

In the Console, open the project, then Settings.

Console fieldUse it as
WebhooksThe POST URL. Example shape: https://bnotify.convexinteractive.com/webhook. Always copy the value shown for your project.
API KeyThe apiToken field inside the JSON body. This identifies the project.
Keep the API key on the server

Call this endpoint only from your backend. Do not put the API key in a mobile app, a website frontend, or a public repository.

Endpoint

HTTP
POST {Webhooks URL from Console → Settings}
Content-Type: application/json

The current production webhook is usually:

URL
https://bnotify.convexinteractive.com/webhook

If Settings shows a different Webhooks value, use that value.

Request fields

Send one JSON object. apiToken and tokens are required for a targeted send. Include scheduledAt only when isScheduled is true.

FieldTypeRequiredDescription
apiTokenstringYesProject API Key from Console → Settings.
tokensstring[]YesDevice tokens that should receive this notification. One string per device.
titlestringYesNotification title.
messagestringYesNotification body.
typestringNoYour label for the message, for example promo.
screenstringNoScreen name the app should open on tap. The SDK exposes this on the click callback.
actionstringNoAction hint for the app, for example navigate.
imageUrlstringNoHTTPS image URL. iOS expanded images also need a Notification Service Extension.
deepLinkstringNoLink the app can open, for example convexinteractive.com.
isExpandedstringNo"true" or "false". Controls expanded notification content.
isScheduledbooleanYestrue to send later. false to send immediately.
scheduledAtstringOnly if scheduledFormat YYYY-MM-DD HH:mm:ss, for example 2026-09-22 18:00:00. Omit this field when isScheduled is false.

Send now vs schedule

Send immediately

Set isScheduled to false and do not send scheduledAt.

JSON
{
  "title": "Order shipped",
  "message": "Your order is on the way.",
  "type": "promo",
  "screen": "home",
  "action": "navigate",
  "imageUrl": "https://example.com/image.jpg",
  "apiToken": "YOUR_API_KEY",
  "isScheduled": false,
  "isExpanded": "false",
  "deepLink": "example.com",
  "tokens": [
    "DEVICE_TOKEN_1",
    "DEVICE_TOKEN_2"
  ]
}

Send at a specific time

Set isScheduled to true and include scheduledAt.

JSON
{
  "title": "Test Notification",
  "message": "This is a test notification to check system",
  "type": "promo",
  "screen": "home",
  "action": "navigate",
  "imageUrl": "https://example.com/image.jpg",
  "apiToken": "YOUR_API_KEY",
  "isScheduled": true,
  "isExpanded": "false",
  "deepLink": "example.com",
  "scheduledAt": "2026-09-22 18:00:00",
  "tokens": [
    "DEVICE_TOKEN_1"
  ]
}

Which devices receive it

tokens is the list of BNotify device tokens. The notification is sent only to those devices.

  • Android / iOS / Flutter SDKs expose the token after registration (onToken in Flutter, the native token callback on Android and iOS).
  • Store that token on your server, next to the user account.
  • When you notify one user, send that user’s token. When you notify many users, send every token in the same tokens array.

An empty tokens array does not identify a device. Always pass the tokens you collected from the SDK.

Examples

Replace YOUR_API_KEY with Settings → API Key, and replace device tokens with tokens from your database. The samples below send immediately (isScheduled: false, no scheduledAt).

cURL

bash
curl --location 'https://bnotify.convexinteractive.com/webhook' \
  --header 'Content-Type: application/json' \
  --data '{
    "title": "Test Notification",
    "message": "This is a test notification to check system",
    "type": "promo",
    "screen": "home",
    "action": "navigate",
    "imageUrl": "https://example.com/image.jpg",
    "apiToken": "YOUR_API_KEY",
    "isScheduled": false,
    "isExpanded": "false",
    "deepLink": "example.com",
    "tokens": [
      "DEVICE_TOKEN_1"
    ]
  }'

Node.js

JavaScript
const response = await fetch("https://bnotify.convexinteractive.com/webhook", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    title: "Test Notification",
    message: "This is a test notification to check system",
    type: "promo",
    screen: "home",
    action: "navigate",
    imageUrl: "https://example.com/image.jpg",
    apiToken: process.env.BNOTIFY_API_KEY,
    isScheduled: false,
    isExpanded: "false",
    deepLink: "example.com",
    tokens: ["DEVICE_TOKEN_1"],
  }),
});

if (!response.ok) {
  throw new Error(`BNotify webhook failed: ${response.status}`);
}

Python

Python
import os
import requests

payload = {
    "title": "Test Notification",
    "message": "This is a test notification to check system",
    "type": "promo",
    "screen": "home",
    "action": "navigate",
    "imageUrl": "https://example.com/image.jpg",
    "apiToken": os.environ["BNOTIFY_API_KEY"],
    "isScheduled": False,
    "isExpanded": "false",
    "deepLink": "example.com",
    "tokens": ["DEVICE_TOKEN_1"],
}

response = requests.post(
    "https://bnotify.convexinteractive.com/webhook",
    json=payload,
    timeout=30,
)
response.raise_for_status()

PHP

PHP
$payload = [
    "title" => "Test Notification",
    "message" => "This is a test notification to check system",
    "type" => "promo",
    "screen" => "home",
    "action" => "navigate",
    "imageUrl" => "https://example.com/image.jpg",
    "apiToken" => getenv("BNOTIFY_API_KEY"),
    "isScheduled" => false,
    "isExpanded" => "false",
    "deepLink" => "example.com",
    "tokens" => ["DEVICE_TOKEN_1"],
];

$ch = curl_init("https://bnotify.convexinteractive.com/webhook");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS => json_encode($payload),
    CURLOPT_RETURNTRANSFER => true,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status < 200 || $status >= 300) {
    throw new RuntimeException("BNotify webhook failed: " . $status);
}

Integration checklist

  • 1Create the project and register the mobile app in the Console
  • 2Integrate the Android, iOS, or Flutter SDK so devices produce a token
  • 3Save each device token on your server
  • 4Copy Webhooks and API Key from Console → Settings
  • 5POST JSON from your backend with apiToken and tokens
  • 6For an immediate send, set isScheduled to false and omit scheduledAt
  • 7For a later send, set isScheduled to true and set scheduledAt to YYYY-MM-DD HH:mm:ss
  • 8Confirm the notification on a physical device that owns one of the tokens

Security

  • Store the API key in a server secret (environment variable or secret manager), not in source control.
  • Call the webhook only from your backend.
  • Send tokens only for the users who should see that message.
  • If an API key is exposed, generate a new one in the Console and update your server.
Tap routing

Set screen to the same route name your app reads from the SDK click callback (onClick / notification extras). The API delivers the payload; the app decides which screen to open.