본문 바로가기
🤖 1인 에이전트 구축기

LLM API 토큰 계산과 사용자별 비용 한도 설계 가이드

by BRIEFER 2026. 6. 12.

LLM API를 운영하는 1인 사업자와 소규모 개발팀이라면, 호출 전 예상 비용을 예약하고 응답의 usage로 정산하며 사용자·조직 한도를 원자적으로 적용해야 한다. 이 글은 실제 API 키나 유료 호출 없이 그 구조를 구현하고 검증하는 방법을 설명한다.

핵심 답: 토큰 수를 화면에 표시하는 것만으로는 비용을 통제할 수 없다. 사전 추정 → 사용자·조직 예산 동시 예약 → API 호출 → 실제 usage 정산 → 경고·차단·복구를 하나의 상태 흐름으로 만들어야 한다.

공식 문서와 가격은 2026년 7월 20일에 확인했다. 모델·단가·사용량 등급은 바뀔 수 있으므로 배포 전 OpenAI API 가격표와 계정의 Limits 화면을 다시 확인한다.

먼저 결정할 네 가지

결정 항목 권장 시작점 이유
과금 원장 정수 마이크로달러 또는 정수 포인트 부동소수점 오차를 피하고 원자적 증가 연산을 쓰기 쉽다.
사전 예약액 예상 입력 비용 + 허용할 최대 출력 비용 + 도구 비용 여유분 동시 요청이 한도를 통과한 뒤 한꺼번에 과금되는 일을 줄인다.
한도 계층 요청 → 사용자 → 조직/프로젝트 → 공급자 한도 한 사용자의 과다 사용과 전체 계정 중단을 별도로 제어한다.
한도 도달 정책 경고, 기능 축소, 하드 차단, 관리자 승인 중 선택 모든 서비스에 같은 80% 경고·100% 차단 규칙이 적합한 것은 아니다.

OpenAI의 rate limit은 RPM·TPM 등 여러 지표 중 먼저 닿는 제한으로 결정되며, 공식 문서상 조직 및 프로젝트 수준에 적용되고 애플리케이션 최종 사용자 수준의 한도는 아니다. 따라서 SaaS 사용자의 일·월 예산은 서비스가 직접 구현해야 한다. 자세한 공급자 제한은 OpenAI Rate limits에서 확인할 수 있다.

토큰 비용 계산식: 단가를 코드에 고정하지 않는다

텍스트 모델의 가장 단순한 호출 비용은 다음처럼 계산한다.

입력 비용 = 입력 토큰 × 입력 단가(토큰 100만 개당) ÷ 1,000,000
출력 비용 = 출력 토큰 × 출력 단가(토큰 100만 개당) ÷ 1,000,000
호출 비용 = 입력 비용 + 출력 비용 + 도구 호출·저장소 등 별도 비용

실제 청구 항목은 모델과 기능에 따라 더 세분될 수 있다. 예를 들어 캐시된 입력은 별도 단가가 적용될 수 있고, 웹 검색·파일 검색·컨테이너 같은 도구는 토큰 외 요금이 붙을 수 있다. 공식 가격 문서도 선택한 모델의 입력·출력 토큰 요금과 일부 도구 요금을 구분한다. 그러므로 다음 값을 버전이 있는 설정 테이블로 관리한다.

{
  "price_version": "checked-2026-07-20",
  "model": "YOUR_MODEL_ID",
  "currency": "USD",
  "input_usd_per_million": "VERIFY_ON_OFFICIAL_PRICE_PAGE",
  "cached_input_usd_per_million": "VERIFY_OR_NULL",
  "output_usd_per_million": "VERIFY_ON_OFFICIAL_PRICE_PAGE",
  "tool_fees": {}
}

실제 숫자 대신 문자열 placeholder를 쓴 이유는 이 원고가 오래된 단가를 재배포하지 않도록 하기 위해서다. 운영에서는 가격표 확인자·확인일·적용 시작 시각을 함께 저장하고, 계산 로그에는 사용한 price_version을 남긴다.

정수 단위로 계산하는 로컬 예제

다음 코드는 네트워크와 API 키가 필요 없다. 단가는 현재 OpenAI 가격이 아닌 계산 검증용 가상 값이다. 예약액은 한도를 느슨하게 만들지 않도록 마이크로달러 단위에서 올림한다.

from decimal import Decimal, ROUND_CEILING

