Skip to main content

Create ZBS Template

This API allows you to create a Zalo Business Solution (ZBS) Template with full display content and dynamic parameters.

Usage flow:

  1. Create the template with this API — the template is saved with status DRAFT and the response returns its _id.
  2. Publish the template with the Publish ZBS Template API to submit it to Zalo for review (PENDING_REVIEW).
  3. Once Zalo approves it (ENABLE), the template can be used to send messages.
Template content is described with contentBlocks

Starting from the latest version, the display content of a template is declared through the contentBlocks array (paragraph, table, voucher, rating) instead of the previous paragraphs and tables fields.


Endpoint

🔗Endpoint Staging
Endpoint
POST https://staging-manage.api.miniai.vn/api/external/zns-template/create
🔗Endpoint Production
Endpoint
POST https://manage-api.miniap.vn/api/external/zns-template/create

Parameters (Request Body)

General information

FieldTypeRequiredDescription
oaIdstringID of the Zalo OA used to send messages. Required before the template can be published.
namestringTemplate name (for internal management).
descriptionstringShort description of the template's purpose.
titlestringTitle shown in the message. Dynamic parameters such as <customer_fullname> can be inserted.
tag"1" | "2" | "3"Template content level — see Template level.
templateTypecustom | voucher | ratingTemplate type — see Template type.
imageTypelogo | imageHeader image style: use a logo or a banner image.
logoLightstringLogo URL for light background. Required when imageType = logo (validated on publish).
logoDarkstringLogo URL for dark background. Required when imageType = logo.
imagesstring[]List of image URLs. At least one image is required when imageType = image.
contentBlocksobject[]Message body content — see contentBlocks.
buttonsobject[]List of buttons, maximum 3 — see buttons.
paramsobject[]Dynamic parameter declarations — see params.
voucherobject⚠️Required when templateType = voucher — see Voucher template.
ratingobject⚠️Required when templateType = rating — see Rating template.
isCustomParamsbooleantrue if you declare the parameters in params yourself; false to use the system's default parameter set.
notestringNote sent to Zalo's review team (explaining the message's use case).
No need to send status

Templates are always created with status DRAFT, even if you include status in the request. Status changes happen through the Publish ZBS Template API.

Template level (tag)

Zalo classifies messages by content level; the level affects review policy and message pricing.

tagLevelSuitable content
"1"TransactionAccount verification, OTP, order/transaction confirmation, balance changes…
"2"Customer careLoyalty point updates, policy updates, opinion surveys, birthday greetings…
"3"Post-saleNew product/service announcements, discount codes and promotions, renewal invitations…

Template type (templateType)

ValueNameDescription
customCustom messageFree-form message: transaction notices, OTP, reminders…
voucherVoucher templateSend a discount code / voucher with conditions and expiry.
ratingRating templateCollect customer feedback after using a product/service.

Message content (contentBlocks)

contentBlocks is an array of content blocks, rendered in the exact order you declare them.

FieldTypeRequiredDescription
idstringUnique identifier of the block (a UUID you generate).
typeparagraph | table | voucher | ratingContent block type.
valuestring⚠️Text content — used by paragraph blocks. Parameters such as <order_code> can be inserted.
rowsobject[]⚠️Table rows — used by table blocks.
voucherobject⚠️Voucher information — used by voucher blocks.
ratingobject⚠️Rating information — used by rating blocks.

Table rows (rows)

FieldTypeRequiredDescription
labelstringLabel shown on the left (e.g. Order code).
keystringValue shown on the right; use <parameter_name> to insert a dynamic parameter.
rowTypenumberRow color effect, defaults to 0.

rowType values:

rowTypeMeaning
0No effect
1Success (green)
2Update (blue)
3Warning (yellow)
4Error (red)
5Basic

Dynamic parameters (params)

Every parameter used in title, a paragraph, or rows must be declared in params.

FieldTypeRequiredDescription
keystringParameter name, without the <> brackets (e.g. order_code).
labelstringDisplay name of the parameter in the editor.
techSettingstringZalo's technical data type — determines review rules and maximum length.
maxLengthnumberMaximum length of the submitted value, matching the techSetting.
sampleValuestringSample value used by Zalo for preview and review.
rowTypenumberColor effect applied to the parameter, defaults to 0.
isFixedbooleantrue if the value is fixed and not passed dynamically when sending.

techSetting values and their maxLength:

techSettingData typemaxLength
"1"Customer name30
"2"Phone number15
"3"Address200
"4"Code (order code, customer code…)30
"5"Custom label30
"6"Transaction status30
"7"Contact information50
"8"Gender / Title5
"9"Product name / Brand200
"10"Quantity / Amount20
"11"Time20
"12"OTP10
"13"URL200
"14"Currency (VND)12
"15"Bank transfer note90
Pick the right techSetting

A parameter without techSetting causes the publish template request to fail with 400. Choosing the wrong technical type (e.g. using Custom label for an amount) is a common reason Zalo rejects a template.


Buttons (buttons)

A maximum of 3 buttons per template.

FieldTypeRequiredDescription
labelstringText shown on the button.
typestringButton action type — see the table below.
valuestringDestination value of the action (URL, phone number, Mini App ID…). Can be an empty string for actions that need no value.
typeAction
"1"Go to the business page
"2"Call (value is a phone number)
"3"Go to the OA information page
"4"Go to the business's Zalo Mini App
"5"Go to the business's app page
"6"Go to the product distribution page
"7"Go to another website / Zalo Mini App
"8"Go to another app
"9"Go to a business article
"10"Go to an app-download call-to-action landing page

