Create News
This API lets you create a new news article in the system. You must provide a title and content; you can also optionally attach images and call-to-action (CTA) buttons linking to your Zalo Mini App.
Endpoint
http POST https://staging-manage.api.miniai.vn/api/external/news
http POST https://manage-api.miniap.vn/api/external/news
The news API sits directly under /api/external/news, without the /v1 prefix used by the product and order APIs.
Authentication
Every request must include your API key in the header:
| Header | Value | Required |
|---|---|---|
x-api-key | miniai-partner <YOUR_API_KEY> | Bắt buộc |
Content-Type | application/json | Bắt buộc |
The system automatically determines your shop (shopId) from your API key and assigns it to the request.
So you don't need to send shopId in the body. If you do send it, that value will be overwritten
with the shop matching your API key — you cannot create news for another shop.
Request Body
Parameters
Only type, title, and content are required. All other fields are optional.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | Bắt buộc | — | Must be present. The system always stores news — send "news". |
title | string | Bắt buộc | — | The article title. Used to generate the slug. |
content | string | Bắt buộc | — | The article content, HTML supported. |
images | string[] | Tùy chọn | — | List of image URLs for the article. |
cta | object[] | Tùy chọn | — | List of call-to-action buttons (see table below). |
shortContent | string | Tùy chọn | — | Accepted but ignored — auto-generated from content. |
status | string | Tùy chọn | active | Accepted but ignored — news is always created as active. |
Each element in cta[]
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Bắt buộc | Button label (e.g. "Buy now") |
url | string | Bắt buộc | Button destination. Must match https://zalo.me/s/... |
cta[].url only accepts Zalo Mini App links in the format https://zalo.me/s/<app-id>/<path>.
Any other URL (including regular https:// websites) will be rejected with a 400 error.
Fields handled automatically
slug— auto-generated fromtitle, with Vietnamese diacritics stripped and joined with-. The slug is unique per shop: if it collides, the system appends a suffix-2,-3, ... (e.g.khuyen-mai-thang-10→khuyen-mai-thang-10-2).shortContent— auto-generated by stripping HTML tags fromcontentand taking the first 100 characters.status— alwaysactiveon creation.shopId— taken from the API key.
This API's body does not accept slug, metaDescription, or categoryId. Sending them returns a 400 error
(e.g. "slug" is not allowed). If you need to set a custom slug or metaDescription, create the news article
first, then call Update News.
- Request Body
- cURL (Staging)
- cURL (Production)
{
"type": "news",
"title": "October Promotion",
"content": "<p>50% off <strong>everything</strong> from 10/01 to 10/31.</p>",
"images": [
"https://dmcl0k8mc5oht.cloudfront.net/64204a17a5a97a86f12e1f0a/e888246f-2647-42f1-9d89-53eacdb7bf64.webp"
],
"cta": [
{
"name": "Buy now",
"url": "https://zalo.me/s/1234567890/products"
}
]
}
curl -X POST 'https://staging-manage.api.miniai.vn/api/external/news' \
-H 'x-api-key: miniai-partner <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"type": "news",
"title": "October Promotion",
"content": "<p>50% off <strong>everything</strong> from 10/01 to 10/31.</p>",
"images": [
"https://dmcl0k8mc5oht.cloudfront.net/64204a17a5a97a86f12e1f0a/e888246f-2647-42f1-9d89-53eacdb7bf64.webp"
],
"cta": [
{ "name": "Buy now", "url": "https://zalo.me/s/1234567890/products" }
]
}'
curl -X POST 'https://manage-api.miniap.vn/api/external/news' \
-H 'x-api-key: miniai-partner <YOUR_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"type": "news",
"title": "October Promotion",
"content": "<p>50% off <strong>everything</strong> from 10/01 to 10/31.</p>",
"images": [
"https://dmcl0k8mc5oht.cloudfront.net/64204a17a5a97a86f12e1f0a/e888246f-2647-42f1-9d89-53eacdb7bf64.webp"
],
"cta": [
{ "name": "Buy now", "url": "https://zalo.me/s/1234567890/products" }
]
}'
Response
Success returns 200 with the full created news record in data.
- Response
{
"success": true,
"data": {
"type": "news",
"title": "October Promotion",
"slug": "october-promotion",
"shortContent": "50% off everything from 10/01 to 10/31.",
"content": "<p>50% off <strong>everything</strong> from 10/01 to 10/31.</p>",
"status": "active",
"shopId": "64204a17a5a97a86f12e1f0a",
"images": [
"https://dmcl0k8mc5oht.cloudfront.net/64204a17a5a97a86f12e1f0a/e888246f-2647-42f1-9d89-53eacdb7bf64.webp"
],
"cta": [
{
"name": "Buy now",
"url": "https://zalo.me/s/1234567890/products"
}
],
"itemIds": [],
"_id": "68c93dba802d36826bc45c9c",
"createdAt": "2025-09-16T10:36:42.809Z",
"updatedAt": "2025-09-16T10:36:42.809Z",
"__v": 0,
"id": "68c93dba802d36826bc45c9c"
}
}
Fields in data
| Field | Type | Description |
|---|---|---|
id / _id | string | News article ID — used for update, delete, and product-linking APIs |
type | string | Always news |
title | string | Article title |
slug | string | Friendly URL path, unique per shop |
shortContent | string | Auto-generated summary (first 100 characters of plain-text content) |
content | string | Full HTML content |
status | string | active or inactive |
shopId | string | Shop ID, taken from the API key |
images | string[] | List of image URLs |
cta | object[] | List of call-to-action buttons |
itemIds | string[] | List of related product IDs (empty by default) |
createdAt | string | Creation time (ISO 8601) |
updatedAt | string | Last update time (ISO 8601) |
Common Errors
| Code | Cause |
|---|---|
400 | Missing required field, wrong data type, cta[].url not in the Zalo format, or a disallowed field was sent (slug, metaDescription, categoryId) |
401 | Missing x-api-key header, wrong miniai-partner prefix, or invalid API key |
429 | Rate limit exceeded (see the Rate Limit section below) |
500 | System error |
- 400 Error - Validation
- 429 Error - Rate Limited
{
"statusCode": 400,
"error": "Bad Request",
"message": "Validation failed",
"validation": {
"body": {
"source": "body",
"keys": ["title"],
"message": "\"title\" is required"
}
}
}
{
"error": "Too many requests, limit to 100 requests per minute"
}
Rate Limit
Each shop can make at most 100 requests per minute across the entire External API.
Exceeding this limit returns a 429 status.
Next Steps
After successfully creating a news article, save data.id to use for:
- Update News — edit content, set
slug,metaDescription, or changestatus - Add Related Products to News — attach products to the article
- Get News List — verify the article you just created