MICRO_USD = Decimal("1000000")
TOKENS_PER_M = Decimal("1000000")


def token_cost_microusd(
    input_tokens: int,
    output_tokens: int,
    input_usd_per_m: Decimal,
    output_usd_per_m: Decimal,
) -> int:
    """쿼터 예약용 비용을 정수 마이크로달러로 반환한다."""
    usd = (
        Decimal(input_tokens) * input_usd_per_m
        + Decimal(output_tokens) * output_usd_per_m
    ) / TOKENS_PER_M
    return int(
        (usd * MICRO_USD).to_integral_value(rounding=ROUND_CEILING)
    )


input_price = Decimal("1.00")  # 현재 단가가 아닌 로컬 검증용 가상 값
output_price = Decimal("4.00")

costs = []
for i in range(100):
    input_tokens = 800 + (i % 5) * 100
    output_tokens = 200 + (i % 4) * 50
    costs.append(
        token_cost_microusd(
            input_tokens,
            output_tokens,
            input_price,
            output_price,
        )
    )

print(f"requests={len(costs)}")
print(f"reserved_micro_usd={sum(costs)}")
print(f"reserved_usd={Decimal(sum(costs)) / MICRO_USD:.6f}")

2026년 7월 20일 Python 3.14.4에서 실행한 결과다.

requests=100
reserved_micro_usd=210000
reserved_usd=0.210000

이 결과는 가상 단가와 모의 토큰 데이터의 산술 검증일 뿐, 특정 모델의 비용 사례나 절감 효과가 아니다.

tiktoken 추정값과 API usage가 다른 이유

한글이 영어보다 항상 몇 배 많은 토큰을 쓴다고 일반화할 수는 없다. 토큰 수는 모델의 인코딩, 문장 내용, 공백, 숫자·기호, 메시지 포맷, 도구 스키마에 따라 달라진다. 같은 문장도 인코딩이 바뀌면 분할 결과가 달라질 수 있으므로 서비스의 실제 입력 표본으로 측정해야 한다.

OpenAI의 현재 Counting tokens 가이드는 로컬 tiktoken이 일반 텍스트 추정에는 유용하지만 이미지·파일을 처리하지 못하고, 도구와 스키마가 추가하는 토큰이나 모델별 포맷을 정확히 반영하기 어렵다고 설명한다. 같은 문서는 Responses API 형식의 입력을 보내 정확한 입력 토큰 수를 받는 POST /v1/responses/input_tokens도 안내한다. 이 엔드포인트 사용 여부와 호출 조건은 배포 시 최신 문서를 다시 확인한다.

공식 Cookbook의 tiktoken 예제는 현재 보관된(archived) 문서이며, 채팅 메시지 계산값을 영구 보장이 아닌 추정치로 보라고 명시한다. 따라서 다음 코드는 호출 전 빠른 로컬 방어선으로만 사용한다.

import tiktoken


def estimate_plain_text_tokens(text: str, model: str) -> int:
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError as exc:
        # 임의의 인코딩으로 조용히 대체하면 과소 추정할 수 있다.
        raise ValueError(f"지원하지 않는 모델 인코딩: {model}") from exc
    return len(encoding.encode(text))


sample = "환불 정책을 세 문장으로 요약해 주세요."
print(estimate_plain_text_tokens(sample, "YOUR_SUPPORTED_MODEL_ID"))

설치 명령은 python -m pip install tiktoken이다. 모델 ID는 배포 환경에서 실제 사용하는 값으로 바꾸고, 라이브러리와 인코딩이 그 모델을 지원하는지 테스트해야 한다. 이 예제는 평문만 세며 실제 유료 API를 호출하지 않는다.

무엇을 최종 원장으로 삼을까

시점 용도 한계
호출 전 tiktoken 로컬 추정 빠른 길이 검사, 대략적인 예약 메시지 포맷·도구·이미지·파일에서 차이 가능
호출 전 공식 입력 토큰 계산 API 결과 실제 payload의 입력 수 확인 별도 네트워크 요청과 지연을 고려해야 함
호출 후 API 응답 usage 실제 사용량 정산의 1차 근거 타임아웃·연결 종료 시 응답을 받지 못할 수 있음
사후 공급자 Usage/Costs 데이터와 청구 내역 누락·불일치 대사 실시간 차단 경로로만 쓰기에는 지연 가능