Voucher template

When templateType = voucher, the top-level voucher field is required:

FieldTypeDescription
codestringVoucher code (usually a dynamic parameter, e.g. <voucher_code>).
titlestringProgram / offer name.
conditionstringApplicable conditions.
startDatestringStart date of validity.
expiryDatestringExpiry date.
Displayed content lives in contentBlocks

The top-level voucher (and rating) field is used for input validation. What actually renders in the message is the voucher / rating block inside contentBlocks, so declare matching values in both places.

Rating template

When templateType = rating, the top-level rating field is required and contains an items array (at least one element):

FieldTypeDescription
starnumberStar count for that answer scenario (1–5).
titlestringTitle shown for that star level.
questionstringFollow-up question for the customer.
answersstring[]List of suggested answers.
thanksstringThank-you message after the customer rates.
descriptionstringAdditional description.

Request Body examples

{
"oaId": "2288954399991473926",
"name": "Xác nhận đơn hàng",
"description": "Thông báo xác nhận đơn hàng cho khách",
"title": "Xin chào <customer_fullname>,",
"tag": "1",
"templateType": "custom",
"imageType": "logo",
"logoLight": "https://cdn.miniap.vn/zns/logo-light.png",
"logoDark": "https://cdn.miniap.vn/zns/logo-dark.png",
"images": [],
"isCustomParams": true,
"contentBlocks": [
{
"id": "10c8db12-7f66-4b53-a79c-22b5a01dac49",
"type": "paragraph",
"value": "Cảm ơn bạn đã đặt hàng tại cửa hàng. Đơn hàng của bạn đã được xác nhận."
},
{
"id": "6f2b0a54-1f5a-4f0f-9a52-0f5b2b6c7d10",
"type": "table",
"rows": [
{ "label": "Mã đơn hàng", "key": "<order_code>", "rowType": 0 },
{ "label": "Trạng thái", "key": "<order_status>", "rowType": 1 },
{ "label": "Tổng thanh toán", "key": "<order_price>", "rowType": 0 }
]
}
],
"buttons": [
{
"label": "Xem đơn hàng",
"value": "https://manage.miniai.vn/orders",
"type": "1"
}
],
"params": [
{
"key": "customer_fullname",
"label": "Customer fullname",
"techSetting": "1",
"maxLength": 30,
"sampleValue": "Nguyễn Văn A"
},
{
"key": "order_code",
"label": "Order code",
"techSetting": "4",
"maxLength": 30,
"sampleValue": "DH123456"
},
{
"key": "order_status",
"label": "Order status",
"techSetting": "6",
"maxLength": 30,
"sampleValue": "Đã xác nhận"
},
{
"key": "order_price",
"label": "Order price",
"techSetting": "14",
"maxLength": 12,
"sampleValue": "1500000"
}
],
"note": "Mẫu tin gửi khi đơn hàng được xác nhận"
}

Response

{
"template": {
"name": "Xác nhận đơn hàng",
"description": "Thông báo xác nhận đơn hàng cho khách",
"oaId": "2288954399991473926",
"tag": "1",
"templateType": "custom",
"imageType": "logo",
"title": "Xin chào <customer_fullname>,",
"contentBlocks": [
{
"id": "10c8db12-7f66-4b53-a79c-22b5a01dac49",
"type": "paragraph",
"value": "Cảm ơn bạn đã đặt hàng tại cửa hàng. Đơn hàng của bạn đã được xác nhận."
},
{
"id": "6f2b0a54-1f5a-4f0f-9a52-0f5b2b6c7d10",
"type": "table",
"rows": [
{ "label": "Mã đơn hàng", "key": "<order_code>", "rowType": 0 },
{ "label": "Trạng thái", "key": "<order_status>", "rowType": 1 },
{ "label": "Tổng thanh toán", "key": "<order_price>", "rowType": 0 }
]
}
],
"buttons": [
{
"label": "Xem đơn hàng",
"value": "https://manage.miniai.vn/orders",
"type": "1"
}
],
"params": [
{
"key": "customer_fullname",
"label": "Customer fullname",
"techSetting": "1",
"maxLength": 30,
"sampleValue": "Nguyễn Văn A"
},
{
"key": "order_code",
"label": "Order code",
"techSetting": "4",
"maxLength": 30,
"sampleValue": "DH123456"
},
{
"key": "order_status",
"label": "Order status",
"techSetting": "6",
"maxLength": 30,
"sampleValue": "Đã xác nhận"
},
{
"key": "order_price",
"label": "Order price",
"techSetting": "14",
"maxLength": 12,
"sampleValue": "1500000"
}
],
"logoDark": "https://cdn.miniap.vn/zns/logo-dark.png",
"logoLight": "https://cdn.miniap.vn/zns/logo-light.png",
"images": [],
"note": "Mẫu tin gửi khi đơn hàng được xác nhận",
"shopId": "64204a17a5a97a86f12e1f0a",
"status": "DRAFT",
"isSync": false,
"isCustomParams": true,
"_id": "68c8ee675f8f83fc813e7830",
"createdAt": "2025-09-16T04:58:15.668Z",
"updatedAt": "2025-09-16T04:58:15.668Z",
"id": "68c8ee675f8f83fc813e7830"
}
}
Next step

Use the _id from the response as the template_id when calling the Publish ZBS Template API, then look it up again with Get template detail.