At a glance
Capabilities
An unsupported call returns501 resource.not_supported.
The capability matrix for every platform is on Supported platforms.
Connect an account
A Zalo Official Account connects through the shared OAuth flow in Connect accounts: sendplatform: "zalo" to POST /v1/accounts/connect, send the administrator to the returned authorization URL, and read the connected account’s ID from your redirect.
Each Zalo authorization covers exactly one Official Account. The connected account’s username is the Official Account’s ID and its display_name is the OA’s name. To connect a second Official Account, run the flow again.
SocialAPI renews Zalo’s access tokens (valid for 25 hours) for you. When renewal fails, the first call that fails returns 401 platform.zalo.auth and the account is marked token_expired. Every later call that acts on the account returns 403 account.reconnection_required until you reconnect it. Reconnect with the same brand_id.
The 7-day messaging window
Zalo lets an Official Account send a customer service message only to a person who interacted with the OA within the last 7 days. Messages sent within 48 hours of the person’s last interaction are free of Zalo’s per-message fee. Messages sent after 48 hours but within 7 days can carry a fee on Zalo’s side. A send outside the window, or to a person who is not eligible (for example, a person who does not follow the OA or who blocked it), fails with422 platform.zalo.not_deliverable. SocialAPI does not check the window before it sends: Zalo’s refusal is the signal. The person’s next message to the OA reopens the window.
Direct messages
You list conversations withGET /v1/inbox/conversations, read a conversation with GET /v1/inbox/conversations/{conversation_id}/messages, and reply with POST /v1/inbox/conversations/{conversation_id}/messages. The request fields are on Direct messages.
These rules are specific to Zalo:
- Zalo returns 10 at most. One read returns the 10 most recent conversations or the 10 most recent messages of a conversation.
- A conversation is one person. The conversation’s participant ID is the person’s Zalo user ID.
- Images by URL. A
urlormedia_idattachment is sent as an image unless itstypeisgiforsticker. - One card. SocialAPI sends the first entry of
cardsas one card and drops the others. - No message ID in the send response.
message_idis empty and each entry ofmessage_idsis an empty string. Read the message’splatform_idfromGET /v1/inbox/conversations/{conversation_id}/messages. - No
message_tag. Zalo has no message tags:message_tagis ignored. - Cost. A send costs 1 interaction credit, the same as on every platform: see Plans and usage.
Webhook events
Zalo delivers a person’s text message to SocialAPI as it happens, and SocialAPI sends it to your webhook endpoints asdm.received. The event carries author.id (the person’s Zalo user ID) and content.text. It has no conversation_id and no platform_id: read the conversation with GET /v1/inbox/conversations to find the message. Images, files, stickers, follows, and read receipts raise no event. The full payload is on Webhook events.
Zalo also emits the post.* events for articles you publish through SocialAPI, account.connected when you connect the account, account.disconnected when SocialAPI flags the account for reconnection, and account.updated when the account loses permissions you did not remove yourself.
Limits
Zalo applies its own quotas per app and per Official Account. When one is used up, the call fails with
429 platform.zalo.rate_limit. Wait for the seconds in Retry-After, or at least 60 seconds when it is absent, then retry.
Scopes
SocialAPI sends no scope list to Zalo. The administrator of the Official Account approves the scopes that Zalo’s consent screen lists for SocialAPI’s Zalo app. Disconnecting the account from SocialAPI does not revoke that authorization on Zalo: the administrator removes it on Zalo. The account supports theposts.read, posts.write, messages.read, and messages.write permissions, which SocialAPI alone enforces.
Related
- Zalo publishing: articles, drafts, and asynchronous creation
- Direct messages: the request fields for sending DMs
- Connect accounts: brands, reconnecting, and disconnecting
- Webhook events: the
dm.receivedpayload - Errors: every Zalo error code
- Supported platforms: what each platform supports