e
EBUT Developer Portal 이벗 API 통합 문서 · v3 · api.ebut.co.kr
핵심 개념 · Rate Limits

Rate Limits

이벗 API 의 요청 제한은 게이트웨이의 초당 속도 제한(IP 단위)과 인증키의 월 호출 한도(계정 단위) 두 단계로 나뉩니다. 둘 다 HTTP 429 를 반환하지만 응답 형식이 서로 다르므로 구분해 처리하셔야 합니다. 운영(live) 인증키와 JWT 에는 월 호출 한도가 적용되지 않습니다.

제한은 두 단계로 적용됩니다

단계 제한 단위 제한 적용 대상
① 게이트웨이
일반 API
출발지 IP 당 초당 요청 수 IP 당 30 req/s (순간 버스트 50) /v3/ 전체 — 인증 방식과 무관하게 적용됩니다.
① 게이트웨이
MCP API
출발지 IP 당 초당 요청 수 IP 당 10 req/s (순간 버스트 10) /v3/mcp/ 전용 — 일반 경로보다 엄격합니다.
② 인증키 계정 당 월 누적 호출 수 아래 표 참조 테스트(test) API Key 로 호출한 요청만
두 단계의 429 는 코드가 같고 헤더가 다릅니다 응답 본문은 둘 다 표준 봉투이며 error.code 도 모두 RATE_LIMIT_EXCEEDED 입니다. 다만 게이트웨이가 차단한 429 에는 Retry-After 와 X-RateLimit-* 헤더가 붙지 않습니다. Retry-After 유무로 어느 쪽인지 구분하실 수 있습니다 — 없으면 속도 제한(곧 회복), 있으면 월 한도 소진(재시도로 해결되지 않음)입니다.

셀러 입장에서 무슨 뜻인가요?

게이트웨이 제한은 인증키가 아니라 호출하는 서버의 공인 IP 를 기준으로 셉니다. 인증키를 몇 개 쓰시든, 어느 서비스를 호출하시든 같은 IP 에서 나간 요청은 하나로 합산됩니다.

호출 환경 적용되는 방식
서버 1대에서 호출 그 서버의 공인 IP 하나로 잡혀 초당 30요청을 씁니다.
서버 여러 대에서 호출 서버마다 공인 IP 가 다르면 각 IP 별로 독립된 한도가 적용됩니다. 호출을 분산하시면 그만큼 여유가 생깁니다.
여러 서버가 같은 NAT·프록시를 통해 나감 밖에서는 IP 가 하나로 보이므로 모두 합쳐 초당 30요청입니다. 서버를 늘려도 한도는 늘지 않습니다.
버스트(burst) 는 순간 여유분입니다 평균 초당 30요청을 넘더라도 최대 50건까지는 즉시 통과시킨 뒤, 그 여유분이 소진되면 429 를 반환합니다. 짧게 몰아치는 호출은 통과하지만 지속적으로 초당 30요청을 넘기면 차단된다는 뜻입니다. 고정된 간격으로 보내시는 편이 안정적입니다.

월 호출 한도 (인증 방식별)

인증 / 환경 제한 비고
API Key — 테스트(test) 월 1,000회 계정 단위로 합산합니다. 인증키를 여러 개 발급하셔도 한도는 하나입니다.
API Key — 운영(live) 월 한도 없음 호출량은 집계하지만 차단하지 않습니다. 공정 사용에 관하여는 이용약관 제28조를 따릅니다.
JWT 월 한도 없음 내부 서비스 연동용입니다.
사용량은 어디서 보나요? 통합계정 > API 인증키 화면에서 이번 달 사용량과 남은 호출 수를 확인하실 수 있습니다. 한도의 80% 에 도달하거나 한도를 모두 사용하시면 가입하신 이메일로 안내해 드립니다. 한도 상향이 필요하시면 help@ebut.co.kr 로 문의해주세요.

응답 헤더로 잔여 확인