Responses API는 usage.input_tokensusage.output_tokens를 보고한다. 공식 토큰 계산 문서에 따르면 출력 토큰은 화면에 보이는 텍스트만이 아니라 모델이 생성한 모든 토큰을 포함할 수 있다. 따라서 출력 문자열을 다시 tiktoken으로 세어 청구량으로 덮어쓰지 않는다.

사용자·조직 한도를 함께 설계하는 상태 흐름

요청 수신
  → 사용자 인증·플랜 확인
  → 입력 토큰 추정과 최대 출력 설정
  → 예상 최대 비용 계산
  → 사용자 한도와 조직 한도를 한 트랜잭션으로 예약
  → LLM API 호출
  → 응답 usage로 실제 비용 계산
  → 예약액과 실제액의 차이 정산
  → 사용량 이벤트 저장·모니터링

예약 전에 입력 길이와 max_output_tokens를 제한한다. 공급자 rate limit 문서는 출력 상한을 예상 응답 크기에 가깝게 설정하는 것이 제한 관리에 도움이 된다고 안내한다. 다만 너무 낮은 상한은 응답을 잘라낼 수 있으므로 기능별 품질 테스트가 먼저다.

한도 키에는 최소한 다음 차원을 둔다.

  • request_id: 중복 처리와 사후 추적용
  • user_id: 고객별 일·월 한도
  • org_id 또는 내부 tenant: 전체 비용 보호
  • projectenvironment: 개발·스테이징·운영 분리
  • period: UTC 기준 일/월 버킷과 시작·종료 시각
  • model, price_version: 계산 재현용
  • estimated_tokens, reserved_cost, actual_usage, actual_cost
  • status: reserved, settled, uncertain, reconciled, rejected

OpenAI의 Production best practices는 스테이징과 운영을 프로젝트로 분리하고 프로젝트별 접근·rate/spend limit을 관리하는 방식을 안내한다. 그러나 공급자 프로젝트 한도는 서비스의 사용자별 원장을 대신하지 않는다.

soft limit과 hard limit은 목적이 다르다

Soft limit은 사용을 막지 않고 경고하거나 기능을 낮춘다. 예를 들어 관리자에게 알림을 보내고, 고비용 모델이나 도구를 비활성화하고, 사용자가 예산 증액을 요청하게 할 수 있다.

Hard limit은 새 API 호출 전에 요청을 거절한다. 선불 크레딧, 무료 체험, 공개형 API처럼 초과 비용을 사업자가 부담하는 서비스에 적합하다. 다만 이미 시작된 스트리밍 요청이나 응답을 받지 못한 요청의 비용까지 되돌릴 수는 없다.

정책 적합한 상황 도달 시 동작 주의점
알림만 내부 도구, 예산 관찰 단계 관리자·사용자 알림 초과 지출을 막지 못한다.
grace 구간 유료 고객의 업무 연속성이 중요 제한 모델로 전환, 짧은 출력만 허용 grace 최대액을 별도로 제한한다.
hard stop 무료 체험, 선불 크레딧, 공개 API 호출 전 402 또는 서비스 정의 오류 고객 지원·증액 경로를 제공한다.
수동 승인 일시적 대량 작업 요청 큐 보류 후 관리자 승인 승인 이력과 만료 시각이 필요하다.

OpenAI 프로젝트의 월 예산 알림은 애플리케이션의 사용자별 hard cap으로 가정하지 않는다. OpenAI Help Center의 Managing projects in the API platform은 프로젝트 월 예산을 soft threshold로 설명하며, 초과 후에도 요청 처리가 계속될 수 있다고 안내한다. 정확한 계정 동작은 배포 시 Dashboard와 최신 도움말에서 재확인한다.

동시성 레이스: 조회 후 증가가 실패하는 이유

다음과 같은 두 단계 코드는 안전하지 않다.

현재 사용액 조회
if 현재 사용액 + 예약액 <= 한도:
    사용액 저장
    요청 허용

요청 100개가 동시에 같은 현재 사용액을 읽으면 모두 통과할 수 있다. 아래 로컬 테스트는 그 레이스를 의도적으로 재현하고, 잠금으로 보호한 원장과 비교한다. 실제 API, Redis, 비밀값은 사용하지 않는다.

from concurrent.futures import ThreadPoolExecutor
from threading import Barrier, Lock

REQUESTS = 100
LIMIT = 100
RESERVE = 10


