빌링 API

콘솔을 열지 않고도 자신의 워크스페이스의 사용량과 비용 데이터를 자체 시스템으로 가져올 수 있습니다. 빌링 키는 읽기 전용 자격 증명이며 하나의 워크스페이스로 범위가 제한됩니다 - 청구 데이터를 읽을 수 있을 뿐, 그 외에는 아무것도 할 수 없습니다.

⚠

빌링 키는 이후에 삭제되거나 폐기된 키를 포함하여 해당 워크스페이스에 기록된 모든 요청을 읽을 수 있지만, 모델을 호출할 수 없으며 API 키를 생성, 수정, 삭제할 수도 없습니다. 이 외의 다른 곳에서 사용하면 401 wrong_key_kind.

ℹ

Billing API는 billing.read 스코프가 있는 관리 키(sk-syn-admin-)로 호출합니다. 스코프가 없으면 403 insufficient_scope를 반환합니다. 관리 키 도입 전에 발급된 빌링 키(sk-syn-bill-)는 계속 작동하지만 새로 발급되지는 않습니다.

빌링 키 만들기

  1. 열기: Console → API 키 → 관리 키 (워크스페이스 관리자와 소유자 가능). 이름을 지정하고 billing.read 스코프를 선택한 뒤, 필요하면 IP 허용 목록으로 제한하거나 만료일을 설정한 다음 키를 복사하세요 - 키는 sk-syn-admin- 로 시작하며 한 번만 표시됩니다.
  2. 이를 Bearer 토큰으로 사용해 아래 엔드포인트를 호출하세요. 같은 페이지에서 언제든지 폐기할 수 있습니다 - 폐기하면 즉시 무효화되며 워크스페이스의 다른 것에는 영향이 없습니다.
  3. 워크스페이스 소유 키가 아니라면 키는 만든 사람에게 묶여 있습니다. 만든 사람이 워크스페이스의 관리자나 소유자 역할을 잃으면 키는 작동을 멈추고 다음 오류를 반환합니다: 403 key_owner_not_authorized.

인증

모든 호출에는 Authorization: Bearer sk-syn-admin-... 를 아래 기본 URL에 대해 보내야 합니다. 빌링 키는 이 엔드포인트에서만 동작하며, 이 엔드포인트도 빌링 키만 허용합니다 - 그 외의 조합은 401 wrong_key_kind.

Authorization: Bearer sk-syn-admin-...

Base URL: https://synthorai.io/api/v1/billing

ℹ

범위는 워크스페이스 전체입니다. 삭제된 키를 포함하여 그 안의 모든 추론 키가 대상이며, 이력 행은 계속 조회할 수 있습니다. api_key_id 및 model 필터는 결과를 좁히기만 할 수 있으며 넓힐 수는 없습니다. 모든 조회는 항상 그 키 자신의 워크스페이스로 고정됩니다.

ℹ

모든 조회는 읽기 전용 레플리카에서 실행되며 프라이머리에서는 실행되지 않습니다. 레플리카가 설정되지 않은 프로세스는 503 replica_unavailable 조용히 대체(fallback)되지 않습니다.

✓

토큰 필드: OpenAI 규칙을 따릅니다 - prompt_tokens 은 총 입력 토큰 수이며 아래의 모든 캐시 읽기와 캐시 쓰기를 이미 포함합니다. 그리고 completion_tokens 은 이미 reasoning_tokens를 포함합니다. 둘 다 합계에 추가로 더해지는 것이 아니라 세부 내역일 뿐, 별도의 토큰이 아닙니다.

prompt_tokens 중 캐시 읽기 부분이 cached_tokens이고, 캐시 쓰기 부분이 cache_write_tokens입니다. /records 행에서는 TTL에 따라 cache_write_5m_tokens와 cache_write_1h_tokens로 더 세분화됩니다.

✓

금액 필드: cost_usd 은 실제로 청구된 금액입니다. byok_list_price_usd 은 BYOK 요청이 정가로 부과되었을 경우의 비용입니다 (BYOK가 아니면 0). list_price_usd 이 API 어디에도 존재하지 않습니다.

ℹ

