Trang này liệt kê toàn bộ endpoint /public/v1/* — đủ để dựng một website Next.js hoặc ứng dụng React Native mà không cần truy cập trực tiếp cơ sở dữ liệu.

Xác thực

Mọi request đều gửi kèm header X-Xstore-Key:

curl -H "X-Xstore-Key: pk_live_..." \
  "https://api.xstore.vn/public/v1/products?limit=12"

Khoá tạo trong trang quản trị Cài đặt → Khoá API. Khoá này công khai theo thiết kế: nó chỉ mở ra dữ liệu vốn đã công khai, và bản dựng Next.js hay ứng dụng di động của bạn sẽ gửi nó tới mọi khách truy cập. Điều đó là bình thường — đừng cố giấu nó. Khoá bị lộ hay dùng sai thì thu hồi, không cần đổi tên miền hay tài khoản.

Khoá xác định cửa hàng, nên bạn không cần header Host — đó là lý do ứng dụng di động gọi thẳng api.xstore.vn được.

Có hai loại khoá và chúng không thay thế cho nhau.

Khoá Lấy ở Dùng cho Bí mật?
pk_live_… Cài đặt → Khoá API đọc dữ liệu công khai qua /public/v1 (trang này) không — gửi tới mọi khách
sk_live_… Nhà phát triển → Khoá API API quản trị, và xstore theme để dựng giao diện Liquid có — đừng commit, đừng đưa vào mã client

Khoá sk_live_ gửi ở header Authorization: Bearer sk_live_… và chỉ làm được đúng những quyền bạn tick khi tạo. Xem Phát triển trên máy để dùng nó với giao diện Liquid.

Phân trang

Mọi endpoint danh sách trả về cùng một phong bì:

{ "items": [ ... ], "next_cursor": "2026-08-01 12:00:00|p001", "has_more": true }

Gửi lại next_cursor ở lần gọi sau. next_cursor là null khi đã hết dữ liệu.

Hai quy ước dễ sai

url là đường dẫn dùng được, hoặc null — không bao giờ tự ghép. Nếu url là null, hãy hiển thị chữ thường, đừng tạo thẻ <a>. Tự ghép /san-pham/{slug} sẽ tạo ra liên kết chết ngay khi cửa hàng đổi cấu trúc URL. Ngoại lệ duy nhất là bài viết: bài viết không có cột url, đường dẫn luôn là /bai-viet/<slug>.

Số tiền là số nguyên VND. Một vài trường (discount_value) trả về dạng chuỗi — hãy ép kiểu trước khi so sánh.

Base URL: https://api.xstore.vn/public/v1
Header bắt buộc: X-Xstore-Key

Endpoint đọc

Endpoint Mô tả Tham số
GET /article-categories Danh mục bài viết.
GET /article-tags Toàn bộ thẻ bài viết đang dùng.
GET /articles Danh sách bài viết đã xuất bản, mới nhất trước. limit, cursor, category, tag
GET /articles/by-slug/{slug} Chi tiết bài viết, kèm nội dung HTML, danh mục và thẻ.
GET /articles/{article_id}/related Bài viết liên quan (cùng danh mục). limit
GET /banners Banner theo vị trí, tôn trọng lịch hiển thị. location_code, limit
GET /categories Danh mục cấp cao nhất, hoặc danh mục con của parent. parent, limit
GET /categories/by-slug/{slug} Chi tiết danh mục theo đường dẫn (slug).
GET /categories/tree Cây danh mục hai cấp — dùng dựng menu điều hướng.
GET /categories/{category_id} Chi tiết danh mục theo id.
GET /categories/{category_id}/breadcrumb Đường dẫn phân cấp, từ gốc xuống.
GET /categories/{category_id}/subcategories Danh mục con trực tiếp.
GET /collections Danh sách bộ sưu tập đang hiển thị. limit
GET /collections/by-slug/{slug} Chi tiết bộ sưu tập theo đường dẫn (slug).
GET /custom-variables Biến tuỳ chỉnh của cửa hàng (tương ứng biến custom trong Liquid).
GET /filters Bộ lọc (thương hiệu, thuộc tính, khoảng giá) mà cửa hàng đã cấu hình cho danh mục. category
GET /flash-sales Các chương trình giảm giá đang chạy. limit
GET /flash-sales/{sale_id} Chi tiết một chương trình giảm giá.
GET /flash-sales/{sale_id}/products Sản phẩm trong chương trình — trả về đầy đủ thẻ sản phẩm kèm giá đã giảm. limit
GET /menus Toàn bộ menu điều hướng, kèm cấu trúc mục con.
GET /pages/by-slug/{slug} Trang nội dung theo đường dẫn (slug).
GET /pages/{page_id} Trang nội dung theo id — dùng khi routes/resolve trả về cms_page.
GET /products Danh sách sản phẩm, phân trang bằng con trỏ. Lọc theo danh mục, bộ sưu tập hoặc danh sách id. limit, cursor, category, collection, ids, q, sort
GET /products/by-slug/{slug} Chi tiết sản phẩm theo đường dẫn (slug).
GET /products/{product_id} Chi tiết sản phẩm theo id.
GET /products/{product_id}/related Sản phẩm liên quan (cùng danh mục). limit
GET /products/{product_id}/variants Danh sách biến thể đang bán của một sản phẩm.
GET /promotions Khuyến mãi dạng văn bản đang hiển thị.
GET /routes/resolve Phân giải một đường dẫn do cửa hàng tự đặt thành thực thể đích. Trả 404 nếu không khớp. path
GET /sitemap Danh sách phân khu sitemap và số dòng của mỗi phân khu.
GET /sitemap/{section} Một trang dữ liệu sitemap. Trả về ĐƯỜNG DẪN, không phải XML — phần sinh XML thuộc về client. limit, cursor
GET /store Thông tin cửa hàng: tên, logo, liên hệ, mạng xã hội, mã tiền tệ.

Endpoint gắn thêm từ /public/*

Cùng một handler, hai đường dẫn. Chữ ký chi tiết xem trang xStore JS.

Endpoint Mô tả Tham số
DELETE /customer/addresses/{address_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
DELETE /customer/reviews/{review_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
DELETE /customer/saved-products/{product_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /cart Bản /v1 của một route /public/* đã có. Xem sdk.yaml. token
GET /cart/quote Bản /v1 của một route /public/* đã có. Xem sdk.yaml. token, coupon_code
GET /checkout/payment-methods Các cổng thanh toán cửa hàng này thực sự nhận được (COD luôn đứng đầu).
GET /customer/addresses Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /customer/contacts/ Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /customer/contacts/{contact_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /customer/coupons Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /customer/me Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /customer/me/points Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /customer/orders Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /customer/orders/{order_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /customer/product-views Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /customer/reviews/ Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /customer/saved-products Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cursor, limit
GET /pickup-locations Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /recommendations/product/{product_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml. rule_type, limit
GET /recommendations/recently-viewed Bản /v1 của một route /public/* đã có. Xem sdk.yaml. customer_id, session_token, limit
GET /shipping/provinces Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /shipping/wards Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
GET /reviews/ Bản /v1 của một route /public/* đã có. Xem sdk.yaml. entity_type, entity_id, cursor, limit
GET /search Bản /v1 của một route /public/* đã có. Xem sdk.yaml. q, limit, cursor, category_id, brand_id
GET /search/content Bản /v1 của một route /public/* đã có. Xem sdk.yaml. q, entity_type, limit, cursor
GET /storefront/settings Bản /v1 của một route /public/* đã có. Xem sdk.yaml. Tham số tenant_id là TUỲ CHỌN và chỉ còn dành cho storefront.vn; SDK không gửi nó vì khoá X-Xstore-Key đã xác định cửa hàng. tenant_id
GET /warehouses Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
PATCH /customer/addresses/{address_id} Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
PATCH /customer/me Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /analytics/entity-view Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /banners/{banner_id}/click Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /cart/merge Bản /v1 của một route /public/* đã có. Xem sdk.yaml. token
POST /checkout Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cart_token
POST /checkout/payment-return Kiểm tra chữ ký của lượt chuyển hướng từ cổng thanh toán. CHỈ ĐỌC — IPN mới là nguồn quyết định. Thân yêu cầu: query_string là payload THÔ (query string cho GET, body thô cho POST); provider là TUỲ CHỌN từ 2026-09-01 — bỏ trống thì máy chủ tự nhận diện cổng trong số các cổng gian hàng đã kết nối.
POST /checkout/pay Khởi tạo thanh toán qua cổng cho đơn đã đặt của giỏ này; trả về URL chuyển hướng. cart_token
POST /checkout/place-order Bản /v1 của một route /public/* đã có. Xem sdk.yaml. cart_token
POST /checkout/{checkout_id}/payment Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/addresses Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/addresses/{address_id}/default Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /contacts Gửi tin nhắn hỗ trợ mà không cần đăng nhập. Tenant lấy từ Host hoặc X-Xstore-Key.
POST /customer/contacts/ Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/login Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/me/password Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/product-views Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/register Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/reviews/ Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /customer/saved-products Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /recommendations/view Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /shipping-methods Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
POST /storefront-errors Ghi nhận một lô sự kiện lỗi 4xx/5xx từ storefront. Không cần đăng nhập; tối đa 50 sự kiện/lần. occurred_at bị giới hạn trong 24 giờ gần nhất và không được ở tương lai — giá trị ngoài khoảng bị thay bằng thời điểm nhận.
PUT /cart/items Bản /v1 của một route /public/* đã có. Xem sdk.yaml. token
PUT /checkout/{checkout_id}/address Bản /v1 của một route /public/* đã có. Xem sdk.yaml.
PUT /checkout/{checkout_id}/shipping Bản /v1 của một route /public/* đã có. Xem sdk.yaml.