HomeFeaturesWhatsApp API

REST API · v1

WhatsApp API

Send from a number you already own, from your own code. Twenty-one endpoints, a bearer token, and the same sending rules your team works under — no Business API application and no per-message fee to a provider.

  • 22 endpoints
  • v1 versioned from day one
  • 0 destructive calls
curl -X POST https://api.birsend.com/v1/messages \
  -H "Authorization: Bearer $BIRSEND_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-4182-shipped" \
  -d '{
    "to": "+905366250810",
    "text": "Your order has shipped. Track it here: acme.com/t/4182"
  }'

One base, one header

No SDK to install. Everything is JSON over HTTPS, and the version is in the path so a response shape can change later without breaking what you built.

Base URLhttps://api.birsend.com/v1
AuthAuthorization: Bearer <your API key>
Safe retriesIdempotency-Key: <your own id>

The 22 endpoints

Each one is governed by the same permission your Permissions screen manages. A key minted against a read-only role can call the reads and nothing else.

Your key

  • GET/meDoes this key work, and what may it do. Sends nothing to anybody.

Messages

  • POST/messagesSend text, or a picture from the library.
  • GET/messages/{id}What happened to it — delivered, read, failed, and why.

Files

  • POST/filesUpload a picture: multipart, base64, or a URL for us to fetch.
  • GET/filesThe library.
  • GET/files/{id}One file’s details.
  • GET/files/{id}/contentThe bytes back. Permission-checked, never a public URL.

Contacts

  • GET/contactsThe list, filterable.
  • POST/contactsAdd somebody. Takes the number whole.
  • POST/contacts/importA CSV file, CSV text, or an array. Returns a report per row.
  • GET/contacts/{id}One person, with their history and consent trail.
  • PATCH/contacts/{id}Everything except the number.

Clients

  • GET/clientsThe businesses you send on behalf of.
  • POST/clientsAdd one.
  • GET/clients/{id}One client.
  • PATCH/clients/{id}Rename, re-file, or archive.

Campaigns

  • GET/campaignsFilter by status, client, or search.
  • GET/campaigns/{id}One campaign and its figures.
  • PATCH/campaigns/{id}Change what can still be changed.
  • POST/campaigns/{id}/pauseStop a send that is going out.
  • POST/campaigns/{id}/resumeLet it go again, from where it stopped.

Reports

  • GET/reportsThe same numbers the panel shows, over a period you pick.
Placeholder. Replace with the API screen at /automations/api.

What it will not do

Read this part first. Each of these is a decision, not a gap — and if one of them rules us out for you, better to know now.

Nothing can be deleted

There is no DELETE on any endpoint. Removing a contact takes their consent record out of the workspace’s sight; removing a file breaks the messages pointing at it; removing a client changes what every colleague sees in the campaign builder. Set a status to archived instead — the history stays and the pickers stop offering it.

Campaigns cannot be created

There is no POST /campaigns, and that is the line this API is drawn along: nothing here decides on its own that thousands of messages go out. Choosing an audience and an hour belongs in front of somebody who can see the audience count. Editing, pausing and resuming an existing campaign are all available.

Your sending rules still apply

Sending hours, daily caps, the opt-in requirement, blocked contacts and your word filter are checked per message, whoever asked. A key is a door, not an exemption — a request outside your window is refused with the reason, not queued around it.

A key cannot exceed its maker

Every key carries a role, and what it may do is the overlap between that role and the permissions of the person who minted it. Nobody can create a key more capable than themselves, and a key narrows automatically when that person is demoted.

Frequently asked questions

Is this the WhatsApp Business API?

No. Birsend drives a number you already own, so there is no application to submit, no template approval queue and no per-message fee to a provider. You get one REST API against your own line.

How do I authenticate?

A bearer token. Create an API key in the panel under Automations → API, name it after the system that will hold it, and pick the role it should have. The key is shown once; only a hash is stored, so a lost key is replaced rather than recovered.

Why does a send only return “queued”?

Because that is all we know at that moment — the message has been accepted for delivery, and WhatsApp reports delivered and read afterwards. GET /messages/{id} is there so the send is not a write-only operation.

Can I send the same message twice by accident?

Not if you pass an Idempotency-Key. A retry after a timeout with the same key returns the original message rather than sending a second one, which is the case that actually happens: the request succeeded and the response was lost.

Are there webhooks?

Not outbound, no. Your systems poll GET /messages/{id} for a specific send, or GET /reports for the aggregate. The only thing that posts to us is the WhatsApp service itself.

Do I get a test mode?

No. There is no sandbox — a request that passes the guardrails sends a real message, so develop against a number you own and read what arrives. Campaigns have no panel-level rehearsal either: the dry mode that exists is an installation-wide switch held by whoever runs the server, and it marks every recipient as skipped, so a dry run consumes the campaign instead of previewing it.

What are the rate limits?

Requests are limited per key, and a send is additionally governed by your workspace pacing and daily cap rather than by a request ceiling. A refusal says which limit it was, so you can tell “too many requests” from “outside your sending hours”.

How is this different from the MCP server?

Different reader. This API is for software you wrote, which does exactly what you programmed. MCP is for an AI agent, which does something reasonable you did not specify — so the two use separate key types and an agent gets narrower powers. One leak stays one door.

Build against your own number.

Fourteen days free, no credit card. Connect a number, mint a key, and send your first message from your own code in an afternoon.

Cookies

The site runs what it needs to work, including the Crisp chat bubble. Google Analytics is the one thing we will not load unless you agree to it.