Rate Limiting 가이드

API의 안정적인 운영을 위해 엔드포인트별로 요청 빈도를 제한합니다. Rate Limit 초과 시 응답 구조와 재시도 전략을 안내합니다.

요청 제한 정책

Book Print API는 3개 정책으로 요청 빈도를 제한합니다. 각 정책은 엔드포인트의 특성에 따라 적용됩니다.

정책대상제한집계 기준
auth인증 엔드포인트 (파트너 직접 호출 없음)10 req/분IP 단위
general일반 API (Books 조회, Orders, Credits, Templates, Webhooks 등)300 req/분API Key 단위
upload파일 업로드 및 콘텐츠 추가 (아래 표 참조)200 req/분API Key 단위

upload 정책 적용 엔드포인트

엔드포인트용도
POST /books/{bookUid}/cover표지 추가 (템플릿 기반)
POST /books/{bookUid}/contents내지 추가 (템플릿 기반)
POST /books/{bookUid}/pdf-cover (POST/PUT)표지 PDF 업로드/교체
POST /books/{bookUid}/pdf-contents (POST/PUT)내지 PDF 업로드/교체
POST /books/{bookUid}/photos사진 업로드
집계 기준: general · upload 정책은 동일 API Key 소유자 단위로 집계됩니다. 여러 서버에서 같은 Key를 사용하면 합산되므로, 높은 처리량이 필요하다면 여러 Key 발급을 고려하세요.

Rate Limit 초과 시 응답

요청 제한을 초과하면 429 Too Many Requests 응답이 반환됩니다. 응답 헤더에 Retry-After: 60이 포함되며, 해당 시간(초) 이후 재요청할 수 있습니다.

Retry-After는 초 단위 정수입니다. 현재 일괄 60초로 반환됩니다.

Error response
HTTP/2 429
Retry-After: 60
content-type: application/json; charset=utf-8

{
  "success": false,
  "message": "Too Many Requests",
  "errors": ["요청 횟수 제한을 초과했습니다. 잠시 후 다시 시도하세요."]
}

Best Practices

1. Retry-After 우선 존중 + 지수 백오프 fallback

429 응답을 받으면 Retry-After 헤더 값만큼 대기하는 것이 기본 원칙입니다. 헤더가 누락된 경우에만 지수 백오프(Exponential Backoff)를 fallback으로 사용하세요.

재시도 후에도 계속 429가 반환되면 요청 빈도를 구조적으로 낮춰야 합니다 (아래 2/3번 참조).

JavaScript
async function requestWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      // Retry-After 헤더 우선 존중 (초 단위)
      const retryAfterSec = parseInt(response.headers.get('Retry-After') || '0', 10);
      const delayMs = retryAfterSec > 0
        ? retryAfterSec * 1000
        : Math.pow(2, attempt) * 1000; // 헤더 없을 때만 지수 백오프 fallback

      console.log(`429 received. Retrying after ${delayMs}ms...`);
      await new Promise(resolve => setTimeout(resolve, delayMs));
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

2. 응답 캐싱

변경이 잦지 않은 데이터(Templates, BookSpecs 등)는 파트너 측에 캐싱하여 불필요한 API 호출을 줄이세요. 템플릿 목록은 일반적으로 하루 단위로 캐시해도 무방합니다.

3. 개별 조회보다 목록 API 활용

여러 건의 데이터가 필요하면 개별 조회를 반복하지 말고 목록 API를 활용해 한 번에 받아오세요. 예를 들어 주문 10건을 확인하려면 10회 개별 조회 대신 GET /orders?limit=10로 1회에 처리하는 편이 효율적입니다.

페이지네이션 상세는 페이지네이션 가이드를 참고하세요.

4. Idempotency-Key와 함께 사용

429 재시도 시 POST 엔드포인트에서 중복 처리(이중 차감 등)를 피하려면 Idempotency-Key 헤더를 함께 사용하세요. 같은 키로 재시도하면 첫 응답이 반환되어 안전합니다.

상세는 멱등성 (Idempotency) 문서를 참고하세요.