ThaiQuest Corporate Data Services API
Look up Thai juristic persons — registration details and latest filed financials — by their 13-digit registration number.
- Overview
- Authentication
- Rate limits
- Get a juristic person
- Response fields
- Errors
- Code examples
- Data notes
1Overview
The CDS API is a read-only REST API. Every request is an HTTPS GET; every response body is UTF-8 JSON (application/json; charset=utf-8), including errors. Thai text is returned as UTF-8 characters, not escaped.
Versioning
The major version is part of the path (/api/v1/). New fields may be added to responses within v1; clients must ignore fields they don't recognise. Breaking changes ship as /api/v2/.
Machine-readable spec
OpenAPI 3.0 at /api/openapi.yaml; interactive explorer at /api/docs. Use them to generate clients.
2Authentication
Every /api/v1/ request must carry an API key in the X-API-Key header. The header name is case-insensitive.
X-API-Key: cds_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- Keys are issued by the CDS team; each key belongs to one client application.
- Keep keys server-side. Never embed them in browser JavaScript or mobile apps, and never put them in a URL.
- A key may carry an expiry date. Expired or disabled keys return 403.
- Key changes (new keys, revocations, new limits) take effect within seconds, without downtime.
The documentation pages (/api/spec, /api/docs, /api/openapi.yaml) do not require a key.
Demo key
To try the API before you have your own key, use the public demo key cds_testKey. It returns the complete record for ThaiQuest (0105543033451) only; any other request with it returns 401 invalid_api_key.
curl https://cds-demo.thaiquest.net/api/v1/juristics/0105543033451 \
-H "X-API-Key: cds_testKey"
Your own key returns the complete record for every juristic person.
3Rate limits
Limits are applied per API key, across all endpoints, in fixed calendar windows using Thailand time (UTC+7). Each window resets at its boundary — the start of the next minute, hour, day (00:00) or month (1st, 00:00). A request must fit within every window.
| Window | Standard plan | Resets |
|---|---|---|
| Per minute | 60 | Every minute, on the minute |
| Per hour | 600 | Every hour, on the hour |
| Per day | 6,000 | Daily at 00:00 (UTC+7) |
| Per month | 60,000 | 1st of each month at 00:00 (UTC+7) |
Your key may have a custom plan. The response headers always tell you the limit that currently applies:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Limit of the most constraining window |
X-RateLimit-Remaining | Requests left in that window after this one |
X-RateLimit-Reset | Unix timestamp (seconds) when that window resets |
X-RateLimit-Window | minute, hour, day or month |
Retry-After | On 429 only: seconds to wait before retrying |
Retry-After seconds — don't retry in a loop.Global limit per IP address
Independently of your plan, all traffic is subject to a global rate limit of 30 requests per 10 seconds per client IP address, enforced at the network edge. Exceeding it returns 429 from the edge (not the JSON error format above, and without X-RateLimit-* headers) and blocks that IP for a short period. Spread bursts out, and keep concurrent workers sharing one IP below this rate.
4Get a juristic person
Returns the registration profile of one juristic person (company or partnership) and the headline figures from its most recent filed financial statement.
| Name | Type | Description |
|---|---|---|
juristic_id | string | 13-digit registration number issued by the Department of Business Development, e.g. 0105543033451. Digits only — no dashes or spaces. |
curl https://cds-demo.thaiquest.net/api/v1/juristics/0105543033451 \
-H "X-API-Key: $CDS_API_KEY"
{
"name_th": "บริษัท ไทยเควสท์ จำกัด",
"name_en": "THAIQUEST LIMITED",
"juristic_id": "0105543033451",
"juristic_type": "บริษัทจำกัด",
"status": "ยังดำเนินกิจการอยู่",
"address": "888/180 อาคารมหาทุนพลาซ่า ชั้น 18 ถนนเพลินจิต แขวงลุมพินี เขตปทุมวัน กรุงเทพมหานคร 10330",
"tsic": "63111",
"purpose": "ให้บริการข่าวสารข้อมูล และอุปกรณ์ในการรับส่งข่าวสา",
"registration_date": "2000-04-03",
"last_filing_year": 2025,
"last_filing_year_be": 2568,
"last_filing_date": "2026-05-14",
"lfy_revenue": 166573112,
"lfy_profit": 28418355
}
5Response fields
All fields are always present. Fields marked nullable are null when the juristic person has never filed a financial statement.
| Field | Type | Description |
|---|---|---|
name_th | string | Registered name in Thai, including legal form (e.g. บริษัท … จำกัด). |
name_en | string | Registered name in English. Empty string if none was registered. |
juristic_id | string | 13-digit registration number. |
juristic_type | string | Legal form in Thai: บริษัทจำกัด, บริษัทมหาชนจำกัด, ห้างหุ้นส่วนจำกัด or ห้างหุ้นส่วนสามัญนิติบุคคล. |
status | string | Registration status in Thai, e.g. ยังดำเนินกิจการอยู่ (operating), เลิก (dissolved), เสร็จการชำระบัญชี (liquidated), ร้าง (defunct), ล้มละลาย (bankrupt). |
address | string | Registered head-office address, single line, in Thai. |
tsic | string | 5-digit Thailand Standard Industrial Classification code — from the latest filing, otherwise the code declared at registration. |
purpose | string | Business objective declared at registration (Thai). May be truncated at source. |
registration_date | string (date) | Date of incorporation, YYYY-MM-DD. |
last_filing_year | integer nullable | Fiscal year (Gregorian, CE) of the most recent filed financial statement. |
last_filing_year_be | integer nullable | The same fiscal year in the Buddhist Era (= last_filing_year + 543), as used by DBD. |
last_filing_date | string (date) nullable | Date that statement was received, YYYY-MM-DD. |
lfy_revenue | number nullable | Total revenue of the last filed year, in Thai baht (THB). |
lfy_profit | number nullable | Net profit of the last filed year in THB; negative for a loss. |
6Errors
Errors use standard HTTP status codes and a JSON body with a stable machine-readable error code and a human-readable message. Branch on error, not on message.
{ "error": "not_found", "message": "juristic 0105500000009 not found" }
| HTTP | error | When | What to do |
|---|---|---|---|
| 401 | missing_api_key | No X-API-Key header | Send the header |
| 401 | invalid_api_key | Key not recognised | Check the key; don't retry |
| 403 | api_key_disabled | Key has been disabled | Contact the CDS team |
| 403 | api_key_expired | Key is past its expiry date | Request a renewal |
| 404 | not_found | No juristic person with that ID, or ID is not 13 digits | Don't retry |
| 429 | rate_limited | A rate-limit window of your key is exhausted | Wait Retry-After seconds |
| 429 | (edge, non-JSON) | Global per-IP limit (30 per 10 s) exceeded | Back off for a few seconds |
| 500 | internal_error | Unexpected server error | Retry later with back-off |
7Code examples
Python (requests)
import os, time, requests
def get_juristic(juristic_id: str) -> dict | None:
r = requests.get(
f"https://cds-demo.thaiquest.net/api/v1/juristics/{juristic_id}",
headers={"X-API-Key": os.environ["CDS_API_KEY"]},
timeout=10,
)
if r.status_code == 404:
return None
if r.status_code == 429:
time.sleep(int(r.headers["Retry-After"]))
return get_juristic(juristic_id)
r.raise_for_status()
return r.json()
JavaScript (Node 18+)
const res = await fetch(
`https://cds-demo.thaiquest.net/api/v1/juristics/${juristicId}`,
{ headers: { "X-API-Key": process.env.CDS_API_KEY } },
);
if (res.status === 404) return null;
if (!res.ok) {
const { error, message } = await res.json();
throw new Error(`${res.status} ${error}: ${message}`);
}
const juristic = await res.json();
Go
req, _ := http.NewRequest("GET", "https://cds-demo.thaiquest.net/api/v1/juristics/"+id, nil)
req.Header.Set("X-API-Key", os.Getenv("CDS_API_KEY"))
res, err := http.DefaultClient.Do(req)
8Data notes
- Source. Public registration and financial-statement data of the Department of Business Development (DBD), Ministry of Commerce, refreshed continuously.
- Years. DBD publishes fiscal years in the Buddhist Era. The API returns both:
last_filing_yearin the Gregorian calendar (2025) andlast_filing_year_beas published (2568). Use the CE value for date arithmetic and sorting. All dates are ISO 8601 (YYYY-MM-DD), Gregorian. - Last filed year. The most recent fiscal year with a non-empty statement. Companies file about five months after year end, so the latest year may lag by more than a year.
- Money. Amounts are in Thai baht as JSON numbers. Revenue is total revenue (sales/services plus other income); profit is net profit after tax.
- IDs. Always treat
juristic_idas a string — it has leading zeros.