Guides / Rate limits
호출 한도와 쿼터
두 API 모두 짧은 구간 한도(Data API는 분당, PRO API는 초당)와 하루 쿼터를 함께 적용합니다. 하루는 한국시간(KST) 0시에 새로 시작합니다.
Data API
| 등급 | 분당 요청 | 하루 요청 | AI 호출(하루) |
|---|---|---|---|
| Launch | 120회 | 3,334회 | 50회 |
| Business | 600회 | 16,667회 | 200회 |
| Scale | 1,800회 | 66,667회 | 500회 |
| Enterprise | 6,000회 | 기본 1,000,000회 · 계약에 따라 계정별로 조정 | 기본 한도 없음 |
모든 등급이 모든 엔드포인트를 씁니다. Launch · Business · Scale의 하루 한도는 계약한 월 포함량(100,000 · 500,000 · 2,000,000회)을 30으로 나눠 올림한 값입니다. 월 포함량으로 호출을 막지는 않고, 하루 한도와 분당 한도만 적용합니다.
PoC(체험, 기본 7일)
PoC는 계약할 목표 등급(Launch · Business · Scale)을 정해 그 등급의 체험 한도로 모든 엔드포인트를 씁니다. 목표 등급을 정하지 않으면 Launch입니다. 기간은 기본 7일이며 계정을 발급한 때부터 셉니다. 기간은 협의로 조정할 수 있습니다.
| PoC 목표 등급 | 분당 요청 | 하루 요청 | AI 호출(하루) |
|---|---|---|---|
| Launch | 60회 | 2,000회 | 20회 |
| Business | 300회 | 8,000회 | 80회 |
| Scale | 900회 | 30,000회 | 200회 |
- 분당 한도는 키마다 셉니다. 그 키의 첫 요청부터 60초가 한 구간이고, 구간이 끝나면 다음 요청이 새 구간을 엽니다. 한도를 넘긴 요청도 그 구간에 셉니다.
- 하루 쿼터는 계정 단위라 같은 계정의 모든 키가 함께 씁니다. 날짜는 한국시간 기준이고(
X-Quota-Period), 분당 한도로 거절된 요청은 하루 쿼터에 넣지 않습니다. - 표의 숫자는 등급 기본값입니다. 계약에 따라 계정별로 조정할 수 있고, 지금 적용된 값은
GET /key나 개발자 콘솔에서 확인합니다. - 계약하지 않은 시장(종목·
market)의 요청은 한도를 세기 전에403 MARKET_NOT_ENTITLED로 거절합니다. 일본·중국은 준비 중이라400 MARKET_NOT_AVAILABLE입니다. 거절된 요청은 분당 한도·하루 쿼터·AI 호출 한도에 넣지 않습니다. - PoC 기간이 끝나면 계정이 멈춥니다. 계정의 모든 키가
403 POC_ENDED를 받고, 기간 연장이나 정식 계약 후 같은 키로 다시 열립니다. - 유료 등급 기간이 끝나면 계정이 Free로 바뀌고, Free에 열리지 않은 엔드포인트는
403 PLAN_REQUIRED를 돌려줍니다. - 예전에 발급한 무료 체험 키(뉴스·검색, 하루 10회 · 분당 1회)는 그대로 쓸 수 있지만 새로 발급하지 않습니다.
응답 헤더
| 헤더 | 뜻 |
|---|---|
X-RateLimit-Limit | 분당 한도 |
X-RateLimit-Remaining | 이번 구간에 남은 요청 수 |
X-Quota-Limit | 하루 한도(계정) |
X-Quota-Remaining | 오늘 남은 요청 수 |
X-Quota-Period | 쿼터 날짜(한국시간, YYYY-MM-DD) |
X-Quota-Reset | 하루 한도가 다시 열리는 다음 한국시간 0시(ISO 8601) |
X-Plan | 플랜(Free · PoC · Launch · Business · Scale · Enterprise) |
X-Plan-Tier | PoC의 목표 등급(Launch · Business · Scale). 그 밖에는 현재 플랜 |
X-Plan-Expires | 플랜 종료 시각. 기간이 없으면 붙지 않습니다 |
X-Markets | 계약한 시장(예: KR,US) |
Retry-After | 429일 때 다시 시도할 수 있을 때까지 남은 초(분당 한도는 구간 끝, 하루·AI 한도는 다음 한국시간 0시) |
AI 호출 한도
모델 비용이 드는 호출은 일반 하루 한도와 따로 계정당 한국시간 하루 단위로 셉니다. 한도는 위 표의 등급별 값이고(PoC는 목표 등급의 체험 한도), Enterprise에는 기본 AI 한도가 없습니다.
- 세는 호출:
GET /rag(답 모델을 실제로 불렀을 때만),GET /disclosures/{id}/summary·GET /briefings/{symbol}(저장본이 없어 새로 만들거나fresh=true로 다시 만들 때만).POST /query는 모델을 부르지 않는 계산이라 세지 않습니다. 같은 계정이 PRO API를 쓰면 질문·요약 생성(MCP 포함)과 한 카운터를 함께 씁니다. - 넘으면
429 AI_QUOTA_EXCEEDED와 한국시간 0시까지의Retry-After를 받습니다. 일반 데이터 호출은 그대로 됩니다. - 계약에 따라 AI 호출 월 한도를 둘 수 있습니다(Enterprise 포함). 한 달은 플랜 시작 시각부터 한국시간으로 셉니다. 넘으면
429 AI_MONTHLY_QUOTA_EXCEEDED와 다음 주기(또는 플랜 종료)까지의Retry-After를 받습니다. 월 한도가 있는 계정은X-AI-Quota-Monthly-Limit·X-AI-Quota-Monthly-Remaining·X-AI-Quota-Monthly-Reset헤더도 받습니다. - 해당 엔드포인트의 응답 헤더
X-AI-Quota-Limit·X-AI-Quota-Remaining·X-AI-Quota-Reset,GET /key의ai_quota, 개발자 콘솔에서 남은 횟수를 확인합니다.
PRO API
| 플랜 | 하루 호출(기본) | 초당(기본) | 포함 |
|---|---|---|---|
| Data | 1,000회 | 2회 | AI 공시 요약 즉석 생성 하루 50건 |
| Ask | 1,000회 | 2회 | 대화형 질문 월 300회 포함 · 하루 최대 300회(웹 PRO와 합산) |
| Bundle | 1,000회 | 2회 | Data와 Ask 모두 |
- 초당 한도는 키마다 토큰 버킷으로 셉니다. 초당 2회면 순간 2회를 보낸 뒤 0.5초마다 1회씩 다시 열립니다. 같은 키로 연결한 MCP 도구 호출도 같은 버킷을 씁니다.
- 하루 호출은 계정 단위이고 REST와 MCP 도구 호출을 합쳐 셉니다.
GET /me와GET /ask/{job_id}는 하루 호출에 넣지 않습니다(초당 한도는 적용). - AI 비용 상한: AI 공시 요약 즉석 생성과 대화형 질문은 계정의 월 AI 비용 상한 안에서 처리합니다. 상한에 닿으면
402 BUDGET_EXCEEDED를 받고, 저장된 요약 조회는 계속 됩니다. - 위 숫자는 플랜 기본값입니다. 계약에 따라 계정별로 조정할 수 있고, 지금 적용된 값은
GET /me로 확인합니다. - 플랜 기간이 끝나면 다음 요청부터
403 PLAN_EXPIRED를 받습니다. 시작 전이면PLAN_NOT_STARTED, 정지·해지면PLAN_INACTIVE, 플랜이 없으면PLAN_REQUIRED입니다.
응답 헤더
| 헤더 | 뜻 |
|---|---|
X-RateLimit-Limit | 초당 한도 |
X-RateLimit-Remaining | 지금 남은 요청 수 |
X-Quota-Limit | 하루 호출 한도(계정) |
X-Quota-Remaining | 오늘 남은 호출 수 |
X-Quota-Reset | 다음 한국시간 0시(ISO 8601, UTC) |
X-Quota-Period | 쿼터 날짜(한국시간, YYYY-MM-DD) |
X-Budget-Remaining | 이번 달 AI 비용 남은 금액(USD) |
X-Ask-Remaining | 오늘 남은 질문 수(웹 PRO 포함) |
Retry-After | 429일 때 다시 시도할 수 있을 때까지 남은 초(하루 한도 소진 포함) |
재시도
429:Retry-After가 있으면 그만큼 기다린 뒤 다시 보냅니다.503 UNAVAILABLE: 잠시 뒤 지수 백오프로 다시 시도합니다.- 그 밖의
4xx는 같은 요청을 다시 보내도 결과가 같습니다. 오류 코드를 보고 요청을 고치세요.
JavaScript — Retry-After를 따르는 재시도
javascript
// 429는 Retry-After만큼 기다렸다가, 503은 짧게 물러섰다가 다시 시도합니다. 나머지 4xx는 재시도하지 않습니다.
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; // 하루 쿼터 소진 등 긴 대기는 호출부에서 처리
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;
}
}
}