class ForcedRaceLedger:
    """검증을 위해 의도적으로 깨뜨린 check-then-write 원장."""
    def __init__(self) -> None:
        self.used = 0
        self.barrier = Barrier(REQUESTS)

    def reserve(self) -> bool:
        snapshot = self.used
        self.barrier.wait()  # 100개 요청이 같은 값을 읽게 만든다.
        if snapshot + RESERVE > LIMIT:
            return False
        self.used = snapshot + RESERVE
        return True


class LockedLedger:
    def __init__(self) -> None:
        self.used = 0
        self.lock = Lock()

    def reserve(self) -> bool:
        with self.lock:
            if self.used + RESERVE > LIMIT:
                return False
            self.used += RESERVE
            return True


def run(ledger) -> tuple[int, int]:
    with ThreadPoolExecutor(max_workers=REQUESTS) as pool:
        admitted = sum(pool.map(lambda _: ledger.reserve(), range(REQUESTS)))
    return admitted, ledger.used


naive = run(ForcedRaceLedger())
atomic = run(LockedLedger())
print(f"naive admitted={naive[0]} final_reserved={naive[1]}")
print(f"atomic admitted={atomic[0]} final_reserved={atomic[1]}")

2026년 7월 20일 Python 3.14.4 실행 결과다.

naive admitted=100 final_reserved=10
atomic admitted=10 final_reserved=100

깨진 원장은 100개 요청을 허용하면서 최종 예약액은 10으로 덮어썼다. 원자적 원장은 한도 100에서 10개만 허용했다. 이 테스트는 동시성 결함을 보여주기 위한 통제된 재현이며 운영 처리량 벤치마크가 아니다.

Redis Lua로 사용자·조직 예산을 원자적으로 예약하기

단순 INCRBY 하나만으로는 증가 후 한도 초과를 되돌리는 사이에 다른 요청이 끼어들 수 있다. Lua 스크립트 안에서 두 한도 확인과 두 증가를 함께 수행한다.

-- KEYS[1]: 사용자-기간 키
-- KEYS[2]: 조직-기간 키
-- ARGV: 예약액, 사용자 한도, 조직 한도, TTL(초)
local reserve = tonumber(ARGV[1])
local user_limit = tonumber(ARGV[2])
local org_limit = tonumber(ARGV[3])
local ttl = tonumber(ARGV[4])

local user_used = tonumber(redis.call('GET', KEYS[1]) or '0')
local org_used = tonumber(redis.call('GET', KEYS[2]) or '0')

if user_used + reserve > user_limit then
  return {0, 'USER_LIMIT', user_used, org_used}
end
if org_used + reserve > org_limit then
  return {0, 'ORG_LIMIT', user_used, org_used}
end

local next_user = redis.call('INCRBY', KEYS[1], reserve)
local next_org = redis.call('INCRBY', KEYS[2], reserve)

if redis.call('TTL', KEYS[1]) < 0 then
  redis.call('EXPIRE', KEYS[1], ttl)
end
if redis.call('TTL', KEYS[2]) < 0 then
  redis.call('EXPIRE', KEYS[2], ttl)
end

return {1, 'OK', next_user, next_org}

운영 적용 전에는 다음 조건을 추가한다.

  1. 정수 단위만 사용한다. 예: 마이크로달러, 토큰, 내부 포인트.
  2. 기간을 키에 고정한다. quota:{org-123}:2026-07:user-456처럼 UTC 월 버킷을 명시한다.
  3. Redis Cluster hash tag를 맞춘다. 다중 키 Lua는 같은 hash slot에 있어야 하므로 위 예시처럼 {org-123} 부분을 공유한다.
  4. request_id 멱등성 원장을 별도로 둔다. 동일 요청 재전송이 두 번 예약되지 않게 한다.
  5. Redis를 유일한 회계 장부로 쓰지 않는다. 내구성 있는 데이터베이스나 이벤트 로그에 예약·정산 이벤트를 남기고 대사한다.
  6. TTL은 기간 종료보다 충분히 길게 둔다. 월말 직후 사후 정산이 가능하도록 보존 기간을 확보한다.

응답 후 정산

예약액이 300이고 실제 비용이 220이면 -80을 원자적으로 반영한다. 실제 비용이 330이면 +30을 기록하고 초과 이벤트를 발생시킨다. 이미 공급자 호출이 끝난 뒤이므로, 정산 단계에서 한도 초과를 발견했다고 실제 비용을 버리거나 300으로 잘라 기록하면 안 된다.