한도가 적용되는 요청의 응답에는 현재 사용량을 알려주는 헤더가 포함됩니다.

헤더 의미
X-RateLimit-Limit이번 달 허용량 (예: 1000)
X-RateLimit-Remaining이번 달 남은 호출 수
X-RateLimit-Reset한도 초기화 시각 — 다음 달 1일 00:00 (Unix epoch 초)
Retry-After429 응답에만 포함. 대기 권장 초
운영(live) 인증키 응답에는 이 헤더가 없습니다 한도가 적용되지 않으므로 알려드릴 잔여량이 없습니다. -1 이나 unlimited 같은 값을 대신 넣지 않습니다 — 없는 것보다 틀린 값이 나쁘기 때문입니다. 헤더가 없을 때를 대비해 parseInt 결과를 그대로 쓰지 마시고 값이 있을 때만 사용하도록 작성해주세요.

429 응답 처리

① 게이트웨이 속도 제한 초과

HTTP/1.1 429 Too Many Requests
Content-Type: application/json

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "요청 한도를 초과했습니다."
  }
}

Retry-After · X-RateLimit-* 헤더가 없습니다. 초당 요청 수를 줄이고 지수 백오프로 재시도하세요. 버스트를 넘긴 순간에만 발생하므로 대개 수백 밀리초 안에 회복됩니다.

② 월 호출 한도 초과 (테스트 인증키)

HTTP/1.1 429 Too Many Requests
Retry-After: 1987200
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1718352000

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "이번 달 호출 한도(1,000회)를 초과했습니다. 다음 달 1일에 초기화됩니다."
  }
}

이쪽은 재시도로 해결되지 않습니다. 다음 달 1일에 초기화되거나 운영(live) 인증키로 전환하셔야 합니다. Retry-After 값이 수십만 초인 이유가 이것입니다.

Node.js 재시도 예시

async function callWithRetry(url, options, maxRetry = 3) {
  for (let i = 0; i < maxRetry; i++) {
    const res = await fetch(url, options);
    if (res.status !== 429) return res;

    // 429 — Retry-After 만큼 대기 (없으면 지수 백오프)
    const wait = res.headers.get("Retry-After");
    const ms = wait ? parseInt(wait) * 1000 : Math.pow(2, i) * 1000;
    await new Promise(r => setTimeout(r, ms));
  }
  throw new Error("Rate limit retry exhausted");
}

모범 사례

1. 지수 백오프 (Exponential Backoff)

429 응답을 받으면 즉시 재시도하지 말고, 대기 시간을 점차 늘려가며 재시도하세요. 여러 클라이언트가 동시에 차단됐다가 한꺼번에 재시도하는 "썬더링 허드" 문제를 방지할 수 있습니다.

대기 시간:  1초 → 2초 → 4초 → 8초 → 16초 ... (최대 60초)
지터 추가:  ±20% 랜덤 가산 (동시 재시도 분산)

2. 배치 호출 활용

같은 종류 데이터를 N개 가져올 때는 개별 호출 대신 페이징을 활용하세요.

3. 캐싱

자주 변하지 않는 데이터(상품 마스터, 공급사 정보 등)는 클라이언트에 캐싱하여 호출 자체를 줄이세요. 일반적인 TTL 기준:

4. 비동기 큐

대량 호출(수천 건 일괄 동기화)은 동기적으로 한 번에 처리하지 말고 작업 큐(예: BullMQ, Sidekiq, Celery)에 분산시켜 월 한도 안에서 순차 처리하세요.

5. 변경 감지 후 호출 (Polling 최소화)

같은 endpoint 를 짧은 주기로 반복 호출(polling)하지 마세요. updated_after 같은 변경 시각 필터를 활용해 새로 변경된 데이터만 가져오는 것이 한도와 부하 면에서 유리합니다.

한도 초과 모니터링

반복적으로 429 를 받는 경우 다음을 확인하세요.