heybmoDocsOpen HeyBMO

API reference

Inbox

Everything HeyBMO tells you, and your notification devices.

Base URL https://app.heybmo.comFor agents: llms.txt · OpenAPI

Operations

ReadPOST /api/ops/inbox.list

Read the inbox

List the person’s HeyBMO inbox, newest first: reminders that went off, automation messages and notices from HeyBMO, with how many are unread. Each entry says who sent it and which records it is about, and how each stands now, so it can be acted on (mark a reminder done, record a payback): a reminders.firing whose facts say done or whose state is not live needs nothing more. Reading does not mark anything read; inbox.markRead does.

MCP tool inbox_listCLI heybmo inbox listLimit readSafe to retryInput
unreadtrue or falseOnly entries not read yet. Default false.
fromtextOnly from this sender: a feature id (reminders), automations, or heybmo.
limitnumberDefault 20.
cursortextnextCursor from the previous page.
curl https://app.heybmo.com/api/ops/inbox.list \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{}}'
200 response
{
  "output": {
    "items": [
      {
        "id": "01a19279-e9c3-7c73-9705-94f082fa3a65",
        "kind": "…",
        "from": "…",
        "title": "…",
        "body": "…",
        "link": "…",
        "details": {
          "visual": {},
          "facts": [],
          "links": []
        },
        "about": [
          {}
        ],
        "read": false,
        "createdAt": "2026-11-09T09:00:00.000Z"
      }
    ],
    "unread": 0,
    "total": 0,
    "nextCursor": "…"
  }
}
WritePOST /api/ops/inbox.markRead

Mark inbox entries read

Mark inbox entries read, by id, or every unread one with all: true. Marking read changes nothing else: a reminder stays not done until reminders.done.

MCP tool inbox_markReadCLI heybmo inbox markReadLimit writeInput
idslist of idEntries from inbox.list. Up to 100 items.
alltrue or falseEvery unread entry. Default false.
curl https://app.heybmo.com/api/ops/inbox.markRead \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{"ids":["01a19baf-5f80-7b83-9fd5-667bd5562b12"]}}'
200 response
{
  "output": {
    "marked": 0,
    "unread": 0
  }
}
ReadPOST /api/ops/inbox.settings

Read notification settings

Read how this person is told things: the channels every message goes to by default, each group’s channels (and whether it follows the default), quiet hours, and the morning email. The inbox always gets every message. One item’s own channels (a reminder’s delivery) win over its group, which wins over the default.

MCP tool inbox_settingsCLI heybmo inbox settingsLimit readSafe to retryInput

No input: send an empty object.

curl https://app.heybmo.com/api/ops/inbox.settings \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{}}'
200 response
{
  "output": {
    "defaults": [
      "email"
    ],
    "groups": [
      {
        "group": "reminders",
        "follows": false,
        "channels": [
          "email"
        ]
      }
    ],
    "quiet": {
      "from": "…",
      "to": "…"
    },
    "dailyEmail": false,
    "sound": false
  }
}
WritePOST /api/ops/inbox.changeSettings

Change notification settings

Change how this person is told things, only when they ask. Set the default channels (email or none, besides the inbox), a group’s own channels (email, push and/or desktop, several at once; follow: true puts it back on the default), quiet hours (null turns them off), or the morning email. Only what is given changes.

MCP tool inbox_changeSettingsCLI heybmo inbox changeSettingsLimit writeSafe to retryInput
groupslist of objectUp to 4 items.Each item:
grouprequiredreminders | budget | automations | heybmo
followtrueBack to following the default.
channelslist of email | push | desktopIts own channels besides the inbox; [] is the inbox only. Up to 3 items.
routedefault | inbox | emailOlder single choice; use channels.
pushtrue or falseOlder pop-up switch; use channels.
quietobject or null
dailyEmailtrue or false
soundtrue or false
defaultslist of emailThe default channels besides the inbox; [] is the inbox only. Up to 1 items.
defaultRouteinbox | emailOlder single choice; use defaults.
curl https://app.heybmo.com/api/ops/inbox.changeSettings \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{"defaults":["email"]}}'
200 response
{
  "output": {
    "defaults": [
      "email"
    ],
    "groups": [
      {
        "group": "reminders",
        "follows": false,
        "channels": [
          "email"
        ]
      }
    ],
    "quiet": {
      "from": "…",
      "to": "…"
    },
    "dailyEmail": false,
    "sound": false
  }
}
ReadPOST /api/ops/inbox.devices

