Zalo shows up in our APAC channel guide as one of four channels worth covering — but a bundle post tells you whether Zalo belongs in your stack, not how to operate it week over week. This post is the operator guide: where Zalo fits, what the Orbit-side surface looks like once you connect a Zalo Official Account, the message classes Zalo exposes and what each send is listed at, how friend acquisition and the unified inbox work, the Vietnam baseline you operate under, and the rejection classes you will actually hit. Every claim here is constrained to the shipped capability documented in the Zalo channel docs.
1. Where Zalo fits: Vietnam's dominant messaging channel
Zalo is Vietnam's default messaging surface. If you sell to, support, or onboard users in Vietnam, Zalo is where they expect a business to be reachable — for notifications, order updates, and two-way service. Outside Vietnam it is a rounding error; inside it, running SMS-only is like running SMS-only where WhatsApp is the norm.
Two buyer personas drive Zalo programs on Devotel Orbit:
- Cross-border APAC brands — a regional or global brand expanding into Vietnam needs a Vietnamese-born channel for receipts, traffic updates, and promotions. ZNS (Zalo Notification Service) handles their one-way template traffic.
- Vietnam-native SMBs and mid-market — domestic operators run their customer-service and notification flows natively on Zalo, often on a modest budget with one or two agents. They need a channel their own customers already live on, not an app-install problem.
The rule from the APAC guide holds: Zalo earns a primary slot in Vietnam. Everywhere else in APAC the primary slot goes to LINE, WeChat, or KakaoTalk.
2. The Orbit-side surface: connecting a Zalo Official Account
Zalo is a bring-your-own-credential channel: Orbit does not auto-provision your access. The onboarding walkthrough the docs document has three steps, and the operator-side part takes minutes once Zalo approves your account:
- Register a Zalo Official Account (OA) and ZNS templates. In the Zalo for Developers console, create the OA and submit each notification template — booking confirmation, OTP, shipping update — for approval. Each approved template gets a template id you will reference as
template_nameon every send. - Generate the OA access token. Mint it through Zalo's OAuth access_token grant. The token is short-lived; you rotate it through Zalo and re-paste it in Orbit.
- Paste it into Orbit. In the dashboard go to Settings → Channels → Zalo and store the token. Orbit encrypts it at rest under your organization's
settings.channels.zaloand never echoes it back in an API response. Per-organization credentials take precedence; without one, sends fall through to a platform default (DEVOTEL_ZALO_ACCESS_TOKEN) if your operator sets one.
One caveat worth knowing up-front: Zalo on Orbit is in beta (the docs say so explicitly). The send and receive paths work end to end, but onboarding still requires you to hold a valid OA and ZNS access token — there is no OAuth flow inside the Orbit UI yet.
3. Message classes: text, flex-format, and broadcast — with worked examples and rates
ZNS is template-only. That constraint shapes the three classes you operate, and the Orbit-side structure on each one is the same POST /api/v1/messages/zalo call with an approved template_name and its template_params.
Text class — OTP. template_name: "otp_verify", template_params: { "code": "482931" }. The canonical ZNS text template send: a single named variable filling an OTP field.
Flex-format class — booking / order notification. template_name: "booking_confirmation", template_params: { "name": "Linh", "code": "VN-4821" }. A multi-variable ZNS template with named slots; Zalo's flex-format templates let you compose structured layouts inside the approved shape.
Broadcast class — blast campaign. Instead of per-message calls, deliver an approved template to an audience via POST /api/v1/campaigns (create the draft) then POST /api/v1/campaigns/:id/send (dispatch) with "channel": "zalo" and "message_template" naming the approved id. This is the same loop the docs use for WhatsApp campaigns; the broadcast fan-out stays ZNS-safe because the template is pre-approved.
Pricing: Zalo Notification Service sets its own per-message rates (ZNS is Zalo's own pricing), and Orbit charges a flat per-1M platform fee on top for delivery and inbound webhook fan-in. The current figure is listed on the pricing page, and the per-message ZNS rate Zalo bills sits underneath that platform fee.
4. Friend-acquisition loop: OA follow mechanics under tenant-owned governance
Acquisition on Zalo runs through the Official Account: customers follow your OA, and from that point on the conversation is two-way in the Zalo sense. There is no platform-side ad-buy or friend-farm loop; the mechanics — QR-to-follow on packaging, deep links from your own app, follow-prompts on receipts — are credentials and workflows you own.
What Orbit owns on this surface is custody: your OA access token, the associating metadata, and the routing of inbound ZNS replies to that contact. The governance layer — consent records, opt-in/opt-out flags, suppression lists — sits in your organization's own records and is tenant-owned end to end. That separation matters for compliance below.
5. Inbox-side: Zalo threads in the unified inbox with queues and dispositions
Inbound Zalo replies land on the standard message.received event with channel: "zalo" and get normalized into the same envelope as SMS, WhatsApp, or Telegram — there is no Zalo-specific webhook for you to register. From that point they behave like any other thread:
- They arrive into the unified inbox alongside other channels, with queues and routing rules you set.
- Agents work them with the same queues, dispositions, and tags as any other conversation; a ZNS template-reply loop (your outbound send, their inbound answer) stays in one conversation timeline.
- Outbound replies still go through ZNS templates — the two-way nature of a ZNS thread means the conversation is real, but each outbound shape still passes template validation.
For operators coming from single-channel widgets, the operational upgrade is that a Zalo thread and an SMS thread are triaged by the same team, often the same queue, with no channel-specific inbox to maintain.
6. Vietnam legal/regulatory baseline: Decree 13 consent and MIC registration (tenant-owned controls)
Zalo traffic into Vietnam runs under Vietnam's data and telco baseline. Two pillars matter for operators:
- Decree 13 / 2023 on Personal Data Protection (PDPD). Vietnam's personal-data protection regime requires that your collection and use of personal data — which includes contact identities, message content, and metadata — has a lawful basis under consent. Consent capture, consent records, and revocation are controls you operate, not something Orbit adjudicates.
- MIC telecom registration. Vietnam's Ministry of Information and Communications requires registration of telecommunications services and lawful-service operation. For a messaging operator this typically binds at the provider and account level; it is a regulatory status, not a toggle in software.
Orbit's surface here is deliberately narrow: tenant-owned controls only. You carry the consent and data-processing records in your own compliance and KYC posture; Orbit stores and moves credentials under encryption but does not mediate Vietnamese legal obligations for your program. The operational rule: document that your ZNS templates and audience sends carry a Decree 13 lawful basis, and keep that basis inside your organization's own compliance file.
7. Walkthrough first Zalo send from the dashboard, plus one Node-SDK snippet
The fastest first send runs from the dashboard: Settings → Channels → Zalo, paste the OA access token, then Messages → Send message → Zalo channel, pick the approved template_name and fill template_params, choose the recipient phone in E.164 digits, send. The message enters the queue as queued, and the delivery receipt reconciles to delivered / failed through the status webhook as it advances.
For a programmatic send, one Node-SDK snippet — the SDK has no typed sendZalo helper yet, so the request routes through the generic request() escape hatch with the channel path:
import { Orbit } from "@devotel-orbit/node";
const orbit = new Orbit({ apiKey: process.env.ORBIT_API_KEY });
const { data } = await orbit.request("POST", "/messages/zalo", {
to: "84901234567",
template_name: "booking_confirmation",
template_params: { name: "Linh", code: "VN-4821" },
});
console.log(data.id); // msg_9f2c1e...
console.log(data.status); // 'queued'The same shape holds for your production integration; the channel path is stable.
8. Common rejection classes and recovery
Recovering sends on Zalo side-steps one of five error paths; each has a tenant-recoverable fix:
| Code | HTTP | Cause | Recovery |
|---|---|---|---|
INVALID_RECIPIENT | 422 | to missing or empty on the send | Supply the recipient phone in E.164 digits |
VALIDATION_ERROR | 422 | template_name missing on a ZNS send (template-only) | Pass an approved ZNS template id |
CHANNEL_NOT_CONFIGURED | 503 | No Zalo credential connected for the organization and no platform default | Connect the OA token under Settings → Channels → Zalo |
MESSAGE_SEND_FAILED | 502 | ZNS rejected the send — expired token, unapproved template, quota | Refresh the OA token, re-submit/repair the template, or align quota with Zalo |
RATE_LIMITED | 429 | Over the 80 requests/minute per-organization Zalo cap | Honor Retry-After; fan bulk sends through the Campaigns API |
Operationally, expired-token and unapproved-template rejections are the two you will see in the early days; both clear through the same two console actions (token rotation, template resubmission) rather than a support ticket.
The takeaway
Zalo's operator routine on Devotel Orbit is compact: one OA credential per organization, three message classes shaped by ZNS templates, a friend-acquisition loop that runs through your own OA growth, threads mixed into the unified inbox, Vietnam's Decree 13/MIC baseline carried in your tenant's own compliance record, and a rejection class list where every path is recoverable from the console or the SDK. The Zalo channel docs carry the field-by-field request reference; this guide tells you how to actually run it day to day. If your Vietnam program runs at volume, route it through Campaigns — the per-minute cap on direct sends makes blast traffic smoother to operate.
Published 1 October 2026.