# NotifyBD API — reminders, alerts and monitors over HTTP and MCP

NotifyBD REST API (/api/v1, JSON, API-key auth) and MCP server for AI assistants: create reminders that repeat until answered, send notifications by app push, SMS, WhatsApp or email, watch websites and servers, and (for resellers) manage users and broadcast.

- Base URL: `https://app.notify.bd/api/v1` — JSON in/out, every reply has `ok`.
- Auth: header `X-API-Key: nbd_…` (or `Authorization: Bearer nbd_…`). Get a key: https://app.notify.bd/developer
- Dates `yyyy-MM-dd`, times `HH:mm` in the account's time zone (default Asia/Dhaka); reply timestamps are UTC.
- Money: BDT. SMS/WhatsApp charged per message from the balance; app + email free. Plan limits: `GET /me`, https://notify.bd/#pricing
- Machine-readable: https://notify.bd/api/openapi.json (OpenAPI 3.1), https://notify.bd/llms.txt

## Account

### GET /api/v1/me

**Your account, balance and plan.** Who the key belongs to, the balance in taka, the account's time zone and current local time, and the plan's limits (including notifications per month and how many are used this month; null = unlimited).

```bash
curl https://app.notify.bd/api/v1/me \
  -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "name": "Rahim Uddin",
  "username": "rahim@example.com",
  "role": "user",
  "now": "2026-09-28T10:15",
  "balance": 120.0,
  "currency": "BDT",
  "timeZone": "Asia/Dhaka",
  "plan": {
    "name": "Pro",
    "expiresAt": "2026-10-28T00:00:00Z",
    "expired": false,
    "maxReminders": 300,
    "maxMonitors": 20,
    "notificationsPerMonth": 600,
    "notificationsUsedThisMonth": 42,
    "sms": true,
    "whatsapp": true,
    "email": true,
    "smsRate": 0.35,
    "whatsappRate": 0.8
  }
}
```

## Reminders

A reminder fires at its time and, with requireAck, keeps asking every repeatEveryMin minutes (up to maxRepeats more times) until the person answers Yes. Times are in the account's time zone (default Asia/Dhaka). Phases send advance alerts (e.g. 15, 7 and 1 day before a domain or bill expiry). alarm makes the NotifyBD Android app ring and vibrate like an alarm clock.

### POST /api/v1/reminders

**Create a reminder.**

JSON body:

- `title` (string, required) — What to remind about (max 120 characters).
- `message` (string) — Extra text (max 500).
- `repeat` (string) — once (default), daily, weekly, monthly or yearly.
- `date` (string) — yyyy-MM-dd. First/only date; default today. Monthly uses its day of month, yearly its day and month.
- `time` (string) — HH:mm, 24-hour, account time zone. Required unless inMinutes is given.
- `inMinutes` (integer) — Instead of date/time: fire this many minutes from now (1–525600), rounded up to the next whole minute.
- `days` (integer[]) — Weekly only: days of the week, 0 = Sunday … 6 = Saturday.
- `phases` (integer[]) — Days before the date to alert, e.g. [15,7,1,0]. Default [0] = on the day. For once, monthly and yearly.
- `methods` (string[]) — Array of "app", "sms", "whatsapp", "email". Default ["app"]. sms/whatsapp need a paid plan and are charged per message from the balance; app and email are free (email: user accounts only).
- `requireAck` (boolean) — Keep asking until answered Yes (default true).
- `repeatEveryMin` (integer) — Minutes between asks while waiting (default 10). Snooze waits the same time.
- `maxRepeats` (integer) — How many more times to ask (0–20, default 3). After that the reminder is marked No answer.
- `alarm` (boolean) — Ring and vibrate like an alarm clock in the Android app, with a full-screen alarm page (default false).
- `color` (string) — One of orange, navy, blue, green, purple, pink, teal, amber (default orange).
- `icon` (string) — One of bell, alarm, calendar-event, globe, server, capsule, cup-hot, dribbble, book, cash-coin, briefcase, house, heart-pulse, car-front, airplane, gift (default alarm).

```bash
curl -X POST https://app.notify.bd/api/v1/reminders \
  -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"title":"example.com renewal","repeat":"yearly","date":"2026-12-01","time":"10:00","phases":[15,7,1,0],"methods":["app","sms"]}'
```

Response 201:

```json
{
  "ok": true,
  "data": {
    "id": "3f1c…",
    "title": "example.com renewal",
    "repeat": "yearly",
    "date": "2026-12-01",
    "time": "10:00",
    "phases": [
      15,
      7,
      1,
      0
    ],
    "methods": [
      "app",
      "sms"
    ],
    "requireAck": true,
    "alarm": false,
    "repeatEveryMin": 10,
    "maxRepeats": 3,
    "active": true,
    "nextRunAt": "2026-11-16T04:00:00Z"
  }
}
```

### GET /api/v1/reminders

**List reminders.** All your reminders, sorted by title.

```bash
curl https://app.notify.bd/api/v1/reminders -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": [
    {
      "id": "3f1c…",
      "title": "Go to play",
      "repeat": "daily",
      "time": "17:00",
      "active": true
    }
  ]
}
```

### GET /api/v1/reminders/{id}

**Get one reminder.**

Path parameters:

- `id` (uuid, required) — Reminder id.

```bash
curl https://app.notify.bd/api/v1/reminders/REMINDER_ID -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": {
    "id": "3f1c…",
    "title": "Go to play",
    "active": true
  }
}
```

### POST /api/v1/reminders/{id}/pause

**Pause a reminder.** Stops it from firing. Use /resume to turn it back on.

Path parameters:

- `id` (uuid, required) — Reminder id.

```bash
curl -X POST https://app.notify.bd/api/v1/reminders/REMINDER_ID/pause -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": {
    "id": "3f1c…",
    "active": false
  }
}
```

### POST /api/v1/reminders/{id}/resume

**Resume a reminder.**

Path parameters:

- `id` (uuid, required) — Reminder id.

```bash
curl -X POST https://app.notify.bd/api/v1/reminders/REMINDER_ID/resume -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": {
    "id": "3f1c…",
    "active": true
  }
}
```

### DELETE /api/v1/reminders/{id}

**Delete a reminder.** Deletes the reminder and its history. Cannot be undone.

Path parameters:

- `id` (uuid, required) — Reminder id.

```bash
curl -X DELETE https://app.notify.bd/api/v1/reminders/REMINDER_ID -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true
}
```

### POST /api/v1/answer/{occurrenceId}

**Answer a waiting reminder.** yes = done (stops asking); snooze and notyet both ask again after the reminder's repeatEveryMin. The occurrenceId comes from GET /notifications (items with waitingForAnswer = true).

Path parameters:

- `occurrenceId` (uuid, required) — occurrenceId from GET /notifications.

JSON body:

- `answer` (string, required) — yes, snooze or notyet.

```bash
curl -X POST https://app.notify.bd/api/v1/answer/OCCURRENCE_ID \
  -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" -d '{"answer":"yes"}'
```

Response 200:

```json
{
  "ok": true,
  "message": "Great! “Go to play” is done."
}
```

## Notifications

### POST /api/v1/notify

**Notify yourself now.** Sends a notification to your own devices right away — handy for backups, cron jobs and scripts. It goes through the same queue; SMS/WhatsApp are charged from your balance. Counts toward the plan's monthly notification limit.

JSON body:

- `title` (string, required) — Title (max 160).
- `message` (string) — Body text (max 1000).
- `methods` (string[]) — Array of "app", "sms", "whatsapp", "email". Default ["app"]. sms/whatsapp need a paid plan and are charged per message from the balance; app and email are free (email: user accounts only).
- `severity` (string) — info (default), success, warning or danger.

```bash
curl -X POST https://app.notify.bd/api/v1/notify \
  -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"title":"Backup finished","message":"db.bak 2.3 GB","methods":["app"],"severity":"success"}'
```

Response 202:

```json
{
  "ok": true,
  "id": "9b2e…",
  "deliveries": [
    {
      "method": "app",
      "status": "queued",
      "cost": 0,
      "error": null
    }
  ]
}
```

### GET /api/v1/notifications

**Read your inbox.** Latest notifications, newest first. waitingForAnswer = a reminder is still waiting for Yes (answer it with POST /answer).

Query parameters:

- `unread` (boolean) — Only unread (default false).
- `limit` (integer) — 1–200 (default 50).

```bash
curl "https://app.notify.bd/api/v1/notifications?unread=true&limit=20" -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": [
    {
      "id": "9b2e…",
      "kind": "reminder",
      "severity": "info",
      "title": "Go to play",
      "body": "",
      "createdAt": "2026-09-28T11:00:00Z",
      "read": false,
      "occurrenceId": "5d0a…",
      "waitingForAnswer": true
    }
  ]
}
```

## Monitors

Uptime checks for websites and servers. A monitor turns down after a few failed checks in a row and up after one good check; only changes send alerts.

### POST /api/v1/monitors

**Watch a site or server.**

JSON body:

- `target` (string, required) — http: a URL; tcp / ping: a host name or IP.
- `kind` (string) — http (default; down on status ≥ 400 or missing keyword), tcp (host + port) or ping.
- `name` (string) — Display name.
- `port` (integer) — tcp only.
- `keyword` (string) — http only: text that must appear on the page.
- `intervalSec` (integer) — Seconds between checks (default 300; the plan sets the minimum).
- `methods` (string[]) — Array of "app", "sms", "whatsapp", "email". Default ["app"]. sms/whatsapp need a paid plan and are charged per message from the balance; app and email are free (email: user accounts only).

```bash
curl -X POST https://app.notify.bd/api/v1/monitors \
  -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Shop","kind":"http","target":"https://shop.example.com","intervalSec":300,"methods":["app"]}'
```

Response 201:

```json
{
  "ok": true,
  "data": {
    "id": "c7aa…",
    "name": "Shop",
    "kind": "http",
    "target": "https://shop.example.com",
    "intervalSec": 300,
    "methods": [
      "app"
    ],
    "active": true,
    "state": "unknown"
  }
}
```

### GET /api/v1/monitors

**List monitors.** With state (up / down / unknown / paused), last check time, latency and last error.

```bash
curl https://app.notify.bd/api/v1/monitors -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": [
    {
      "id": "c7aa…",
      "name": "Shop",
      "state": "up",
      "latencyMs": 182,
      "lastCheckAt": "2026-09-28T11:02:10Z"
    }
  ]
}
```

### DELETE /api/v1/monitors/{id}

**Delete a monitor.**

Path parameters:

- `id` (uuid, required) — Monitor id.

```bash
curl -X DELETE https://app.notify.bd/api/v1/monitors/MONITOR_ID -H "X-API-Key: YOUR_API_KEY"
```

Response 200:

```json
{
  "ok": true
}
```

## Resellers (admin keys)

Only API keys of Admin (reseller) accounts can call these; other keys get 403 admin_only. Users sign in with their email.

### GET /api/v1/users (admin key)

**List your users.**

```bash
curl https://app.notify.bd/api/v1/users -H "X-API-Key: YOUR_ADMIN_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "Rahim Uddin",
      "username": "rahim@example.com",
      "active": true,
      "balance": 100.0,
      "plan": "Pro"
    }
  ]
}
```

### POST /api/v1/users (admin key)

**Create a user.**

JSON body:

- `name` (string, required) — Full name.
- `email` (string, required) — Email — also the sign-in name.
- `password` (string, required) — At least 6 characters.
- `phone` (string) — Mobile number for SMS/WhatsApp.
- `packageId` (uuid) — Plan id (the Developer page in the app lists yours).
- `chargePlan` (boolean) — Take the plan price from the user's balance (default false).

```bash
curl -X POST https://app.notify.bd/api/v1/users \
  -H "X-API-Key: YOUR_ADMIN_KEY" -H "Content-Type: application/json" \
  -d '{"name":"Rahim Uddin","email":"rahim@example.com","password":"secret123","phone":"01712345678"}'
```

Response 201:

```json
{
  "ok": true,
  "data": {
    "id": "…",
    "username": "rahim@example.com",
    "active": true
  }
}
```

### PUT /api/v1/users/{email}/password (admin key)

**Change a user's password.** Sets a new password and signs the user out everywhere.

Path parameters:

- `email` (string, required) — The user's email (sign-in name).

JSON body:

- `password` (string, required) — At least 6 characters.

```bash
curl -X PUT https://app.notify.bd/api/v1/users/rahim@example.com/password \
  -H "X-API-Key: YOUR_ADMIN_KEY" -H "Content-Type: application/json" -d '{"password":"newSecret1"}'
```

Response 200:

```json
{
  "ok": true,
  "message": "Password updated. The user's other sessions are signed out."
}
```

### PUT /api/v1/users/{email}/status (admin key)

**Activate or suspend a user.** active false suspends the user (signed out, no notifications).

Path parameters:

- `email` (string, required) — The user's email.

JSON body:

- `active` (boolean, required) — true = active, false = suspended.

```bash
curl -X PUT https://app.notify.bd/api/v1/users/rahim@example.com/status \
  -H "X-API-Key: YOUR_ADMIN_KEY" -H "Content-Type: application/json" -d '{"active":false}'
```

Response 200:

```json
{
  "ok": true,
  "data": {
    "username": "rahim@example.com",
    "active": false
  }
}
```

### POST /api/v1/users/{email}/topup (admin key)

