Guides / Rate limits
Rate limits
Both APIs apply a short window (per minute on the Data API, per second on the PRO API) together with a daily quota. A new day starts at 00:00 Korea Standard Time (KST, UTC+9).
Data API
| Tier | Requests per minute | Requests per day | AI calls per day |
|---|---|---|---|
| Launch | 120 | 3,334 | 50 |
| Business | 600 | 16,667 | 200 |
| Scale | 1,800 | 66,667 | 500 |
| Enterprise | 6,000 | 1,000,000 by default · adjusted per account by contract | No default limit |
Every tier uses every endpoint. The daily limit of Launch, Business and Scale is the contracted monthly allowance (100,000 · 500,000 · 2,000,000 requests) divided by 30, rounded up. Calls are not blocked on the monthly allowance; only the daily and per-minute limits apply.
PoC (trial, 7 days by default)
A PoC picks the tier you plan to contract (Launch, Business or Scale) and uses every endpoint at that tier's trial limits. Without a target tier it is Launch. The period is 7 days by default and counts from when the account is issued; the term can be adjusted by agreement.
| PoC target tier | Requests per minute | Requests per day | AI calls per day |
|---|---|---|---|
| Launch | 60 | 2,000 | 20 |
| Business | 300 | 8,000 | 80 |
| Scale | 900 | 30,000 | 200 |
- The per-minute limit is counted per key. A window opens with the key's first request and lasts 60 seconds; the next request after it ends opens a new window. Requests over the limit still count toward the window.
- The daily quota is per account, so all keys on the account share it. The date is in KST (
X-Quota-Period). Requests rejected by the per-minute limit do not use the daily quota. - The numbers above are tier defaults. They can be adjusted per account by contract; check the values in effect with
GET /keyor in the developer console. - Requests for a market outside your contract (symbol or
market) are rejected with403 MARKET_NOT_ENTITLEDbefore any limit is counted. Japan and China return400 MARKET_NOT_AVAILABLE(coming soon). Rejected requests do not use the per-minute limit, the daily quota or the AI-call limit. - When the PoC period ends, the account stops. Every key on the account gets
403 POC_ENDED; after an extension or a full contract, the same keys work again. - When a paid-tier term ends, the account falls back to Free, and endpoints Free does not include return
403 PLAN_REQUIRED. - Free trial keys issued earlier (news and search, 10 per day · 1 per minute) keep working, but we no longer issue new ones.
Response headers
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Per-minute limit |
X-RateLimit-Remaining | Requests left in the current window |
X-Quota-Limit | Daily limit (account) |
X-Quota-Remaining | Requests left today |
X-Quota-Period | Quota date (KST, YYYY-MM-DD) |
X-Quota-Reset | Next 00:00 KST, when the daily quota reopens (ISO 8601) |
X-Plan | Plan (Free · PoC · Launch · Business · Scale · Enterprise) |
X-Plan-Tier | The PoC target tier (Launch · Business · Scale); otherwise the current plan |
X-Plan-Expires | When the plan ends; absent for plans without an end date |
X-Markets | Markets on your contract (e.g. KR,US) |
Retry-After | Seconds until you can retry, on 429 (end of the window for the per-minute limit, next 00:00 KST for the daily and AI limits) |
AI call limit
Calls that incur model costs are counted separately from the regular daily quota, per account per KST day. The limit is the tier value in the tables above (a PoC uses its target tier's trial limit). Enterprise has no default AI limit.
- What counts:
GET /rag(only when the answer model is actually called),GET /disclosures/{id}/summaryandGET /briefings/{symbol}(only when no stored copy exists and a new one is generated, or withfresh=true).POST /queryruns without a model and does not count. If the same account uses the PRO API, its question and summary generation (MCP included) share this counter. - Over the limit, you get
429 AI_QUOTA_EXCEEDEDwith aRetry-Afteruntil 00:00 KST. Regular data calls keep working. - A contract can add a monthly AI call limit (Enterprise included). The month runs from the plan start time in Korea time. Over it, you get
429 AI_MONTHLY_QUOTA_EXCEEDEDwith aRetry-Afteruntil the next cycle (or the plan end). Accounts with a monthly limit also get theX-AI-Quota-Monthly-Limit·X-AI-Quota-Monthly-Remaining·X-AI-Quota-Monthly-Resetheaders. - Check the remaining count in the
X-AI-Quota-Limit·X-AI-Quota-Remaining·X-AI-Quota-Resetresponse headers on those endpoints, inai_quotafromGET /key, or in the developer console.
PRO API
| Plan | Calls per day (default) | Per second (default) | Includes |
|---|---|---|---|
| Data | 1,000 | 2 | On-demand AI filing summaries, 50 per day |
| Ask | 1,000 | 2 | 300 questions per month included · up to 300 per day (shared with web PRO) |
| Bundle | 1,000 | 2 | Both Data and Ask |
- The per-second limit is a token bucket per key. At 2 per second you can send 2 requests at once, then one more opens every 0.5 seconds. MCP tool calls made with the same key share the bucket.
- Daily calls are per account and combine REST and MCP tool calls.
GET /meandGET /ask/{job_id}do not count toward daily calls (the per-second limit still applies). - AI spend cap: on-demand AI filing summaries and questions run within the account's monthly AI spend cap. At the cap you get
402 BUDGET_EXCEEDED; stored summaries remain available. - The numbers above are plan defaults. They can be adjusted per account by contract;
GET /meshows the values in effect. - When a plan term ends, the next request returns
403 PLAN_EXPIRED. Before the start date it isPLAN_NOT_STARTED, a suspended or cancelled plan isPLAN_INACTIVE, and no plan isPLAN_REQUIRED.
Response headers
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Per-second limit |
X-RateLimit-Remaining | Requests available now |
X-Quota-Limit | Daily call limit (account) |
X-Quota-Remaining | Calls left today |
X-Quota-Reset | Next 00:00 KST (ISO 8601, UTC) |
X-Quota-Period | Quota date (KST, YYYY-MM-DD) |
X-Budget-Remaining | AI spend left this month (USD) |
X-Ask-Remaining | Questions left today (including web PRO) |
Retry-After | Seconds until you can retry, on any 429 (including the daily quota) |
Retries
429: ifRetry-Afteris present, wait that many seconds, then retry.503 UNAVAILABLE: retry after a short while with exponential backoff.- Other
4xxresponses do not change on retry. Check Errors and fix the request.
JavaScript: retry that honors Retry-After
// Wait Retry-After on 429, back off briefly on 503, and do not retry other 4xx responses.
async function callWithRetry(url, init, attempts = 4) {
for (let i = 0; ; i++) {
const res = await fetch(url, init);
if (res.ok || i === attempts - 1) return res;
if (res.status === 429) {
const wait = Number(res.headers.get("Retry-After"));
if (!Number.isFinite(wait) || wait > 60) return res; // long waits (e.g. daily quota used up): handle in the caller
await new Promise((r) => setTimeout(r, wait * 1000));
} else if (res.status === 503) {
await new Promise((r) => setTimeout(r, 2 ** i * 500 + Math.random() * 250));
} else {
return res;
}
}
}Need higher limits?