여기서 "오류"는 API에 도달했지만 거부된 모든 요청을 의미합니다 - 402(잔액 부족), 403, 429 같은 4xx뿐 아니라 업스트림 실패도 포함됩니다. 제외되는 것은 우리 자체 내부 인프라 거부뿐이며, 콘솔과 동일한 기준입니다. 거부된 요청은 서버마다 key, 상태 코드, 분 단위로 최대 한 번 기록되므로 402, 403, 429 횟수는 하한값입니다. 성공한 요청과 과금은 완전합니다.

GET /usage - 집계 사용량

GET /usage

시간 또는 일 단위로 미리 집계된 행으로, 청구서와 대시보드용입니다. 시간별 롤업에 마지막 수집 이후 기록된 요청을 더하므로, 최근 버킷이 수집 주기 하나만큼 통째로 뒤처지지 않습니다.

매개변수유형설명
start*string범위 시작: RFC 3339 타임스탬프 또는 2026-09-01과 같은 날짜.
endstring범위 종료. 기본값은 현재 시각입니다.
granularitystring버킷 크기: hour 또는 day. 기본값은 day입니다.
group_bystring행을 나눌 차원: api_key, model, 또는 둘 다 (임의의 부분집합). 기본값은 둘 다입니다.
api_key_idinteger하나 이상의 API 키 id로 필터링합니다. 반복 가능하며 범위를 좁히기만 하고 넓히지 않습니다.
modelstring하나 이상의 모델 id로 필터링합니다. 반복 가능합니다.
limitinteger페이지당 행 수. 기본값 1000, 최대 5000.
cursorstring이전 페이지의 meta.next_cursor에서 가져온, 불투명한 페이지네이션 커서.

각 행에서 api_key_id와 api_key_name은 group_by api_key를 포함할 때만 나타나며, model도 마찬가지로 model을 포함할 때만 나타납니다. 버킷에 지연 시간 샘플이 없으면 avg_latency_ms가 null일 수 있습니다.

요청 예시

curl "https://synthorai.io/api/v1/billing/usage?start=2026-09-01&end=2026-09-24&granularity=day" \
  -H "Authorization: Bearer sk-syn-admin-..."

응답 예시

{
  "data": [
    {
      "bucket_start": "2026-09-23T00:00:00Z",
      "bucket_end": "2026-09-24T00:00:00Z",
      "api_key_id": 42,
      "api_key_name": "prod-backend",
      "model": "claude-sonnet-5",
      "requests": 1280,
      "success_requests": 1265,
      "error_requests": 15,
      "errors_4xx": 12,
      "errors_429": 2,
      "errors_5xx": 1,
      "prompt_tokens": 512000,
      "completion_tokens": 98000,
      "cached_tokens": 210000,
      "cache_write_tokens": 8000,
      "reasoning_tokens": 4000,
      "cost_usd": 4.1732,
      "byok_list_price_usd": 0,
      "byok_requests": 0,
      "avg_latency_ms": 812,
      "final": true
    }
  ],
  "meta": {
    "generated_at": "2026-09-24T08:00:00Z",
    "data_complete_until": "2026-09-24T06:00:00Z",
    "timezone": "UTC",
    "currency": "USD",
    "next_cursor": null,
    "has_more": false
  }
}

GET /records - 요청 단위 행

GET /records

요청마다 한 행이며, 자체 데이터베이스로의 증분 동기화를 위한 것입니다. cursor로 동기화하세요. 절대 시간으로 동기화하지 마세요. 수신한 행은 record_id로 중복 제거하세요 - 이유는 아래 "시간 공백 피하기"를 참고하세요.

매개변수유형설명
cursorstring이전 호출의 meta.next_cursor에서 가져온, 불투명한 동기화 커서(문자열). cursor와 start 중 정확히 하나만 지정하세요. 범위 제한이 없습니다.
startstring범위 시작 (RFC 3339 타임스탬프 또는 날짜). cursor와 start 중 하나만 지정하세요. start/end 범위는 최대 31일이지만, cursor에는 범위 제한이 없습니다.
endstring범위 종료. 기본값은 현재 시각입니다.
api_key_idinteger하나 이상의 API 키 id로 필터링합니다. 반복 가능하며 범위를 좁히기만 하고 넓히지 않습니다.
modelstring하나 이상의 모델 id로 필터링합니다. 반복 가능합니다.
limitinteger페이지당 행 수. 기본값 500, 최대 1000.

요청 예시

curl "https://synthorai.io/api/v1/billing/records?start=2026-09-24T00:00:00Z&limit=500" \
  -H "Authorization: Bearer sk-syn-admin-..."

