ThaiQuest Corporate Data Services API · Developer Guide
API Specification

ThaiQuest Corporate Data Services API

Look up Thai juristic persons — registration details and latest filed financials — by their 13-digit registration number.

Version
v1 (document 1.0)
Published
11 November 2026
Base URL
https://cds-demo.thaiquest.net
Format
JSON over HTTPS
  1. Overview
  2. Authentication
  3. Rate limits
  4. Get a juristic person
  5. Response fields
  6. Errors
  7. Code examples
  8. 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

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.

WindowStandard planResets
Per minute60Every minute, on the minute
Per hour600Every hour, on the hour
Per day6,000Daily at 00:00 (UTC+7)
Per month60,0001st 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:

HeaderMeaning
X-RateLimit-LimitLimit of the most constraining window
X-RateLimit-RemainingRequests left in that window after this one
X-RateLimit-ResetUnix timestamp (seconds) when that window resets
X-RateLimit-Windowminute, hour, day or month
Retry-AfterOn 429 only: seconds to wait before retrying
Every authenticated request counts, including ones that return 404. Requests rejected with 429 do not count. On a 429, wait 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

GET/api/v1/juristics/{juristic_id}

Returns the registration profile of one juristic person (company or partnership) and the headline figures from its most recent filed financial statement.

Path parameter
NameTypeDescription
juristic_idstring13-digit registration number issued by the Department of Business Development, e.g. 0105543033451. Digits only — no dashes or spaces.
Request
curl https://cds-demo.thaiquest.net/api/v1/juristics/0105543033451 \
  -H "X-API-Key: $CDS_API_KEY"
Response · 200 OK
{
  "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.

FieldTypeDescription
name_thstringRegistered name in Thai, including legal form (e.g. บริษัท … จำกัด).
name_enstringRegistered name in English. Empty string if none was registered.
juristic_idstring13-digit registration number.
juristic_typestringLegal form in Thai: บริษัทจำกัด, บริษัทมหาชนจำกัด, ห้างหุ้นส่วนจำกัด or ห้างหุ้นส่วนสามัญนิติบุคคล.
statusstringRegistration status in Thai, e.g. ยังดำเนินกิจการอยู่ (operating), เลิก (dissolved), เสร็จการชำระบัญชี (liquidated), ร้าง (defunct), ล้มละลาย (bankrupt).
addressstringRegistered head-office address, single line, in Thai.
tsicstring5-digit Thailand Standard Industrial Classification code — from the latest filing, otherwise the code declared at registration.
purposestringBusiness objective declared at registration (Thai). May be truncated at source.
registration_datestring (date)Date of incorporation, YYYY-MM-DD.
last_filing_yearinteger nullableFiscal year (Gregorian, CE) of the most recent filed financial statement.
last_filing_year_beinteger nullableThe same fiscal year in the Buddhist Era (= last_filing_year + 543), as used by DBD.
last_filing_datestring (date) nullableDate that statement was received, YYYY-MM-DD.
lfy_revenuenumber nullableTotal revenue of the last filed year, in Thai baht (THB).
lfy_profitnumber nullableNet 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" }
HTTPerrorWhenWhat to do
401missing_api_keyNo X-API-Key headerSend the header
401invalid_api_keyKey not recognisedCheck the key; don't retry
403api_key_disabledKey has been disabledContact the CDS team
403api_key_expiredKey is past its expiry dateRequest a renewal
404not_foundNo juristic person with that ID, or ID is not 13 digitsDon't retry
429rate_limitedA rate-limit window of your key is exhaustedWait Retry-After seconds
429(edge, non-JSON)Global per-IP limit (30 per 10 s) exceededBack off for a few seconds
500internal_errorUnexpected server errorRetry 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

This is a demonstration service. Availability and data completeness are provided on a best-effort basis and the interface may change before general release.