curl --request GET \
--url https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows \
--header 'X-API-Key: <api-key>'import requests
url = "https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"statusCode": 200,
"data": {
"investor": "foreign",
"range": "1m",
"resolution": "day",
"currency": "VND",
"asOf": "2026-09-30",
"from": "2026-08-31",
"availableRanges": [
"1m",
"3m",
"6m",
"1y"
],
"points": [
{
"period": "2026-08-31",
"buyValue": 154200000000,
"sellValue": 171850000000,
"netValue": -17650000000,
"sessions": 1
},
{
"period": "2026-09-30",
"buyValue": 182450000000,
"sellValue": 156320000000,
"netValue": 26130000000,
"sessions": 1
}
]
},
"meta": {
"source": [
"vnsc:/stocks/{symbol}/trading/foreign/history"
],
"as_of": "2026-09-30",
"unit": "VND",
"classification": "RAW",
"formula_version": "vn-netflow-v1",
"was_restated": false,
"served_from_cache": true,
"cache_expires_at": "2026-10-01T09:00:00.000Z",
"timestamp": "2026-10-01T08:00:00.000Z"
}
}{
"success": false,
"statusCode": 401,
"error": {
"code": "API_KEY_INVALID",
"message": "Invalid API key"
},
"meta": {
"timestamp": "2026-06-19T08:31:59.478Z"
}
}{
"success": false,
"statusCode": 401,
"error": {
"code": "API_KEY_INVALID",
"message": "Invalid API key"
},
"meta": {
"timestamp": "2026-06-19T08:34:08.023Z"
}
}{
"success": false,
"statusCode": 403,
"error": {
"code": "FEATURE_NOT_IN_PLAN",
"message": "Your plan does not include this feature"
},
"meta": {
"timestamp": "2026-06-19T08:34:08.100Z"
}
}{
"success": false,
"statusCode": 404,
"error": {
"code": "EQUITY_NOT_FOUND",
"message": "Không tìm thấy mã cổ phiếu XYZ"
},
"meta": {
"error": "Not Found",
"statusCode": 404,
"timestamp": "2026-10-01T08:00:00.000Z"
}
}{
"success": false,
"statusCode": 429,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded"
},
"meta": {
"timestamp": "2026-06-19T08:34:09.000Z"
}
}{
"success": false,
"statusCode": 500,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
},
"meta": {
"timestamp": "2026-06-19T08:34:10.000Z"
}
}Vietnam equity investor net flows
Buy, sell and net value of one Vietnamese stock traded by foreign investors or by securities companies’ proprietary desks, oldest to newest. Values are in VND and include order-matching and put-through trades. Vietnam only.
1m / 3m return one point per session. 6m / 1y return one point per
month (sum of that month’s sessions; the current month runs up to the latest
session).
curl --request GET \
--url https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows \
--header 'X-API-Key: <api-key>'import requests
url = "https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-v2.hayinsights.com/openapi/v1/market/vn/equities/{code}/netflows")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"success": true,
"statusCode": 200,
"data": {
"investor": "foreign",
"range": "1m",
"resolution": "day",
"currency": "VND",
"asOf": "2026-09-30",
"from": "2026-08-31",
"availableRanges": [
"1m",
"3m",
"6m",
"1y"
],
"points": [
{
"period": "2026-08-31",
"buyValue": 154200000000,
"sellValue": 171850000000,
"netValue": -17650000000,
"sessions": 1
},
{
"period": "2026-09-30",
"buyValue": 182450000000,
"sellValue": 156320000000,
"netValue": 26130000000,
"sessions": 1
}
]
},
"meta": {
"source": [
"vnsc:/stocks/{symbol}/trading/foreign/history"
],
"as_of": "2026-09-30",
"unit": "VND",
"classification": "RAW",
"formula_version": "vn-netflow-v1",
"was_restated": false,
"served_from_cache": true,
"cache_expires_at": "2026-10-01T09:00:00.000Z",
"timestamp": "2026-10-01T08:00:00.000Z"
}
}{
"success": false,
"statusCode": 401,
"error": {
"code": "API_KEY_INVALID",
"message": "Invalid API key"
},
"meta": {
"timestamp": "2026-06-19T08:31:59.478Z"
}
}{
"success": false,
"statusCode": 401,
"error": {
"code": "API_KEY_INVALID",
"message": "Invalid API key"
},
"meta": {
"timestamp": "2026-06-19T08:34:08.023Z"
}
}{
"success": false,
"statusCode": 403,
"error": {
"code": "FEATURE_NOT_IN_PLAN",
"message": "Your plan does not include this feature"
},
"meta": {
"timestamp": "2026-06-19T08:34:08.100Z"
}
}{
"success": false,
"statusCode": 404,
"error": {
"code": "EQUITY_NOT_FOUND",
"message": "Không tìm thấy mã cổ phiếu XYZ"
},
"meta": {
"error": "Not Found",
"statusCode": 404,
"timestamp": "2026-10-01T08:00:00.000Z"
}
}{
"success": false,
"statusCode": 429,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded"
},
"meta": {
"timestamp": "2026-06-19T08:34:09.000Z"
}
}{
"success": false,
"statusCode": 500,
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error"
},
"meta": {
"timestamp": "2026-06-19T08:34:10.000Z"
}
}Authorizations
Your HayInsights API key (prefixed apk_). Create and manage keys in the
HayInsights dashboard (Account → API keys).
Send it in the X-API-Key header on every request to /openapi/v1/*.
Which data domains you may access and your request quota are both governed by
the subscription plan attached to the key — see the Plans & features and
Rate limits guides.
Path Parameters
Stock code — the 3-character ticker (FPT, VCB, A32). Case-insensitive.
^[A-Za-z0-9]{3}$"VCB"
Query Parameters
foreign = foreign investors; proprietary = securities companies' proprietary trading.
foreign, proprietary "foreign"
Window to return, counted back from the latest session.
1m, 3m, 6m, 1y Response
Net flow series for the requested investor group and window.
Standard success envelope shared by every endpoint. Each operation's response
wrapper extends this (via allOf) and adds a typed data property.
Always true for a successful response.
true
Mirrors the HTTP status code.
200
Net flow series of one investor group, oldest to newest.
Show child attributes
Show child attributes
Response metadata for the Equities domain. On top of timestamp, every equities
response says where the numbers came from and how fresh they are.
Show child attributes
Show child attributes