응답 예시

{
  "data": [
    {
      "record_id": "rec_8f2a91c4",
      "request_id": "req_9f3c2b1a",
      "recorded_at": "2026-09-24T05:58:31Z",
      "completed_at": "2026-09-24T05:58:29Z",
      "api_key_id": 42,
      "api_key_name": "prod-backend",
      "model": "claude-sonnet-5",
      "status": "success",
      "status_code": 200,
      "prompt_tokens": 812,
      "completion_tokens": 194,
      "cached_tokens": 512,
      "cache_write_tokens": 64,
      "cache_write_5m_tokens": 64,
      "cache_write_1h_tokens": 0,
      "cost_usd": 0.00412,
      "byok_list_price_usd": 0,
      "is_byok": false,
      "is_stream": true,
      "duration_ms": 1340,
      "ttft_ms": 210
    }
  ],
  "meta": {
    "next_cursor": "eyJvIjoiODgxNDA5MCJ9",
    "has_more": false,
    "window_final": true,
    "safe_until": "2026-09-24T05:58:31Z",
    "latest_recorded_at": "2026-09-24T05:58:31Z",
    "data_complete_until": "2026-09-24T05:58:00Z"
  }
}
매개변수설명
next_cursor다음 호출을 위한 커서입니다. 항상 존재합니다.
has_more지금 이 커서로 다시 호출하면 더 많은 행이 반환되는지 여부입니다.
window_finalend를 지정했고 그것이 safe_until 이전이거나 같을 때만 true입니다 - 그때 요청한 범위가 완전함이 보장됩니다. 그 외에는 없거나 false입니다.
safe_until호출자가 확정된 것으로 신뢰할 수 있는 가장 최근의 recorded_at입니다. 이보다 최신인 행은 아직 보류 중입니다.
latest_recorded_at확정 여부와 관계없이 모든 행 중 가장 최근의 recorded_at입니다.
data_complete_until/freshness가 반환하는 값과 동일합니다 - 시간별 롤업이 어디까지 완료되었는지를 나타내며, /usage와 상호 대조하는 데 사용합니다.
⚠

시간 기준: /usage는 completed_at 로 버킷화됩니다 (요청이 완료된 시각). /records의 start/end 필터는 recorded_at 로 필터됩니다 (행이 기록된 시각으로, 부하가 높을 때는 완료 시각보다 늦을 수 있습니다). /records를 /usage와 맞추려면 동기화한 행을 recorded_at이 아니라 completed_at 기준으로 직접 버킷화하세요.

GET /records/export - 스트리밍 내보내기

GET /records/export

/records와 동일한 필터를 사용하며, 줄바꿈으로 구분된 JSON(application/x-ndjson)으로 스트리밍됩니다 - 페이지가 나뉜 목록이 아니라 대규모 백필용으로 만들어졌습니다. 한 워크스페이스당 한 번에 하나의 내보내기만 스트리밍할 수 있으며, 두 번째는 429 too_many_concurrent_requests를 받습니다.

요청 예시

curl -N "https://synthorai.io/api/v1/billing/records/export?cursor=eyJvIjoiODgxNDAzMiJ9" \
  -H "Authorization: Bearer sk-syn-admin-..."

응답 예시

{"record_id":"rec_8f2a91c4","request_id":"req_9f3c2b1a","model":"claude-sonnet-5","status":"success","cost_usd":0.00412}
{"record_id":"rec_8f2a91c5","request_id":"req_9f3c2b1b","model":"claude-sonnet-5","status":"success","cost_usd":0.00398}
{"_meta":{"next_cursor":"eyJvIjoiODgxNDA5MSJ9","rows":2,"complete":true,"window_final":true,"generated_at":"2026-09-24T06:00:02Z"}}

스트림의 마지막 줄은 _meta 객체입니다:

매개변수설명
next_cursor다음 내보내기 호출을 위한 커서입니다.
rows이 스트림에서 기록된 레코드 수.
completefalse는 범위를 모두 처리하기 전에 스트림이 멈췄다는 뜻입니다 - cursor=next_cursor로 재개하세요.
window_final/records와 동일한 의미입니다: 내보내기의 end가 safe_until 이전이거나 같을 때만 true입니다.
generated_at이 줄이 기록된 시각입니다.
stopped_becausecomplete가 false일 때 표시됩니다: row_cap, scan_cap(한 번에 훑을 수 있는 최대 id 범위를 다 훑었지만 결과가 차지 않음. 필터가 좁을 때 흔함), time_cap, query_error, window_not_final.

