Template-only Asia channels: the send playbook
Four of Orbit’s Asia messaging channels — WeChat, Zalo, KakaoTalk Alimtalk, and anything routed through Meta (Messenger, Instagram) — reject free-form text until it rides an approved template or a Metamessaging_type tag. LINE and Telegram accept a free-form body. Pick wrong and the send fails at validation with 422 VALIDATION_ERROR before it ever reaches the provider.
This playbook is the one conceptual source the per-channel pages link back to: which channels demand a template, how the same request body moves across template channels with only the path swapped, what the 422 branch means, one receiver for all inbound traffic, and how to bulk-send templates through campaigns.
1. Which channels demand a template
For Messenger and Instagram, “template” is a Meta concept, not an Orbit pre-approval: outside the 24-hour customer-service window the send must carry a Meta messaging tag (for example
POST_UPDATE or ACCOUNT_UPDATE) via the messaging_type metadata, and the recipient is only reachable if that tag’s policy allows it. See the per-channel pages for the exact tag surface.2. Decision tree: one body, swap the channel
The template-only channels share the same request body shape. The only differences are the endpoint path and whatto holds:
- Recipient is a phone number (E.164 digits), template lives on Zalo? →
/messages/zalo. - Recipient is a phone number, template lives on KakaoTalk, any recipient (follower or not)? →
/messages/kakaowith an approved Alimtalk code (via a campaign — see §5), or withmetadata.kakao_message_type: "friendtalk"plus abodywhen the recipient added your channel as a friend. - Recipient is a WeChat
openidcaptured from an inbound follow? →/messages/wechat. - You hold no approved template at all → you are on the wrong channel; switch to LINE or Telegram and send a free-form
body, or get a template approved first.
openid in to, so run its swap with a real follower id — the shape point stands: to, template_name, template_params is the whole contract for every template-only channel.)
KakaoTalk’s free-form variant is the same endpoint with metadata selecting the type:
3. Why a template send returns 422
Template-only channels validate before the provider is contacted. Two distinct rejections:422 VALIDATION_ERRORwith notemplate_name— ZNS and OA messaging are template-only, so a body-only send is refused at the API. This is the optimistic gate: the 422 carries no provider round trip, so it costs nothing and returns immediately.CHANNEL_NOT_CONFIGURED(503) — the channel has no connected credentials and no platform default; fix this first, template questions come after.
MESSAGE_SEND_FAILED (502) with the upstream errcode — an unapproved or mistyped template name is the most common cause. Avoid it the same way the WhatsApp template recipe does: list your approved templates (GET /api/v1/templates), copy the exact approved name, and treat the approved-name cache as your source of truth rather than retyping names at each call site. (Meta’s equivalent rejection is WHATSAPP_TEMPLATE_NOT_FOUND when the name or language.code does not match an approved template.)
The error branch, per channel — the same pattern the per-channel pages document:
template_name (or, for KakaoTalk, either the approved Alimtalk code or a friendtalk body). The full per-channel error tables live on the Zalo, WeChat, and KakaoTalk pages.
4. One receiver for all inbound traffic
Inbound replies from every Asia channel arrive on the samemessage.received webhook with the normalized envelope — subscribe once under Settings → Webhooks and route on data.channel. The full envelope shape is documented under Normalized inbound event envelope; the receiver below is the whole handler for WeChat, Zalo, KakaoTalk, LINE, and Telegram.
data.from on your contact record — on WeChat it is the follower’s openid, and you need it as to for every outbound template send.
5. Bulk send via campaigns
LoopingPOST /messages/<channel> per recipient works, but the campaigns API is the intended bulk path and the only path for KakaoTalk Alimtalk (the direct endpoint only carries Friendtalk). Submit one campaign and the fan-out is one templated send per recipient, reusing the same template_name / template_params contract as the direct endpoints:
draft; launch it with POST /api/v1/campaigns/{id}/send and each recipient’s delivery advances to queued from there. For WeChat and Zalo the same pattern holds — swap channel and the approved template name. Full parameter reference: Campaigns API.
6. Per-channel references
This playbook covers the shared template contract once. For per-channel quirks — credential fields, rate limits, provider-specific error codes, KakaoTalk’s Friendtalk/Alimtalk split, WeChat’s H5 deep-link — go to the channel page:- Zalo — ZNS templates, E.164 recipients
- WeChat — OA templates,
openidrecipients, optionalmetadata.urldeep-link - KakaoTalk — Alimtalk vs Friendtalk, message-type metadata
- LINE — free-form bodies, profile sender
- Telegram — free-form bodies