Changelog
Changes that affect people integrating. Additions with no contract impact are left out.
What counts as a breaking change
| Change | Breaking? |
|---|---|
| New optional field in a response | no |
| New optional field in a request | no |
| New endpoint | no |
| New value in an enum | no — handle unknown values with a default case |
| Field removed from a response | yes |
| Optional field became required | yes |
| A field's type changed | yes |
| A status code changed | yes |
Breaking changes only happen in a major API version, announced by email to every active account beforehand.
2.2.0
Everything in this version is additive.
Agencies and workspaces
GET /workspaces— an agency's group, with what each client consumed in the billing period. Only with the agency account's unrestricted key.GET /account/mereturnsparent: the agency that manages and pays for the account when it is a client's workspace.- Inside a workspace,
/walletand/affiliateanswer409 billed_by_parent.
2.1.0
Everything in this version is additive: nothing that already worked stops working.
New endpoints
- Contacts and consent —
/contacts, custom fields, tags, bulk import and/suppressions. See Contacts and consent. - Triggering flows —
POST /flows/{id}/trigger, withGET /flowsandGET /flows/{id}. See Flows through the API. - Campaigns and audiences —
/broadcastsand/audiences. See Campaigns. - Inbox —
/inbox, with the live stream. See Inbox. GET /plans/quote,GET /audit/operator-access,GET /wallet,GET /wallet/entries,GET /affiliateandGET /affiliate/referrals.
New events
contact.created, contact.opted_in, contact.opted_out, broadcast.completed,
broadcast.paused, flow.run.completed, flow.answer.captured,
conversation.assigned and conversation.closed. See
Event catalog.
New fields and headers
POST /messagesaccepts anIdempotency-Key. See Retrying without duplicating.- Every
402carriesaction, with what to do and where. See Errors. - The request limit is now per key, under an account ceiling. Responses carry
X-RateLimit-Scope, and a429carrieserror.scope. See Rate limits. GET /billingcarriessubscriptions, one per subscription of the account. The oldsubscriptionfield stays, marked deprecated.- Plans gained
stackable,currencyPrices,rateLimitsand the caps on contacts, campaigns and the inbox.
2.0.0
The old routes no longer answer. There is no alias: the old path returns 404, or
405 where it survives under a different method.
One sending endpoint
What changed between a text and a template was the message type, which is a body
field — not a path. The per-type routes became one, with type.
| Before | Now |
|---|---|
POST /messages/send/text | POST /messages with {"type":"text"} |
POST /messages/send/template | POST /messages with {"type":"template"} |
POST /messages/send/test | POST /messages with {"type":"test"} |
POST /messages/text, /template, /test | same — the undocumented aliases are gone |
The rest of the body is unchanged: to, from, body, name, language and
components stay as they were. So do the success and error responses.
Scheduling
The same POST /messages takes sendAt (an ISO 8601 instant) or delaySeconds and
answers 202. New: GET /messages/scheduled, GET /messages/scheduled/{id} and
DELETE /messages/scheduled/{id}. See Sending messages.
Uniform pagination
Every listing now takes ?limit= and ?offset= and answers
{ data, total, limit, offset }. Code reading res.data keeps working; code relying
on total being absent does not.
New endpoints
GET /account/senders, GET /account/usage, DELETE /account/wabas/{id},
GET /audit, GET /plans (public, no credential), GET /billing,
GET /billing/invoices, GET /billing/license and POST /templates/media.
Billing events
billing.past_due, billing.blocked and billing.restored — the first events we
originate rather than relay from Meta. See Event catalogue.
Other contract changes
POST /auth/logoutbecameDELETE /auth/session.- Both invite
/revokeroutes becameDELETEon the resource itself. - A wrong method on an existing path answers
405with anAllowheader, where it used to answer404. 402now carriesreason, including the newlicense_expired.
Removed from the documentation
The endpoints marked "coming soon" were taken out of the reference: they answered
404, and the reference now describes only what exists. Image, video, document,
buttons, list, CTA, carousel, location, contact, reaction, sticker, typing indicator
and read receipts are all still available through the mirror,
POST /v1/{phone_number_id}/messages, which takes the full Cloud API payload — see
The other message types.
1.0.0
First public release.
Simplified API — sending by message type, with the sender number resolved from the token. Listing, creating and removing templates with up-front validation of variables and examples. API keys with creation and immediate revocation.
/v1 mirror — the Meta Cloud API contract, byte for byte. Swapping the domain and
the token is enough to move an existing integration.
Webhooks — deliveries signed with HMAC-SHA256 over "{timestamp}.{body}", six
attempts with backoff from 60s to 6h, a delivery log and manual redelivery.
Coexistence — a number shared between the WhatsApp Business app and the Cloud API, with history and contact sync in the first 24 hours.
Rate limits — 500 sends per minute, 60 media uploads per minute, 60 reads per minute,
with X-RateLimit-* headers on every response.