GET /summary - 예비 통계 및 이상

GET /summary

총계, 비용 기준 상위 모델 및 상위 키, 해당 범위의 오류율, 그리고 anomalies 목록(high_error_rate, rate_limited, data_not_final, rollup_delayed)이 추가됩니다. 각각 info 또는 warning의 심각도와 사람이 읽을 수 있는 메시지를 포함합니다. 아직 확정되지 않은 범위의 숫자는 여전히 바뀔 수 있습니다 - 아래를 참고하세요.

매개변수유형설명
startstring범위 시작. 기본값은 end 이전 30일입니다.
endstring범위 종료. 기본값은 현재 시각입니다.
api_key_idinteger하나 이상의 API 키 id로 필터링합니다. 반복 가능하며 범위를 좁히기만 하고 넓히지 않습니다.
modelstring하나 이상의 모델 id로 필터링합니다. 반복 가능합니다.

models_count와 keys_count는 top_models와 top_keys의 배후 총계를 나타내며, 이 목록들은 비용 기준 상위 최대 20개까지만 나열합니다. end 이전 30일이, start 가 생략된 경우의 기본 범위입니다.

요청 예시

curl "https://synthorai.io/api/v1/billing/summary?start=2026-09-17&end=2026-09-24" \
  -H "Authorization: Bearer sk-syn-admin-..."

응답 예시

{
  "data": {
    "totals": { "requests": 48210, "cost_usd": 132.55, "error_rate": 0.021 },
    "models_count": 6,
    "keys_count": 3,
    "top_models": [ { "model": "claude-sonnet-5", "cost_usd": 88.10, "byok_list_price_usd": 0 } ],
    "top_keys": [ { "api_key_id": 42, "api_key_name": "prod-backend", "cost_usd": 61.30, "byok_list_price_usd": 0 } ],
    "anomalies": [
      { "type": "data_not_final", "severity": "info", "message": "The last 2 hours of this range are not yet final." }
    ]
  },
  "meta": {
    "generated_at": "2026-09-24T06:00:02Z",
    "data_complete_until": "2026-09-24T04:00:00Z"
  }
}

GET /freshness - 데이터 완전성

GET /freshness

반환되는 값은 data_complete_until, latest_recorded_at, safe_until 및 pipeline_lag_seconds - 방금 가져온 범위를 확정된 것으로 간주하기 전에 이를 폴링하세요. safe_until은 호출자가 완전하다고 신뢰할 수 있는 가장 최근의 recorded_at입니다. 그보다 최신인 행은 아직 도착 중일 수 있습니다.

요청 예시

curl "https://synthorai.io/api/v1/billing/freshness" \
  -H "Authorization: Bearer sk-syn-admin-..."

응답 예시

{
  "data": {
    "data_complete_until": "2026-09-24T04:00:00Z",
    "latest_recorded_at": "2026-09-24T05:58:31Z",
    "safe_until": "2026-09-24T05:58:31Z",
    "pipeline_lag_seconds": 47
  },
  "meta": { "generated_at": "2026-09-24T06:00:02Z" }
}

GET /balance - 워크스페이스에서 지금 쓸 수 있는 잔액

GET /balance

워크스페이스의 현재 사용 가능 잔액을 반환하며, 콘솔에 표시되는 사용 가능 잔액과 같습니다. 폴링용으로 설계되어 30~60초마다 확인하면 충분합니다. 별도의 속도 제한을 사용하므로 폴링이 데이터 엔드포인트의 한도를 소모하지 않으며, 잔액이 0일 때도 응답합니다.

요청 예시

curl "https://synthorai.io/api/v1/billing/balance" \
  -H "Authorization: Bearer sk-syn-admin-..."

응답 예시

