Bird vs 360dialog
Bird vs 360dialog for WhatsApp
360dialog is a WhatsApp-only provider and this is the comparison where that focus shows. They pass Meta's own payload straight through, publish their prices, and run a hosted MCP server of their own. Bird is a platform where WhatsApp is one channel of several, and an agent can send on it.
What 360dialog is great at.
Where Bird is different.
What 360dialog is great at
Meta's payload, unchanged. Their send body is the Cloud API message shape: messaging_product, recipient_type, to, type and the matching type object. A team already holding Cloud API code changes the host and the auth header and keeps the payload, which is the shortest migration path in this comparison and one Bird cannot offer.
A published price list, self-serve. Every tier is a monthly figure per WhatsApp number with Meta's conversation fees passed through separately, and the partner tiers publish their platform and per-channel fees too. You can cost a deployment from the website without talking to anyone.
WhatsApp is the whole company. No email, no SMS, no voice, and a status page that separates their own components from Meta's. If WhatsApp is your only channel and you want a vendor whose roadmap cannot be pulled elsewhere, that focus is the argument, and it is a real one.
Where Bird is different
An agent that can send the message. Both run a hosted MCP server, and this is the difference between them: 360dialog's tools manage templates, profiles and webhooks, and their docs describe it composing an example JSON body for sending through their Messaging API. Bird's 43 WhatsApp tools include the send itself and number registration.
A retry that cannot double-send. An Idempotency-Key header on the send makes a repeat safe. Their messages reference documents no idempotency key or header, and on WhatsApp a duplicate opens a second billable conversation rather than just repeating itself.
A typed SDK rather than Meta's envelope. Passing Cloud API's shape through means inheriting its ergonomics: messaging_product on every request, and the content type repeated in both type and the object beside it. Bird's send is one typed call whose body names the content directly, in TypeScript, Python, Go or PHP.
The matrix
Capability by capability.
Both are Meta BSPs and both run a hosted MCP server, which makes this the closest comparison in the series on the axis Bird usually wins. Read the agent row against the Twilio and Infobip pages: it is a Bird win there for different reasons, and here it turns on one thing, whether the agent can send.
| Capability | Bird | 360dialog | Who wins? |
|---|---|---|---|
| Send request | JSON to /v1/whatsapp/messages on your regional host with a bearer API key, and the body names the content type directly. | JSON to a messages endpoint on their WABA host with a D360-API-KEY header. The body is Meta's Cloud API shape: messaging_product, recipient_type, to, type and the matching object. | |
| Safe retries | An Idempotency-Key header on the send makes a retry safe. | Their messages reference documents no idempotency key or header, so a retry after a timeout can send twice. | |
| What an agent can do | 43 WhatsApp tools on the hosted server at mcp.bird.com, including the send itself, the template lifecycle through submission to Meta, number registration and profile, and statistics. | A hosted server at mcp.360dialog.com/mcp whose tools create, preview, list and delete templates, set a channel's display name and profile, configure webhooks, and read accounts, channels, balance and invoices. Their docs describe it producing an example JSON body for sending through their Messaging API. | |
| How a gated tool behaves | A tool your grant cannot call stays listed and is annotated with the scope it needs, and a denial answers with an OAuth step-up. Hiding it was tried and removed: it made a missing scope indistinguishable from a missing capability, and agents drew the second conclusion. | Scopes are chosen at authorization time and denying one hides the corresponding tools, so an agent never sees a tool it cannot call. | |
| Content types | One send body selects text, template, image, video, audio, sticker, document, location, interactive or contact cards. | One send endpoint carries Meta's full type list: text, image, audio, video, document, sticker, location, contacts, interactive, template and reaction. | |
| Typed SDKs | Typed SDKs for TypeScript, Python, Go and PHP, generated from the API. | No official language SDKs appear in their documentation index. Because the payload is Meta's, an existing Cloud API client works against their host. | |
| Channels beyond WhatsApp | SMS, email, voice, Verify and Realtime sit under the same base URL and key, so a second channel is another endpoint rather than another vendor. | WhatsApp is the product. RCS is contact-gated rather than self-serve, and there is no email, SMS or voice. | |
| Published pricing | Rates are published per country on the WhatsApp pricing page. | Every tier is published as a monthly figure per number, with Meta's conversation fees passed through separately and no markup on them. |
The same message
Sending one WhatsApp template.
360dialog's request is Meta's, which is exactly the point of it: if you already send through the Cloud API, only the host and the auth header change. Bird's is a typed call where the content type is the field name rather than a value repeated beside its object, and it takes an Idempotency-Key.
360dialog
const orderId = "ord_8f21";
const response = await fetch("https://waba-v2.360dialog.io/messages", {
method: "POST",
headers: {
"D360-API-KEY": process.env.D360_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
messaging_product: "whatsapp",
recipient_type: "individual",
to: "15551234567",
type: "template",
template: {
name: "order_shipped",
language: { code: "en_US" },
components: [
{ type: "body", parameters: [{ type: "text", text: orderId }] },
],
},
}),
});
const result = await response.json();
console.log(result.messages[0].id);
Bird
import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
const orderId = "ord_8f21";
const { data, error } = await bird.whatsapp
.send(
{
from: "+13124495648",
to: "+15551234567",
template: {
slug: "order_shipped",
language: "en_US",
components: [{ type: "body", parameters: [{ type: "text", text: orderId }] }],
},
},
{ idempotencyKey: orderId },
)
.safe();
if (error) console.error(error.message);
else console.log(data.id, data.status);
Switching cost
Moderate.
The send is a real rewrite rather than a rename, because you are leaving Meta's envelope. messaging_product and recipient_type disappear, the content type stops being a value repeated beside its object and becomes the field itself, and the D360-API-KEY header becomes a bearer key. In exchange the call becomes typed, and a retry becomes safe.
The scheduling item is Meta rather than either vendor. Templates are approved against the WhatsApp Business Account they live under, so moving providers means submitting them again and waiting. Bird takes authoring, per-language versioning and submission over the API and as agent tools, which makes the resubmission scriptable rather than retyped.
Questions people actually ask
Is Bird a good 360dialog alternative?
Both have an MCP server. What is the actual difference?
Which handles a missing permission better?
Do I lose anything by leaving Meta's payload shape?
Where to go next
The sending guide is the one to start with: it covers the send call and the window rules.