정산 규칙은 다음과 같다.

delta = actual_cost - reserved_cost
원장 사용액 += delta
요청 상태 = settled
actual_cost가 hard limit을 넘겼다면 overrun 이벤트 발행

과소 예약이 반복되면 모델·기능별 안전 여유분을 조정하되, 임의의 고정 배수보다 실제 비용 ÷ 예약 비용 분포를 측정해 정한다.

rate limit과 비용 한도를 혼동하지 않는다

제한 질문 대표 지표 구현 위치
공급자 rate limit 지금 이 속도로 보낼 수 있는가? RPM, TPM, RPD, TPD OpenAI 조직·프로젝트 + 앱의 큐/백오프
사용자 비용 한도 이 사용자가 더 써도 되는가? 일·월 비용, 크레딧 애플리케이션 원장
조직 비용 한도 전체 사업 예산 안인가? 월 누적 비용 앱 원장 + 공급자 Limits/알림
요청 크기 한도 한 요청이 너무 큰가? 입력 토큰, 최대 출력 API 진입부
동시성 한도 한 사용자가 슬롯을 독점하는가? in-flight 요청 수 세마포어·큐

OpenAI 공식 문서에 따르면 rate limit 정보는 응답 헤더의 x-ratelimit-remaining-requests, x-ratelimit-remaining-tokens, reset 관련 필드 등으로 확인할 수 있다. 429가 발생하면 무제한 재시도하지 말고 최대 횟수가 있는 지수 백오프와 지터를 적용한다. 실패한 요청도 분당 제한에 기여할 수 있다는 공식 경고가 있으므로 즉시 반복 전송은 해결책이 아니다.

더 큰 처리량이 필요하다고 무조건 동시 요청 수를 늘리면 TPM 또는 비용 한도에 먼저 닿을 수 있다. n8n 동시 실행과 처리량 제한을 설계할 때도 사용자 쿼터 예약을 워커 실행 전에 배치해야 한다. 429와 재시도 분기는 API 실패·재시도 운영 가이드의 정책과 연결하고, 키·프로젝트 분리는 API 키와 비용 통제를 보안 운영으로 확장하는 방법을 참고한다.

실패 정책: Redis·타임아웃·스트리밍을 어떻게 처리할까

1. 쿼터 저장소가 응답하지 않을 때

  • Fail-closed: 새 LLM 호출을 막는다. 무료 체험·선불·공개 API의 기본값으로 적합하다.
  • Fail-open: 제한적으로 호출을 허용한다. 내부 업무 중단 비용이 더 큰 경우에만, 사용자별 작은 비상 한도·짧은 만료·사후 대사를 함께 둔다.
  • 잘못된 방식: Redis 오류를 무조건 0원 사용으로 간주한다. 장애 시간 동안 모든 요청이 한도를 우회한다.

2. API 타임아웃 또는 연결 종료

응답을 못 받았다고 비용이 0이라고 단정하지 않는다. 예약을 즉시 전액 환불하지 말고 uncertain 상태로 보류한 뒤 공급자 Usage/Costs 데이터와 대사한다. 동일 요청을 재시도할 때는 새 request_id를 무작정 만들지 말고 업무 멱등성, 이전 요청 상태, 최대 재시도 횟수를 확인한다.

3. 스트리밍 중 클라이언트가 끊겼을 때

브라우저 연결 종료와 공급자 생성 중단이 같은 사건이라고 가정하지 않는다. 서버가 upstream 취소를 전달했는지 기록하고, 가능하면 최종 usage 이벤트를 수집한다. 확인하지 못한 요청은 uncertain 대사 큐로 보낸다.

4. 월 경계와 시간대

사용자 화면의 현지 시간과 회계 원장의 기간을 섞지 않는다. 원장은 UTC 시작·종료 시각을 저장하고, 화면에서만 사용자 시간대로 변환한다. 기간 키를 현재 시각으로 다시 계산해 정산하면 월 경계에서 다른 버킷을 수정할 수 있으므로 예약 때 결정한 period를 그대로 사용한다.

5. 공급자 한도 또는 가격 설정이 바뀌었을 때