{
  "data": {
    "available_usd": 1284.37,
    "debt_usd": 0,
    "source": "live",
    "voucher": null,
    "scheduled_credits": [
      { "amount_usd": 250, "release_at": "2026-10-01T00:00:00Z" }
    ],
    "scheduled_credit_total_usd": 250
  },
  "meta": { "generated_at": "2026-09-24T06:00:02Z", "currency": "USD" }
}
매개변수설명
available_usd현재 요청 과금에 쓰이는 일반 잔액. 0 아래로 내려가지 않습니다. 처리 중인 요청이 정산되면서 잠시 늘어날 수 있으며, 사용액은 /usage 또는 /records를 사용하세요.
debt_usd미납 잔액: 충전액을 초과한 사용분입니다. 미납이 없으면 0입니다. 충전 시 미납 잔액이 먼저 차감되고, 남은 금액만 available_usd가 됩니다.
sourcelive: 실시간 원장에서 읽은 값. delayed: 원장에 접근할 수 없어 최대 약 30초 늦을 수 있는 데이터베이스 사본에서 가져온 값.
voucher프로모션/바우처 크레딧으로 이미지 생성 전용(applies_to)이며, 나열된 모델 패턴에서 expires_at까지 사용할 수 있습니다. 다른 요청은 available_usd만 사용하며 이 금액은 available_usd에 포함되지 않습니다. 없으면 null, 만료 후에는 active가 false입니다.
scheduled_credits이미 합의되어 분할 지급되는 크레딧(amount_usd, release_at). 각 회차는 release_at 후 약 10분 이내에 잔액에 더해지며 그 전에는 사용할 수 없습니다. scheduled_credit_total_usd는 그 합계입니다.

오류

모든 오류는 {"error": {"type", "message", "hint"}}:

{
  "error": {
    "type": "range_too_large",
    "message": "the requested range exceeds this endpoint's cap",
    "hint": "narrow start/end to at most 31 days, or sync /records with a cursor instead"
  }
}
유형HTTP 상태의미
invalid_parameter400쿼리 매개변수가 누락되었거나, 형식이 잘못되었거나, 범위를 벗어났습니다.
range_too_large400요청한 시간 범위 또는 id 윈도우가 해당 엔드포인트가 허용하는 범위보다 큽니다. hint에 해당 한도의 이름이 표시됩니다.
start_too_recent400start/end 기간의 시작이 safe_until보다 늦어 시작 경계가 아직 확정되지 않았습니다. Retry-After 헤더의 시간 후 다시 시도하거나 cursor로 동기화하세요.
wrong_key_kind401이 자격 증명은 빌링 키가 아니거나, 빌링 키가 이 엔드포인트 외부에서 사용되었습니다.
authentication_error401키가 누락되었거나, 무효하거나, 만료되었거나, IP 허용 목록에 의해 차단되었습니다.
key_owner_not_authorized403키를 만든 사람이 더 이상 워크스페이스의 관리자나 소유자가 아닙니다. 결제 데이터를 읽는 키는 워크스페이스 소유 키가 아닌 한, 만든 사람이 그 역할을 유지하는 동안에만 작동합니다. 관리자나 소유자가 새 키를 만들어야 합니다.
rate_limited429이 워크스페이스에서 분당 60회를 초과한 요청이 발생했습니다. Retry-After 헤더에 표시된 시간 이후에 재시도하세요.
too_many_concurrent_requests429이 워크스페이스의 동시 요청이 3개를 넘었거나, 다른 내보내기가 이미 진행 중입니다.
replica_unavailable503이 프로세스에는 읽기 전용 레플리카가 설정되어 있지 않습니다. API는 프라이머리로 대체되지 않습니다.
query_timeout503쿼리가 10초 문장 타임아웃 또는 15초 마감 시간을 초과했습니다. 범위를 좁혀 다시 시도하세요.
internal_error500예상치 못한 서버 오류입니다. 다시 시도하고, 계속되면 신고해 주세요.

속도 제한 및 한도

가드값
속도 제한워크스페이스당 분당 60회 요청, 모든 인스턴스에서 공유되는 슬라이딩 윈도우입니다.
동시성워크스페이스당 서버마다 동시 요청 3개, 내보내기 스트림은 워크스페이스당 서버마다 1개.
잔액 폴링/balance: 워크스페이스당 분당 60회, 동시 2건까지이며 다른 엔드포인트와 별도로 계산합니다.
범위 한도/usage: hour 단위 31일, day 단위 366일. /summary: 최대 366일. /records 및 내보내기: 최대 31일.
페이지 한도/usage는 페이지당 최대 5,000행을 반환하며, /records는 최대 1,000행입니다. 내보내기는 2,000행 단위로 스트리밍하며 1,000,000행에서 멈춥니다 - cursor로 재개할 수 있습니다. 기록 id 2,000,000개를 훑은 뒤에도 멈추며(stopped_because=scan_cap), 데이터베이스에 맞춰 속도를 늦춥니다. cursor로 이어서 받으세요.
캐싱모든 응답에는 Cache-Control: no-store가 포함됩니다.

