One API for every notification your product sends

Bodhveda is an open-source notification API. Send to one user or broadcast to all of them, and every send respects what that user chose to hear about. In-app and email today, with push, SMS and chat apps next.

Open source under AGPL-3.0. Run it on our cloud or your own servers.

Your server

POST /notifications/send

{
"recipient_id": "priya",
"target": { "channel": "posts", "topic": "post_482", "event": "new_comment" },
"payload": {
"title": "Arjun commented on your post",
"body": "This saved me a whole weekend."
},
"email": {
"subject": "Arjun commented on your post",
"html": "<p>This saved me a whole weekend.</p>"
}
}

A direct send to one recipient. The payload goes to her inbox and the email block goes to her email address.

Press send, then change Priya's settings and send again.
P

Priya, in your app

priya@example.com

Emails you send Priya will show up here.

Priya's notification settings

In-app

Email

Comments on my posts

Product updates

Security alerts

Every notification has an address

A target is three names you choose: where in your product, which thing, and what happened. Preferences, broadcasts and delivery stats all hang off it.

posts

channel

The area of your product

post_482

topic

The specific thing, or any

new_comment

event

What happened

Users mute by target

A user can turn off one target or a whole channel, per medium. One catalog entry with topic any covers every post, so you never create one per post.

Broadcasts follow targets

Send without a recipient and Bodhveda delivers to everyone subscribed to that target. People who opted out are skipped, and you can see how many.

Typos fail on the first call

Turn on strict targets and an uncataloged target returns a 400 instead of a bug report weeks later. Mandatory entries keep things like password resets unmutable.

Send from your backend. Draw it in your frontend.

Payloads are any JSON you like, and the inbox is your own components. Use the SDKs for JavaScript, Go and React, or call the REST API from anything else.

  • The recipient is created on their first notification. There’s no user sync to build.
  • Email goes out through your own Resend account, from your own domain.
  • A recipient-scoped key lets the browser read one user’s inbox and nothing else.
Send your first notification in the quickstart
comments.ts
import { Bodhveda } from "@bodhveda/js";

const bodhveda = new Bodhveda(process.env.BODHVEDA_API_KEY);

await bodhveda.notifications.send({
    recipient_id: post.authorId,
    target: { channel: "posts", topic: post.id, event: "new_comment" },
    payload: { title: `${user.name} commented on your post` },
});

The parts you’d otherwise build yourself

Sending is the easy bit. Bodhveda also handles what comes after it.

One send, many mediums
One send fans out to every medium it carries a block for, and each medium has its own preference.In-appEmailWeb pushMobile pushSMSWhatsAppTelegramIn-app and email ship today. The rest are coming, in that order.
An inbox API
List a user’s notifications with cursor pagination, mark them read or opened, delete them, and get the unread count for the bell.
Preferences per target and medium
One call returns everything a settings screen needs: each target, each medium, and whether it’s on, inherited or required.
Email with real delivery status
Bodhveda sends through your Resend account and records sent, delivered, bounced and complained from its webhooks. One-click unsubscribe flips the same preference as your settings toggle.
A console for the rest
Send notifications by hand, look up any recipient and their preferences, see what happened to every send, and manage API keys.
Yours to run
A Go API and worker on Postgres and Redis, licensed AGPL-3.0. Use the hosted version or deploy the same code on your own servers.

A million broadcast notifications in under nine seconds

Measured, not estimated. Each run checks that every row landed as delivered before it reports a time.

RecipientsTimePer second
10,000108 ms93,021
100,000691 ms144,736
1,000,0008.56 s116,876
Apple M4 with Postgres 17.4 in Docker on stock settings and 10 delivery workers. Run the benchmark yourself.

What it is, and what it isn’t

Bodhveda does one job. Here’s where it stops, so you can tell quickly whether it fits.

It is

  • A notification API. Direct sends, broadcasts, an inbox to read them from, and preferences that gate every send.
  • Built for every medium. Each medium is its own block on the same send, with its own preference. New ones slot in without changing the sends you already have.
  • Headless. You get data and hooks. The bell, the dropdown and the settings page look like the rest of your app.
  • Open source. The hosted version runs the same code that’s on GitHub.

It isn’t

  • A workflow builder. No drag-and-drop journeys or delay nodes. Your code decides when to send.
  • A drop-in widget. There’s no prebuilt inbox UI to restyle. That’s on purpose.
  • An email service. You bring a Resend account and Bodhveda sends through it. Templates stay in your code.
  • On every medium, yet. In-app and email ship today. Web push is next, then mobile push, SMS, and chat apps like WhatsApp and Telegram.

A note from the creator

Hey,

Every product I build ends up needing notifications. Someone replied. A sync finished. A new feature shipped. And every time, the first version is a table, a polling endpoint and a bell icon.

Then come the requests. Let me turn these off. Email me instead. Why did I get this twice? Each one is a week of plumbing that has nothing to do with the product.

So I built that plumbing once, properly, and called it Bodhveda.

I use it myself, in production. Arthveda tells traders when someone follows them and when something new ships. Grahak runs its whole notification center on it: new conversations, mentions and assignments in-app, plus one email per thread when a customer sends a burst of replies, not one email per reply.

It’s just me building this. If something is missing or feels wrong, email me at hey@ceoshikhar.com.

Thanks for being here.

Free until you outgrow it

Pricing is per notification sent, with no per-seat or per-recipient charges.

Free

$0per month

For side projects and new products.

  • 10,000 notifications a month
  • Every medium, as each one ships
  • Every feature, including the console
Start for free

Pro

Coming soon

$20per month

For products with a real audience.

  • 100,000 notifications a month
  • Everything in Free
  • Priority support
Ask about Pro

Self-hosted

$0on your servers

For when you want to own every row.

  • No limits beyond your hardware
  • The same code as the hosted version
  • AGPL-3.0
View on GitHub

Questions developers ask first

No. A direct send creates the recipient if they don’t exist yet, using whatever ID you already have for that user. Broadcasts go to the recipients you already have.

No. Bodhveda is headless: the React SDK gives you hooks for notifications, unread counts and preferences, and you render them with your own components.

In-app and email today. Web push is next, followed by mobile push, SMS, and chat apps like WhatsApp and Telegram. Each new medium arrives as another block on the same send call, so code you write now keeps working.

Resend, for now. You connect your own Resend account in the console, so emails come from your domain and your sender reputation. Templates stay in your code: you pass the subject and HTML on each send.

Yes. Leave out the payload and include only the email block. That’s useful when the inbox should update on every event but the email should go out once, as a summary.

Yes. Emails include one-click unsubscribe, which turns off the same preference your settings page shows. Targets you mark as mandatory, like password resets, can’t be unsubscribed from.

Sends past the limit are recorded as quota_exceeded instead of delivered, and you can see each one in the console. Nothing is dropped silently.

Yes. It’s a Go API and worker on Postgres and Redis, with Docker Compose files in the repo. The hosted version runs the same code.

Just me, Shikhar. I build and maintain it on my own. Everything else I’m building is on ceoshikhar.com.

Send your first notification today

Create a project, copy an API key, and make one request. The quickstart takes about five minutes.