SFI External API — Báo cáo phân tích
Danh mục báo cáo, danh mục sản phẩm, danh sách và chi tiết báo cáo phân tích cho ứng dụng đối tác — không cần đăng nhập khách hàng, chỉ xác thực bằng X-Api-Key.
https://a.sfi.com.vn/ekyc/ex_apiChínhhttps://b.sfi.com.vn/ekyc/ex_apiDự phòngTổng quan
Toàn bộ endpoint trong tài liệu này nằm trong entry point /ekyc/ex_api, dùng chung quy ước
?cmd={tên_lệnh} và chung khung phản hồi JSON. Khác với nhóm API giao dịch
(open_position, account_status…), các API ở đây không cần JWT và không gắn với tài khoản khách hàng nào.
Phần Tổng quan → Mã lỗi chung dùng chung cho mọi nhóm API công khai của /ekyc/ex_api;
phần riêng của nhóm này (tham số, cấu trúc dữ liệu, lưu ý nghiệp vụ) nằm ở khối bên dưới.
Danh mục endpoint
| Nhóm | Endpoint | Mô tả | Xác thực |
|---|---|---|---|
| 1 · Báo cáo phân tích | GET ?cmd=news_categories | Danh mục báo cáo + số báo cáo, dùng dựng bộ lọc cate |
X-Api-Key |
| 1 · Báo cáo phân tích | GET ?cmd=news_products | Danh mục sản phẩm, dùng dựng bộ lọc productslug |
X-Api-Key |
| 1 · Báo cáo phân tích | GET ?cmd=news | Danh sách báo cáo, lọc theo danh mục / sản phẩm / tháng | X-Api-Key |
| 1 · Báo cáo phân tích | GET ?cmd=news&id=… | Chi tiết một báo cáo (kèm content HTML) |
X-Api-Key |
Danh mục này là nguồn tra cứu nhanh của nhóm Báo cáo phân tích — mỗi endpoint có một mục mô tả chi tiết bên dưới.
Xác thực bằng API Key
Mọi request phải gửi kèm header:
X-Api-Key: {api_key_được_SFI_cấp}
Nếu thiếu hoặc sai key, server trả về HTTP 401 với body
{"success": false, "message": "Unauthorized."}.
Key được cấp riêng cho từng ứng dụng đối tác; vui lòng lưu ở phía server, không nhúng vào ứng dụng client.
X-Api-Key dùng chung cho tất cả nhóm API trong tài liệu này, và cũng chính là key dùng
cho guestcmd=login_request ở luồng OOB Auth.
Định dạng phản hồi
Toàn bộ API dùng chung khung phản hồi JSON của hệ thống SFI:
{
"success": true,
"message": "Thành công!",
"data": [ ... ],
"svr": "srv-01"
}
| Trường | Kiểu | Mô tả |
|---|---|---|
| success | boolean | Kết quả xử lý |
| message | string | Thông điệp (tiếng Việt) |
| data | array / object | Dữ liệu trả về. Rỗng ([]) khi lỗi; vắng mặt ở phản hồi lỗi xác thực JWT — xem Mã lỗi chung |
| svr | string | Định danh máy chủ xử lý (dùng khi báo lỗi) |
Mã lỗi chung
| HTTP | message | Nguyên nhân |
|---|---|---|
| 401 | Unauthorized. | Thiếu header X-Api-Key hoặc key không hợp lệ |
| 200 | [IAH] Phiên làm việc đã hết hạn. Vui lòng đăng nhập lại! | cmd không thuộc nhóm API công khai, hoặc gọi bằng phương thức khác GET — request rơi vào nhánh yêu cầu JWT. Phản hồi này không có khóa data. |
| 200 | (tuỳ nghiệp vụ) | Lỗi nghiệp vụ — xem success: false và message |
200 với
success: false. Client luôn phải kiểm tra trường success, không
chỉ dựa vào HTTP status. Mã lỗi riêng của nhóm này được liệt kê ở cuối khối bên dưới.
Báo cáo phân tích
Danh mục báo cáo, danh mục sản phẩm, danh sách và chi tiết báo cáo phân tích. Nguồn dữ liệu là kho báo cáo của SFI, đồng bộ tự động từ website.
1 · Danh mục báo cáo
?cmd=news_categories
Trả về mọi danh mục đang có báo cáo, kèm số báo cáo, sắp xếp theo tên. Dùng để dựng danh sách
chọn cho bộ lọc cate. Danh mục chưa gắn với báo cáo nào sẽ không xuất hiện.
Không có tham số.
Request
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=news_categories' \
-H 'X-Api-Key: YOUR_API_KEY'
Response
{
"success": true,
"message": "Thành công",
"data": [
{ "id": 71, "slug": "duong", "name": "Đường", "count": 128 },
{ "id": 88, "slug": "kim-loai-quy", "name": "Kim loại quý", "count": 54 },
{ "id": 63, "slug": "phan-tich-chuyen-sau","name": "Phân tích chuyên sâu", "count": 316 }
],
"svr": "srv-01"
}
| Trường | Kiểu | Mô tả |
|---|---|---|
| id | int | Mã danh mục |
| slug | string | Giá trị truyền cho tham số cate |
| name | string | Tên hiển thị |
| count | int | Số báo cáo thuộc danh mục |
Thử ngay — ?cmd=news_categories
Khóa categories trong mỗi báo cáo
Mỗi báo cáo được gán vào một hoặc nhiều
danh mục trên hệ thống nội dung của SFI (ví dụ Phân tích chuyên sâu, Vĩ mô,
Đường, Kim loại quý). Danh sách này trả về ở khóa categories của cả API danh
sách lẫn API chi tiết, theo đúng thứ tự đã cấu hình:
"categories": [
{ "id": 63, "slug": "phan-tich-chuyen-sau", "name": "Phân tích chuyên sâu" },
{ "id": 71, "slug": "duong", "name": "Đường" }
]
| Trường | Kiểu | Mô tả |
|---|---|---|
| id | int | Mã danh mục. Ổn định, không đổi khi đổi tên. |
| slug | string | Giá trị dùng cho tham số cate. Có thể rỗng trong trường hợp hiếm (danh mục vừa tạo, chưa đồng bộ được tên) — khi đó lọc theo slug sẽ không khớp báo cáo đó. |
| name | string | Tên hiển thị tiếng Việt. |
Lọc theo danh mục
Tham số cate nhận một hoặc nhiều slug ngăn cách bằng dấu phẩy. Nhiều slug hiểu theo
HOẶC:
# một danh mục
?cmd=news&cate=vi-mo
# hai danh mục — báo cáo thuộc BẤT KỲ danh mục nào trong hai
?cmd=news&cate=phan-tich-chuyen-sau,vi-mo
# kết hợp với các bộ lọc khác: giữa các THAM SỐ là VÀ
?cmd=news&cate=kim-loai-quy&productslug=bac&modified=08-2026
Nói cách khác: trong cate là HOẶC, giữa cate với
productslug / modified là VÀ. Hiện chưa hỗ trợ yêu cầu
"báo cáo phải thuộc đủ nhiều danh mục" (VÀ trong cùng cate) — cần thì báo SFI.
cate, hệ thống xét
20.000 báo cáo mới nhất của các danh mục đó. Với size tối đa 100 thì tương
đương 200 trang — quá mốc này kết quả sẽ rỗng. Cần lấy toàn bộ kho lịch sử của một danh mục thì hãy
thu hẹp thêm bằng modified theo từng tháng.
2 · Danh sách sản phẩm (bộ lọc)
?cmd=news_products
Trả về bản đồ sản phẩm SFI dùng để gắn sản phẩm cho báo cáo. Kết quả dùng để dựng danh sách chọn cho
tham số productslug ở API danh sách báo cáo.
Request
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=news_products' \
-H 'X-Api-Key: YOUR_API_KEY'
Response
{
"success": true,
"message": "Thành công",
"data": [
{
"name": "Kim loại",
"subs": [
{ "slug": "bac", "name": "Bạc" },
{ "slug": "bach-kim", "name": "Bạch kim" },
{ "slug": "dong-lme", "name": "Đồng LME" }
]
},
{
"name": "Năng lượng",
"subs": [
{ "slug": "dau-brent", "name": "Dầu Brent" }
]
}
],
"svr": "srv-01"
}
| Trường | Kiểu | Mô tả |
|---|---|---|
| name | string | Tên nhóm sản phẩm — trùng với productgroup của báo cáo |
| subs | array | Danh sách sản phẩm trong nhóm |
| subs[].name | string | Tên sản phẩm — trùng với product của báo cáo |
| subs[].slug | string | Giá trị dùng cho tham số productslug ở API danh sách báo cáo |
Kim loại (18 sản phẩm),
Năng lượng (9), Nguyên liệu công nghiệp (9), Nông sản (10).
Ví dụ trên đã được rút gọn.
Thử ngay — ?cmd=news_products
Không có tham số.
3 · Danh sách báo cáo
?cmd=news
Trả về danh sách báo cáo theo trang, sắp xếp mới nhất trước.
Trường content không có trong danh sách — gọi API chi tiết để lấy nội dung.
Tham số truy vấn
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
| productslug | string | Không | — | Lọc theo sản phẩm, lấy từ cmd=news_products. Chỉ khớp báo cáo có gắn sản phẩm. |
| cate | string | Không | — |
Lọc theo danh mục của báo cáo — xem mục 1.
Một slug (cate=phan-tich-chuyen-sau) hoặc nhiều slug ngăn cách bằng
dấu phẩy (cate=phan-tich-chuyen-sau,vi-mo). Nhiều giá trị hiểu theo
HOẶC: báo cáo thuộc bất kỳ danh mục nào trong danh sách đều được trả về.
Tối đa 20 slug mỗi lần gọi, phần dư bị bỏ. Slug không tồn tại thì đơn giản là
không khớp báo cáo nào (không phải lỗi).
|
| modified | string MM-YYYY | Không | — | Lọc theo tháng đăng, ví dụ 08-2026. Hệ thống đối chiếu theo ngày tạo báo cáo. |
| page | int | Không | 1 | Trang, bắt đầu từ 1. Giá trị < 1 được đưa về 1. |
| size | int | Không | 10 | Số bản ghi mỗi trang, tối đa 100. Giá trị lớn hơn bị giới hạn về 100. |
data rỗng, hoặc
số phần tử trả về nhỏ hơn size.
Request
# Mới nhất, trang 1, 20 bản ghi
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=news&page=1&size=20' \
-H 'X-Api-Key: YOUR_API_KEY'
# Sản phẩm "bac" trong tháng 08/2026
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=news&productslug=bac&modified=08-2026' \
-H 'X-Api-Key: YOUR_API_KEY'
# Báo cáo thuộc danh mục "phan-tich-chuyen-sau" HOẶC "vi-mo"
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=news&cate=phan-tich-chuyen-sau,vi-mo&size=20' \
-H 'X-Api-Key: YOUR_API_KEY'
Response — báo cáo không gắn sản phẩm
{
"success": true,
"message": "Thành công!",
"data": [
{
"id": 60730,
"title": "LƯỢNG MÍA NGHIỀN CUỐI THÁNG 7 TẠI BRAZIL SUY GIẢM",
"thumb": "https://img.saigonfutures.com/2026/08/ava-chiu-1808.jpg",
"excerpt": "I. ĐƯỜNG 1. Diễn biến thị trường phiên giao dịch ngày 17/08/2026 ...",
"created": "2026-08-18T11:23:17",
"modified": "18/08/2026 11:23",
"categories": [
{ "id": 63, "slug": "phan-tich-chuyen-sau", "name": "Phân tích chuyên sâu" },
{ "id": 71, "slug": "duong", "name": "Đường" }
]
}
],
"svr": "srv-01"
}
Response — báo cáo gắn sản phẩm
{
"success": true,
"message": "Thành công!",
"data": [
{
"id": 60727,
"title": "PHÂN TÍCH HỢP ĐỒNG TƯƠNG LAI BẠCH KIM KỲ HẠN THÁNG 5/2026",
"thumb": "https://img.saigonfutures.com/2026/08/pl188.png",
"excerpt": "NHẬN ĐỊNH XU HƯỚNG: Xu hướng Trung hạn: Tăng. ...",
"created": "2026-08-18T09:59:13",
"modified": "18/08/2026 09:59",
"product": "Bạch kim",
"productslug": "bach-kim",
"productcode": "PLEV26",
"productgroup": "Kim loại",
"categories": [
{ "id": 88, "slug": "kim-loai-quy", "name": "Kim loại quý" }
]
}
],
"svr": "srv-01"
}
Thử ngay — ?cmd=news
4 · Chi tiết báo cáo
?cmd=news&id={id}
Cùng cmd=news; khi có tham số id khác rỗng, API chuyển sang chế độ chi
tiết và bỏ qua mọi tham số lọc / phân trang. Gửi id= rỗng thì API vẫn trả
về danh sách như bình thường.
| Tham số | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
| id | int | Có | Mã báo cáo, lấy từ trường id của API danh sách. |
Request
curl 'https://a.sfi.com.vn/ekyc/ex_api?cmd=news&id=40231' \
-H 'X-Api-Key: YOUR_API_KEY'
Response
{
"success": true,
"message": "Thành công!",
"data": {
"id": 60730,
"title": "LƯỢNG MÍA NGHIỀN CUỐI THÁNG 7 TẠI BRAZIL SUY GIẢM",
"thumb": "https://img.saigonfutures.com/2026/08/ava-chiu-1808.jpg",
"content": "<h2><span><strong>I. ĐƯỜNG</strong></span></h2> <p>1. Diễn biến thị trường ...</p> ...",
"excerpt": "I. ĐƯỜNG 1. Diễn biến thị trường phiên giao dịch ngày 17/08/2026 ...",
"created": "2026-08-18T11:23:17",
"modified": "18/08/2026 11:23",
"product": "",
"productslug": "",
"productcode": "",
"productgroup": "",
"categories": [
{ "id": 63, "slug": "phan-tich-chuyen-sau", "name": "Phân tích chuyên sâu" },
{ "id": 71, "slug": "duong", "name": "Đường" }
]
},
"svr": "srv-01"
}
Thử ngay — ?cmd=news
Cùng cmd=news, chỉ khác là truyền id.
5 · Trường dữ liệu báo cáo
| Trường | Kiểu | Có ở danh sách | Mô tả |
|---|---|---|---|
| id | int | Có | Mã báo cáo (dùng cho API chi tiết) |
| title | string | Có | Tiêu đề đã lược bỏ tiền tố phân loại |
| excerpt | string | Có | Tóm tắt, thuần văn bản. Thường kết thúc bằng ... |
| content | string (HTML) | Không | Nội dung đầy đủ — chỉ có ở API chi tiết. HTML thuần: đã gỡ mọi thuộc tính và thẻ bọc bố cục, riêng <img> giữ lại src |
| thumb | string (URL) | Có | Ảnh đại diện |
| created | string Y-m-d\TH:i:s | Có | Thời điểm đăng (giờ Việt Nam) |
| productcode | string | Có (nếu gắn sản phẩm) | Mã hợp đồng, ví dụ PLEV26 |
| product | string | Có (nếu gắn sản phẩm) | Tên sản phẩm |
| productgroup | string | Có (nếu gắn sản phẩm) | Nhóm sản phẩm |
| productslug | string | Có (nếu gắn sản phẩm) | Slug dùng cho tham số lọc |
| categories | array | Có | Danh mục báo cáo được gán trên hệ thống nội dung — xem mục 1. Luôn có mặt; báo cáo chưa gán danh mục nào thì là mảng rỗng [] |
- Danh sách · báo cáo không gắn sản phẩm:
id, title, thumb, excerpt, created, modified, categories— không có nhóm trường sản phẩm. - Danh sách · báo cáo gắn sản phẩm: như trên, có thêm
product, productslug, productcode, productgroup. - Chi tiết: luôn có đủ nhóm trường sản phẩm (giá trị rỗng nếu báo cáo không gắn sản phẩm) và thêm
content. categoriescó ở mọi báo cáo và ở cả danh sách lẫn chi tiết; báo cáo chưa gán danh mục nào thì là[].
Mã lỗi riêng của nhóm
| HTTP | message | Nguyên nhân |
|---|---|---|
| 404 | Không tìm thấy báo cáo. | id không tồn tại (kèm data: []) |
Lưu ý tích hợp
- Gọi API từ máy chủ của đối tác, không gọi trực tiếp từ trình duyệt / app để tránh lộ API Key.
- Luôn kiểm tra
successtrước khi đọcdata; ghi lạisvrkhi cần báo lỗi cho SFI. - Cache dữ liệu ít thay đổi (ví dụ
news_products) và đặt TTL tối thiểu 1–5 phút cho dữ liệu danh sách. - Đồng bộ tăng dần bằng cách lưu
idlớn nhất đã lấy và dừng khi gặp lạiidđó. - Tôn trọng giới hạn phân trang (
size≤ 100) thay vì kéo toàn bộ kho dữ liệu trong một lần. - Đặt timeout hợp lý (5–10s) và retry có backoff; nếu domain chính chậm > 5s, chuyển sang domain dự phòng.
Ví dụ code
Hàm gọi chung dưới đây dùng được cho mọi endpoint công khai của /ekyc/ex_api — chỉ thay
cmd và tham số.
JavaScript (server-side / Node.js)
const BASE = 'https://a.sfi.com.vn/ekyc/ex_api';
const HEADERS = { 'X-Api-Key': process.env.SFI_API_KEY };
async function call(params) {
const qs = new URLSearchParams(params);
const res = await fetch(`${BASE}?${qs}`, { headers: HEADERS });
const body = await res.json();
if (!body.success) throw new Error(body.message);
return body.data;
}
// Danh mục sản phẩm (cache lại, ít thay đổi)
const products = await call({ cmd: 'news_products' });
// Danh sách báo cáo + chi tiết
const list = await call({ cmd: 'news', cate: 'kim-loai-quy', page: 1, size: 20 });
const detail = await call({ cmd: 'news', id: list[0].id });
PHP
function sfiCall(array $params) {
$url = 'https://a.sfi.com.vn/ekyc/ex_api?' . http_build_query($params);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('SFI_API_KEY')],
CURLOPT_TIMEOUT => 10,
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
if (empty($body['success'])) {
throw new RuntimeException($body['message'] ?? 'SFI API error');
}
return $body['data'];
}
$news = sfiCall(['cmd' => 'news', 'cate' => 'phan-tich-chuyen-sau', 'page' => 1, 'size' => 10]);