**Add or deduct balance.** Positive amount adds taka to the user's balance, negative deducts.

Path parameters:

- `email` (string, required) — The user's email.

JSON body:

- `amount` (number, required) — Taka; negative to deduct.
- `note` (string) — e.g. a bKash transaction id.

```bash
curl -X POST https://app.notify.bd/api/v1/users/rahim@example.com/topup \
  -H "X-API-Key: YOUR_ADMIN_KEY" -H "Content-Type: application/json" -d '{"amount":100,"note":"bKash 8H3K2"}'
```

Response 200:

```json
{
  "ok": true,
  "balance": 100.0
}
```

### GET /api/v1/topics (admin key)

**List your channels.** Channels (topics) with subscriber counts.

```bash
curl https://app.notify.bd/api/v1/topics -H "X-API-Key: YOUR_ADMIN_KEY"
```

Response 200:

```json
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "name": "Server alerts",
      "open": true,
      "subscribers": 42
    }
  ]
}
```

### POST /api/v1/broadcast (admin key)

**Broadcast.** Message all your users, or one channel's subscribers. SMS/WhatsApp are charged to your balance.

JSON body:

- `title` (string, required) — Title.
- `message` (string) — Body text.
- `topicId` (uuid) — Channel id from GET /topics; leave out for all users.
- `methods` (string[]) — Array of "app", "sms", "whatsapp", "email". Default ["app"]. sms/whatsapp need a paid plan and are charged per message from the balance; app and email are free (email: user accounts only).
- `severity` (string) — info, success, warning or danger.

```bash
curl -X POST https://app.notify.bd/api/v1/broadcast \
  -H "X-API-Key: YOUR_ADMIN_KEY" -H "Content-Type: application/json" \
  -d '{"title":"Server maintenance tonight","methods":["app"],"severity":"warning"}'
```

Response 202:

```json
{
  "ok": true,
  "id": "…",
  "recipients": 87
}
```

## Errors

Errors: `{"ok": false, "error": "code", "message": "…"}`.

| Status | error | Meaning |
|---|---|---|
| 401 | `invalid_api_key` | Missing or wrong API key. |
| 403 | `account_inactive` | The account (or its reseller) is not active. |
| 403 | `api_not_in_plan` | The plan does not include the API. |
| 403 | `admin_only` | Only reseller (Admin) keys can call this. |
| 402 | `limit_reached` | The plan's reminder or monitor limit is reached. |
| 402 | `method_not_in_plan` | SMS or WhatsApp is not in the plan. |
| 402 | `monthly_limit_reached` | The plan's notifications for this month are used up. |
| 400 | `invalid` | A value is missing or wrong; message says which. |
| 400 | `missing_title` | POST /notify without a title. |
| 400 | `bad_repeat` | repeat is not once, daily, weekly, monthly or yearly. |
| 400 | `bad_in_minutes` | inMinutes is not 1–525600. |
| 400 | `bad_kind` | Monitor kind is not http, tcp or ping. |
| 400 | `weak_password` | Password shorter than 6 characters. |
| 400 | `missing_active` | Status change without active true/false. |
| 400 | `missing_amount` | Top-up without an amount. |
| 404 | `not_found` | No such reminder / monitor / user in your account. |

## MCP server for AI assistants

- URL `https://app.notify.bd/mcp`, Streamable HTTP. Sign in with OAuth 2.1 (PKCE, dynamic client registration) or `Authorization: Bearer <API key>`.
- Claude / ChatGPT / Cursor: add a custom MCP connector with that URL, leave client id/secret empty, sign in, Allow.
- Gemini: custom app, use it in the Spark tab (`@NotifyBD`).
- Claude Code: `claude mcp add --transport http notifybd https://app.notify.bd/mcp --header "Authorization: Bearer YOUR_API_KEY"`

Tools:

- `whoami` — Account, balance, time zone + local time, plan and monthly notification usage.
- `list_reminders / get_reminder` — Read reminders.
- `create_reminder` — Same fields as POST /reminders, including inMinutes ("in 30 minutes") and alarm.
- `pause_reminder / resume_reminder / delete_reminder` — Change a reminder.
- `answer_reminder` — Answer yes / snooze / notyet.
- `send_notification` — Notify yourself now.
- `list_notifications` — Read the inbox.
- `list_monitors / create_monitor / delete_monitor` — Uptime monitors.
- `list_users / create_user / set_user_password / set_user_status / topup_user / list_topics / broadcast` — Reseller (Admin) accounts only.

## Public data

`GET https://app.notify.bd/api/public/plans` — active plans and prices, no key, CORS open.