절대 반환되지 않는 항목: channel_id, upstream_request_id, usage_raw, other, content, ip_address, user_agent, cost_detail.

시간 공백 피하기

요청은 완료된 후 비동기적으로 로그에 기록됩니다 (보통 몇 초, 백로그가 있으면 더 오래 걸립니다). /usage와 /summary가 읽어오는 시간별 롤업은 배치 단위로 적재됩니다. 가장 최근 몇 시간은 항상 약간 불완전합니다. /usage와 /summary는 마지막 수집 이후 기록된 요청도 더합니다(meta.live_tail이 true). 롤업이 너무 뒤처지면 더하지 않으며(meta.live_tail이 false), 최근 버킷은 불완전합니다.

data_complete_until은 다음 두 값 중 더 이른 값입니다: 시간별 롤업의 워터마크에서 현재 파이프라인 지연을 뺀 값, 또는 아직 롤업되지 않은 가장 오래된 요청 - 여기서 30분의 안전 마진을 뺀 뒤 시간 단위로 내림합니다.

ℹ

확정된 버킷은 안정적이지만 한 가지 예외가 있습니다: 일일 정합성 검사 작업이 오차를 발견하면 48시간 이내에는 해당 시간대의 데이터를 여전히 수정할 수 있습니다. /records는 항상 요청의 정확한 수치에 대한 출처입니다.

모든 /usage 행에는 final 플래그가 있습니다: true 는 해당 버킷의 종료 시각이 data_complete_until (/freshness의 값) 이전이거나 같을 때 성립합니다. 확정된 버킷은 다시는 바뀌지 않습니다.

  • 집계 데이터: (bucket_start, api_key_id, model)을 기준으로 각 행을 자체 저장소에 upsert하고, 여전히 final: false인 버킷은 다시 가져오세요. 새 합계에서 이전 합계를 빼서 델타를 구하는 방식은 절대 사용하지 마세요.
  • 원시 행: cursor로 동기화하세요. 절대 시간으로 동기화하지 마세요. next_cursor를 보관하고 다음 호출에서 거기서부터 재개하며, 재전송된 페이지가 같은 행을 다시 전달할 경우를 대비해 수신한 행을 record_id(행마다 안정적인 불투명 id)로 중복 제거하세요. 기록된 지 약 5분이 안 된 행은 보류됩니다 - safe_until은 가장 최근에 기록된 행의 시각에서 5분을 뺀 값입니다 - 그래서 아직 커밋 중인 행이 이미 내준 커서 위치보다 앞서 나타나는 일이 없으며, 공백에 빠지는 데이터도 없습니다. 요청 수를 셀 때는 request_id 기준으로 중복을 제거해 세세요.
  • 제한된 창: cursor로 동기화하는 대신 start/end 범위로 조회한다면, window_final이 true일 때만 완전하다고 신뢰하세요 (end를 지정했고 그것이 safe_until 이전이거나 같을 때만 true입니다). window_final이 false라면 같은 범위로 나중에 다시 호출하거나 cursor 동기화로 전환하세요. 기간의 시작은 safe_until 이전이어야 합니다. 그보다 늦은 시작은 Retry-After 헤더와 함께 400 start_too_recent를 반환합니다.

권장 연동 방법

  • 야간 인보이스 처리: 하루에 한 번 granularity=day로 /usage를 호출하고, 지난번 실행에서 여전히 final: false였던 버킷은 다시 가져오세요.
  • 요청 단위 상세: 한 시간마다 저장해 둔 마지막 next_cursor를 cursor로 설정해 /records를 호출하고, has_more가 true인 동안 계속 페이지네이션하며, 수신한 행은 record_id로 중복 제거하세요.
  • 대시보드: 표시 중인 범위에는 /records를 직접 집계하지 말고 /summary를 호출하세요 - 이미 이상 목록을 포함하고 있습니다.

청구 데이터를 읽는 대신 일반 API 키를 프로그래밍 방식으로 발급하거나 관리해야 하나요? 관리 키를 참고하세요.