Yes, there is a way to post WhatsApp Status updates by API: link the WhatsApp number to Mossmoon with one QR scan, then call POST /status-updates with text or a photo or video URL. The post shows up on the account’s Status for 24 hours, and the API also tells you who viewed it, lets you choose who can see it and deletes it early.
Below are the real requests and responses for each step, then the limits to plan around. It is part of the $15 per line plan with nothing extra to switch on. The rest of the profile and privacy endpoints are summed up in the profile and Status features.
Is there an official WhatsApp Status API?
Not from Meta. The WhatsApp Business Platform (Cloud API) is built for sending messages to individual people, and it has no endpoint for Status. Businesses that want their Stories posted on time, from the same system that already runs their promotions, have had to do it by hand on the phone.
Mossmoon works differently. It links the customer’s own number as a linked device, so the API can do what the person can do on the Updates tab: post text, photos and video, see viewers, change Status privacy and delete posts. It works on personal WhatsApp and the WhatsApp Business app, with no business verification. The Business API vs personal API explainer covers when each approach fits.
Status is where a bakery, a salon or a realtor tells every customer in their contacts something at once, without messaging each one.
How do I post a WhatsApp Status update from code?
Five steps, from a fresh number to a live post you can measure.
- 1
Link the WhatsApp number
Create a line withPOST /api/v1/wa/linesand show your customer theconnect_url. They scan the QR from WhatsApp’s Linked devices screen and you getline.ready. Personal WhatsApp and the WhatsApp Business app both work. - 2
Choose who sees it (optional)
PUT .../status-updates/audiencewithcontacts,contacts_exceptoronly_share_with. Skip this to keep whatever the phone already uses. It applies to posts made after the change. - 3
Post the Status
POST .../status-updateswithtextfor a text post, ormedia_urland an optionalcaptionfor a photo or video. It appears on the phone’s Updates tab like any post made there. - 4
Keep the status_id
The201carriesstatus_id,posted_atandexpires_at, 24 hours later. Store the id exactly as given: it is how you read viewers or take the post down. No webhook fires for Status posts. - 5
Read viewers, or delete it early
GET .../status-updates/:status_id/viewersreturns who viewed it and when, andDELETE .../status-updates/:status_idremoves it for everyone before the 24 hours are up.
How do I post a text Status?
Send text on its own. background_color and font are optional: leave the color out and you get a random one from WhatsApp’s palette, leave the font out and you get sans.
curl https://mossmoon.app/api/v1/wa/lines/wa_8f3c2e1a/status-updates \
-H "Authorization: Bearer mm_live_..." \
-H "Content-Type: application/json" \
-d '{
"text": "Open late tonight. Fresh sourdough until 9pm.",
"background_color": "#26C4DC",
"font": "serif"
}'const res = await fetch("https://mossmoon.app/api/v1/wa/lines/wa_8f3c2e1a/status-updates", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MOSSMOON_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Open late tonight. Fresh sourdough until 9pm.",
background_color: "#26C4DC",
font: "serif",
}),
});
const { status_update } = await res.json();res = requests.post(
"https://mossmoon.app/api/v1/wa/lines/wa_8f3c2e1a/status-updates",
headers={"Authorization": f"Bearer {MOSSMOON_KEY}"},
json={
"text": "Open late tonight. Fresh sourdough until 9pm.",
"background_color": "#26C4DC",
"font": "serif",
},
)
status_update = res.json()["status_update"]201 Created
{
"ok": true,
"status_update": {
"status_id": "true_status@broadcast_3EB0C4F1A2B3_36554986758374@lid",
"type": "text",
"text": "Open late tonight. Fresh sourdough until 9pm.",
"caption": null,
"background_color": "#26C4DC",
"font": "serif",
"posted_at": "2026-10-16T17:30:04.000Z",
"expires_at": "2026-10-17T17:30:04.000Z"
}
}Text can be up to 700 characters and 10 lines, the same limits as the composer on the phone. The color has to be one of WhatsApp’s own 21 backgrounds (any other value gets a 400 that lists them), and the font is sans, serif or script.
- #A62C71
- #90A841
- #C1A03F
- #792138
- #AE8774
- #F0B330
- #B6B327
- #C69FCC
- #8B6990
- #FF8A8C
- #54C265
- #FF7B6B
- #26C4DC
- #57C9FF
- #74676A
- #7E90A3
- #5696FF
- #6E257E
- #7ACBA5
- #243640
- #8294CA
How do I post a photo or video Status?
Send a media_url instead of text, with an optional caption. Mossmoon fetches the file, prepares it the way WhatsApp’s own Status screen does and posts it, then reads the post back from the account’s Status list before answering, so a 201 means it is really up.
POST /api/v1/wa/lines/wa_8f3c2e1a/status-updates
Authorization: Bearer mm_live_...
Content-Type: application/json
{
"media_url": "https://cdn.harborbakery.com/today/sourdough.jpg",
"caption": "Sourdough is out of the oven"
}- Photos and videos only. JPEG, PNG, WebP and GIF images, MP4, 3GP and QuickTime video. A PDF or audio file gets
400. - Up to 16 MB. The URL must be public https, like any
media_urlin the API. A caption can be up to 1,024 characters. - No hosting? Upload first.
POST /uploadsgives you an upload URL and amedia_urlto use here.
Text posts take only text, background_color and font, and media posts take only media_url and caption. Mixing the two gets a clear 400 rather than a guess.
How do I see who viewed a WhatsApp Status?
Call GET .../status-updates/:status_id/viewers. You get each viewer’s WhatsApp id, their phone number where WhatsApp knows it, and when they looked, newest first. Viewers WhatsApp knows only by an internal id ending in @lid are matched back to a number when possible.
GET /api/v1/wa/lines/wa_8f3c2e1a/status-updates/
true_status@broadcast_3EB0C4F1A2B3_36554986758374@lid/viewers
{
"line_id": "wa_8f3c2e1a",
"status_id": "true_status@broadcast_3EB0C4F1A2B3_36554986758374@lid",
"viewer_count": 2,
"viewers": [
{
"wa_id": "[email protected]",
"e164": "+15554041290",
"viewed_at": "2026-10-16T18:42:10.000Z"
},
{
"wa_id": "103414994325753@lid",
"e164": "+15553182290",
"viewed_at": "2026-10-16T18:31:55.000Z"
}
],
"viewers_hidden_reason": null
}A useful pattern: an hour after posting, pull the viewers and tag those contacts in your CRM as engaged with today’s offer.
How do I control who sees my Status?
The API sets the same Status privacy you find on the phone. Send contacts for everyone in the account’s contacts, contacts_except to leave some people out, or only_share_with to show it to a chosen list. The last two take a numbers list of up to 1,024 phone numbers.
PUT /api/v1/wa/lines/wa_8f3c2e1a/status-updates/audience
Authorization: Bearer mm_live_...
Content-Type: application/json
{
"audience": "only_share_with",
"numbers": ["+15554041290", "+15553182290", "+447700900123"]
}
// 200 OK
{
"line_id": "wa_8f3c2e1a",
"audience": "only_share_with",
"numbers": ["+15554041290", "+15553182290", "+447700900123"]
}The answer is read back from WhatsApp, not echoed from your request. The change applies to future posts: anything already up keeps the audience it was posted with. GET on the same path tells you the current setting.
Status on WhatsApp is a contacts feature. If a customer should see your posts, save them as a contact with POST /contacts/save, which counts as “My contacts” for privacy settings.
How do I list or delete Status updates?
GET .../status-updates returns the account’s posts that are still up, newest first, in the same shape as the post response. That includes posts made on the phone, so your app can show the full picture. To take one down for everyone, as Delete does on the phone:
DELETE /api/v1/wa/lines/wa_8f3c2e1a/status-updates/
true_status@broadcast_3EB0C4F1A2B3_36554986758374@lid
Authorization: Bearer mm_live_...
// 200 OK
{
"ok": true,
"status_id": "true_status@broadcast_3EB0C4F1A2B3_36554986758374@lid",
"deleted": true
}Mossmoon checks that the post is gone from WhatsApp’s list before it answers. A post that has already expired or was deleted comes back 404 status_not_found.
Do contacts’ Status updates reach my CRM?
No, and that is on purpose. The account sees its contacts’ Stories on the Updates tab, but they are not conversations, so Mossmoon never sends them to your webhook as message.received and never stores them as chats. Reactions to Status posts are left out too, and your own posts don’t produce delivery webhooks.
Replies are different: when someone answers your Status, WhatsApp delivers it as a normal direct message in their chat, so it arrives like any other message. There is no endpoint for reading other people’s Status posts. New to webhooks? Start with the webhook setup guide.
What are the limits of the WhatsApp Status API?
- Text: 700 characters and 10 lines, one of 21 colors, three fonts.
- Media: one photo or video per post, up to 16 MB, from a public https URL, with an optional caption of up to 1,024 characters.
- 24 hours: every post expires a day after
posted_at, and the list only shows live ones. Keep your own copy if you want a history. - Viewers need read receipts on the posting account, as on the phone.
- Audience is forward-looking: changing it does not re-share or hide posts already up.
- No Status webhook: posting, viewing and expiry don’t fire events, so poll viewers when you need them.
- The line must be connected. If the phone has unlinked it, you get
409 line_not_ready.
Full field details are in the docs under Status updates.
Mossmoon vs goghl.ai for WhatsApp Status
goghl.ai links WhatsApp by QR inside GoHighLevel and focuses on chats, groups and workflows. We searched their public site and help center for Status or Stories and found nothing, so every row here is marked Not listed.
$15 a line. First line free for 7 days.
| Feature | RecommendedMossmoon$15 a line. First line free for 7 days.Start free → | goghl.ai |
|---|---|---|
| Post a text Status | YesUp to 700 characters, WhatsApp's 21 background colors and 3 fonts | Not listed |
| Post a photo or video Status | YesUp to 16 MB, with a caption | Not listed |
| See who viewed a Status | YesEach viewer's number and time | Not listed |
| Choose who sees Status updates | YesMy contacts, all except some, or only some | Not listed |
| Delete a Status before it expires | YesOne call, removed for everyone | Not listed |
Checked against goghl.ai’s public site and help center on October 16, 2026. “Not listed” means we couldn’t find it in their docs, not that it can’t exist. Only features goghl.ai doesn’t list are shown. Sources: goghl.ai, goghl.ai help center, help center page index.
Meta’s WhatsApp Business Platform can’t post Status at all (Cloud API docs). The full comparison across every feature is on the features page. Ready to try it? Start free and link a number in a couple of minutes.
Frequently asked questions
No. Meta's WhatsApp Business Platform (the Cloud API) sends messages to people but has no endpoint for posting to Status. Mossmoon posts Status as the linked account itself, the way the phone does, on personal WhatsApp and on the WhatsApp Business app.
24 hours, the same as one posted on the phone. The response gives you expires_at, GET /status-updates only lists posts that are still up, and DELETE takes one down sooner.
Either nobody has opened it yet, or the account has read receipts turned off. WhatsApp only shows viewers to an account that sends read receipts itself, so in that case viewers_hidden_reason is read_receipts_off. PATCH /privacy with read_receipts set to all turns them back on, on the phone as well.
Mossmoon posts the moment you call it, so the schedule lives on your side: a cron job, a queue in your app, or an n8n or Make scenario with an HTTP step. Posting at 7am every day is one POST at 7am every day.
No. Other people's Status posts are not conversations, so Mossmoon never sends them to your webhook or stores them as messages. When someone replies to your Status, that reply is an ordinary direct message and arrives as message.received.
A Status update is the 24-hour post on the Updates tab. Status text is the short line with an emoji under the name, such as In a meeting, which you set with PUT /profile/status-text (up to 139 characters, with an optional expiry). The about line is set through PATCH /profile.