List devices that show pop-ups

List the browsers and devices where this person allowed HeyBMO pop-ups, and the key a browser needs to allow them (null when pop-ups are off on this server).

MCP tool inbox_devicesCLI heybmo inbox devicesLimit readSafe to retryInput

No input: send an empty object.

curl https://app.heybmo.com/api/ops/inbox.devices \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{}}'
200 response
{
  "output": {
    "publicKey": "…",
    "devices": [
      {
        "id": "01a19279-e9c3-7c73-9705-94f082fa3a65",
        "label": "…",
        "endpoint": "…",
        "addedAt": "2026-11-09T09:00:00.000Z",
        "lastUsedAt": "2026-11-09T09:00:00.000Z"
      }
    ]
  }
}
WritePOST /api/ops/inbox.addDevice

Allow pop-ups on this browser

Save the browser the person is using as one that shows HeyBMO pop-ups (its Web Push subscription). Done by HeyBMO in the browser after the person allows notifications. A person keeps up to 20; adding one more forgets the one used longest ago.

Only the person can do this, in HeyBMO in the browser. Called from here, it changes nothing.

MCP tool inbox_addDeviceCLI heybmo inbox addDeviceLimit writeSafe to retryInput
endpointrequiredtextUp to 2048 characters.
p256dhrequiredtext
authrequiredtext
labelrequiredtextUp to 120 characters.
curl https://app.heybmo.com/api/ops/inbox.addDevice \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{"endpoint":"https://fcm.googleapis.com/fcm/send/abc123","p256dh":"BNcRdreALRFXTkOOUHK1EtK2wtaz5Ry4YfYCA_0QTpQtUbVlUls0VJXg7A8u-Ts1XbjhazAkj7I99e8QcYP7DkM","auth":"tBHItJI5svbpez7KI4CCXg","label":"Chrome on Windows"}}'
200 response
{
  "output": {
    "device": {
      "id": "01a19279-e9c3-7c73-9705-94f082fa3a65",
      "label": "…",
      "endpoint": "…",
      "addedAt": "2026-11-09T09:00:00.000Z",
      "lastUsedAt": "2026-11-09T09:00:00.000Z"
    }
  }
}
DeletePOST /api/ops/inbox.removeDevice

Stop pop-ups on a device

Stop HeyBMO pop-ups on one browser or device (from inbox.devices). Its inbox and emails are not affected; pop-ups can be allowed again from that browser.

Deletes for good. The first call changes nothing and answers CONFIRMATION_REQUIRED with what would be deleted; call again with confirm: true once the person agrees.

MCP tool inbox_removeDeviceCLI heybmo inbox removeDeviceLimit deleteSafe to retryInput
idrequiredid
confirmtrue or falseSet to true once the person agreed. Without it nothing is deleted and you get a description of what would be.
curl https://app.heybmo.com/api/ops/inbox.removeDevice \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{"id":"01a1b0b6-94af-77a1-b13f-0fb0e1b38487"}}'
200 response
{
  "output": {
    "removed": false
  }
}
WritePOST /api/ops/inbox.testPopup

Send a test pop-up

Send one test pop-up to every device where the person allowed pop-ups, so they can see it works. Quiet hours do not stop it.

Only the person can do this, in HeyBMO in the browser. Called from here, it changes nothing.

MCP tool inbox_testPopupCLI heybmo inbox testPopupLimit writeInput

No input: send an empty object.

curl https://app.heybmo.com/api/ops/inbox.testPopup \
  -H "Authorization: Bearer $HEYBMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input":{}}'
200 response
{
  "output": {
    "devices": 0
  }
}