가격 설정은 즉시 덮어쓰지 말고 새 price_version을 만든다. 이미 예약된 요청은 예약 당시 버전, 새 요청은 새 버전을 사용한다. rate limit과 사용량 등급은 계정·모델에 따라 달라질 수 있으므로 문서의 예시 수치를 코드 상수로 복사하지 않고 Dashboard에서 확인한다.

모니터링에 남길 최소 지표

  • 사용자·조직별 reserved_cost, actual_cost, delta
  • 추정 입력 토큰과 실제 usage.input_tokens의 오차
  • 최대 출력 예약량과 실제 usage.output_tokens의 차이
  • 한도 거절 수와 사유: 사용자, 조직, 요청 크기, 동시성
  • uncertain 요청 수·금액·최장 미정 시간
  • 모델·기능·price_version별 비용
  • 429 수, 재시도 횟수, 최종 실패율
  • soft limit 알림 후 사용량 변화와 hard stop 횟수

사용자 ID, 프롬프트 원문, 고객 정보는 비용 로그에 불필요하게 복제하지 않는다. 비용 대사에 필요한 식별자는 내부 난수 ID로 연결하고 로그 접근 권한과 보존 기간을 제한한다.

배포 전 체크리스트

  • 기존 URL https://joshua12.com/entry/28과 canonical을 유지한다.
  • 공식 가격표에서 실제 모델의 입력·캐시 입력·출력·도구 단가를 재확인한다.
  • 가격 설정에 확인일과 price_version이 있다.
  • 입력 길이와 최대 출력 토큰을 기능별로 제한한다.
  • tiktoken은 사전 추정, API usage는 사후 정산 근거로 구분한다.
  • 사용자 한도와 조직 한도를 하나의 원자적 연산으로 예약한다.
  • 동시 요청 테스트에서 누적 예약액이 hard limit을 넘지 않는다.
  • soft limit, grace, hard stop, 관리자 승인 중 서비스 정책을 문서화한다.
  • Redis 장애 시 fail-open/closed 정책과 비상 한도가 있다.
  • 타임아웃·스트리밍 중단 요청을 uncertain으로 대사한다.
  • 429 재시도에 지수 백오프, 지터, 최대 횟수가 있다.
  • 개발·스테이징·운영 프로젝트와 자격 증명을 분리한다.
  • 실제 API 키·프롬프트·고객정보가 코드와 로그에 없다.
  • 모바일에서 표의 가로 스크롤과 코드 줄바꿈을 확인한다.
  • 사람의 사실 검토와 CMS 미리보기 승인 후 발행한다.

자주 묻는 질문

한글은 영어보다 토큰이 더 많이 드나?

문자 수만으로 고정 배수를 적용하면 안 된다. 언어뿐 아니라 모델 인코딩과 실제 문장에 따라 결과가 달라진다. 배포 모델과 대표 입력 표본을 tiktoken 또는 공식 입력 토큰 계산 API로 측정하고, 호출 후 usage와 비교한다.

tiktoken 값으로 바로 사용자에게 과금해도 되나?

권장하지 않는다. 로컬 추정은 호출 전 예약과 길이 검사에 쓰고, 최종 정산은 API가 보고한 usage와 적용 단가를 기준으로 한다. 이미지·파일·도구·메시지 포맷이 있으면 차이가 커질 수 있다.

사용자 한도에 토큰과 비용 중 무엇을 쓰는 게 좋은가?

비용 보호가 목적이면 통화 또는 내부 크레딧이 이해하기 쉽다. 다만 모델별 단가가 다르므로 토큰 수도 함께 기록해야 원인을 설명할 수 있다. 요청 수·토큰·비용·동시성은 서로 다른 제한이므로 하나만으로 모두 대체하지 않는다.

공급자 프로젝트 예산을 설정하면 자체 hard limit은 없어도 되나?

아니다. 프로젝트 예산 알림과 조직 사용 한도는 최종 사용자별 정책이 아니다. 사용자별 선불·무료 체험·플랜 한도는 애플리케이션에서 호출 전에 원자적으로 검사해야 한다.

한도에 도달하면 항상 즉시 차단해야 하나?

서비스 성격에 따라 다르다. 공개 무료 API는 hard stop이 합리적일 수 있고, 내부 핵심 업무는 작은 grace 구간과 관리자 알림이 적합할 수 있다. fail-open을 선택한다면 최대 금액·기간·대상과 사후 대사를 반드시 제한한다.

공식 문서와 확인일