Skip to main content

API 개요

Log Query API는 계정 아래에서 수행된 모든 API 호출의 상세 기록을 반환합니다. 여기에는 사용된 모델, 실제 청구 금액, 지연 시간, 호출이 스트리밍되었는지 여부, 그리고 호출이 실패했을 때의 오류 코드가 포함됩니다. 이 API는 잔액 조회 API를 보완합니다. 잔액 조회는 남은 크레딧이 얼마인지 알려주고, 로그 조회는 그것이 어디로 갔는지 알려줍니다. 세 가지 대표적인 사용 사례는 다음과 같습니다:

자동 대사

시간 범위나 모델별로 실제 지출을 집계하고 자체 과금 내역과 대조합니다

셀프 서비스 문제 해결

실패한 요청의 오류 코드를 확인하여 매개변수 문제와 상위 시스템 문제를 구분합니다

지원 티켓

정확한 호출을 특정할 수 있도록 지원팀에 request_id를 제공하십시오
로그는 콘솔의 Logs 페이지에서도 볼 수 있습니다. 이 API는 동일한 데이터에 대한 프로그래밍 방식의 진입점으로, 자동 대사, 예약된 내보내기, 또는 자체 모니터링에 활용하는 용도입니다. 수동 확인은 콘솔을 사용하십시오 — 내 호출 기록을 보는 방법을 참조하십시오.
권장 사용법: 하루에 한 번 동기화하고 로그를 자체 데이터베이스에 저장하십시오.이 API는 반복적인 실시간 조회가 아니라 예약된 증분 내보내기를 위해 설계되었습니다:
  • 하루에 한 번 실행하여 마지막 동기화 이후 생성된 기록만 자체 데이터베이스나 CSV 파일로 가져오십시오
  • 요청당 더 많이 가져오십시오: pageSize은 최대 5000까지 올라갑니다 — 기본값 10으로 두지 마십시오. 여기서의 함정은 아래의 매개변수 참고사항을 참조하십시오
  • 대량 백필(한 번에 3개월치를 가져오기) 용도로 사용하지 말고, UI에서 실시간 페이지네이션을 구동하는 데도 사용하지 마십시오
  • 동시에 호출하지 마십시오 — 페이지는 순차적으로 넘기며, 각 페이지 사이에 약 1초를 두십시오
  • 각 시간 범위는 하루 이내로 유지하십시오. 트래픽이 많은 계정은 시간 단위로 나누십시오
왜 그런지에 대해서는 아래의 성능 노트 섹션을 참조하십시오. 윈도우가 오래될수록, 그리고 페이지네이션이 깊을수록 각 요청 비용이 더 커집니다. 서버 측 한도를 넘으면 오류가 반환되며, 같은 매개변수로 다시 시도해도 더 빨라지지 않습니다. 이 페이지의 Python 예제는 이미 이 패턴을 따르고 있으며 하루 한 번 실행하는 cron 작업에 그대로 넣을 수 있습니다.

시스템 토큰을 얻는 방법

Log Query API는 시스템 토큰으로 인증하며, 이는 API 키와 동일한 것이 아닙니다(이 페이지 끝의 중요 참고 사항을 참조하십시오).
1

콘솔에 접속

프로필 페이지에 액세스하려면 api.apiyi.com/account/profile에 방문하십시오
2

시스템 토큰 찾기

페이지 하단에서 “계정 옵션 - 시스템 토큰” 섹션을 찾으십시오
3

액세스 토큰 생성

후속 API 쿼리에 사용할 수 있는 액세스 토큰을 받으려면 계정 비밀번호를 입력하십시오
시스템 토큰 받기

API 정보

요청 세부 정보

요청 헤더

쿼리 매개변수

시간 범위는 필수로 간주하십시오.이 엔드포인트는 실제로 이 두 매개변수를 강제하지 않습니다. 없어도 호출은 성공합니다. 하지만 이를 생략하면 서버는 계정의 최신 레코드부터 거꾸로 전체 기록을 검색하며, 호출 기록이 많은 계정은 서버 측 제한에 걸려 느린 응답 대신 오류를 받게 됩니다.이 페이지에서 가장 쉽게 저지르는 실수이자 가장 직접적인 결과를 낳는 실수입니다. 서버가 호출을 거부하기 때문이 아니라, 실패 양상이 알아차리기 어렵기 때문에 Required로 표시합니다. 누락된 매개변수를 보고하지 않고 타임아웃을 보고합니다.
pageSize는 이 엔드포인트에서 유일한 camelCase 매개변수입니다. 이를 page_size로 잘못 적어도 조용히 무시됩니다.나머지 모든 매개변수(model_name, token_name, start_timestamp, request_id, …)는 snake_case를 사용합니다. 이 항목만은 그렇지 않습니다. 잘못 지정해도 오류가 발생하지 않습니다. 서버는 해당 매개변수를 없는 것으로 처리하고 페이지당 레코드 수 기본값 10을 사용합니다, 이로 인해 “상한이 10이다” 또는 “이 기간에 호출을 10번만 했다”로 오해하기 쉽습니다.
5000을 초과하면 조용히 잘리는 대신 명확한 오류가 발생합니다.
이 엔드포인트에서 가장 효과적인 최적화는 pageSize의 값을 키우는 것입니다. 페이지당 레코드 10개일 때 하루 500,000건의 호출이 있는 계정은 50,000개의 요청이 필요하지만, 페이지당 5000개일 때는 100개면 됩니다. 요청 수가 두 자릿수 규모로 줄어들고, 그에 따라 페이지네이션 오프셋도 감소합니다 — 아래 성능 참고 사항을 보십시오.5000개 레코드 페이지는 gzip으로 압축하면 대략 700 KB이며 약 2.5초가 걸립니다. 대역폭이나 메모리가 빠듯하다면, 1000가 무난한 중간 지점입니다.

성능 참고 사항

단일 요청의 비용은 고정되어 있지 않습니다. 세 가지 요인에 따라 달라집니다. 이 규칙을 따르면 API는 빠르게 동작하지만, 무시하면 서버 측 60초 쿼리 제한에 걸려 오류가 반환됩니다. 실용적인 규칙 네 가지입니다.
  1. 항상 start_timestampend_timestamp를 전달하십시오. 윈도우를 생략하는 것은 이 API를 호출하는 가장 비싼 방법입니다.
  2. pageSize를 늘리십시오. 이건 쉽습니다. 페이지당 10건에서 1000–5000건으로 늘리면 요청 횟수가 두 자릿수 규모로 줄어들고, 오프셋도 함께 줄어듭니다.
  3. 오프셋을 깊게 하기보다 윈도우를 줄이십시오. 비용이 드는 것은 “몇 번째 페이지인지”가 아니라 “그 위치에 도달하기 위해 몇 개의 레코드를 건너뛰었는지”이며, 이는 초선형적으로 증가합니다. 큰 윈도우 하나를 끝까지 페이지 처리하기보다 24개의 1시간 윈도우로 나누어 각 윈도우가 다시 오프셋 0에서 시작하게 하십시오.
  4. 히스토리를 한 번 백필하고 저장한 뒤, 이후에는 증가분만 동기화하십시오. 오래된 데이터는 최근 데이터보다 조회 비용이 훨씬 더 크므로, 같은 히스토리를 반복해서 다시 읽는 것은 순수한 낭비입니다.
윈도우가 pageSize=1000에서 여전히 수십 페이지를 차지한다면, 해당 기간의 호출량이 높다는 뜻입니다. 윈도우를 반으로 나누고 각 절반을 별도로 가져오십시오. 이렇게 하는 편이 더 깊이 페이지 처리하는 것보다 훨씬 빠릅니다. 아래 Python 예제의 MAX_PAGES 상수가 바로 이 작업을 수행합니다.

60초는 엄격한 제한이며, 초과하면 오류가 반환됩니다

서버는 단일 쿼리를 60초로 제한합니다. 그 시간을 넘으면 느린 응답을 받는 것이 아니라 — 오류를 받게 되며, 이미 소요한 시간으로는 데이터를 전혀 얻지 못합니다. 다음 세 가지 패턴이 이를 유발할 가능성이 높습니다. 재시도하며 운을 기대하기보다 아예 피하십시오. 같은 파라미터로 다시 시도해도 더 빨라지지 않습니다. 그냥 60초가 한 번 더 들 뿐입니다. 올바른 대응은 시간 윈도우를 좁히거나, pageSize를 늘려 페이지 수를 줄이는 것입니다. 어느 쪽이든, 호출당 서버가 처리해야 하는 데이터를 더 적게 만들어야 합니다.

로그 유형

지출을 계산할 때는 항상 type=2을 전달하십시오. 이를 지정하지 않으면 충전 및 시스템 부여 기록도 반환됩니다. 해당 기록의 quota은 0이지만 model_nametoken_name도 비어 있으므로, 단순히 합산하거나 모델별로 그룹화하면 잘못된 결과가 생성됩니다.계정에서 비동기 동영상 모델(Seedance 등)을 사용하는 경우 type=11도 가져오십시오. 작업이 실패하면 사전 청구 금액이 음수 환불 항목으로 반환되므로, type=2만 합산하면 해당 사전 청구 금액이 지출로 계산됩니다.

응답 세부 정보

성공 응답 예시

주요 응답 필드

other 필드는 중첩 객체가 아닌 JSON 문자열이므로 한 번 더 파싱해야 합니다 (Python에서는 json.loads(), JavaScript에서는 JSON.parse()). 여기에는 billing_type, request_path(실제로 호출된 엔드포인트), group_ratio, model_ratiousage가 포함됩니다.비동기 동영상 작업의 정산 항목에는 final_quota(작업의 최종 총액), original_quota (제출 시 청구된 사전 금액), adjustment_quota(이 항목의 차액) 및 actual_tokens도 포함됩니다. 아래 자주 묻는 질문을 참조하십시오.

쿼터 변환

변환 규칙

500,000 쿼터 = $1.00 USD
공식: USD 금액 = quota ÷ 500,000 예시:
  • quota: 7500 → $0.015 USD
  • quota: 22500 → $0.045 USD
  • quota: 18 → $0.000036 USD
이는 잔액 조회 API에서 사용하는 변환과 동일하므로, 두 값은 직접 일치합니다.

오류 응답

HTTP 401 - 인증 실패

원인: 시스템 token이 유효하지 않거나 만료되었거나, sk-로 시작하는 API 키가 실수로 시스템 token으로 사용되었습니다. 해결 방법: 콘솔에서 시스템 token을 다시 생성하고, Authorization가 원시 값을 Bearer 접두사 없이 사용하도록 하십시오.

코드 예시

cURL 예시 (단일 페이지, 빠른 확인)

--compressed 옵션은 필수입니다, API가 gzip 압축 콘텐츠를 반환하기 때문입니다. 이 옵션이 없으면 출력이 깨집니다.
이것은 token이 제대로 작동하는지 확인하는 데 사용합니다. 실제 정산에는 아래의 일일 동기화 스크립트를 사용합니다.

Python 예제: 일일 증분 동기화(크론 작업으로 바로 사용할 수 있음)

이것은 권장 표준 사용법입니다: 하루에 한 번 실행하여 마지막 동기화 이후 새로 생긴 내용만 가져와 로컬 SQLite 데이터베이스에 기록합니다. 다시 실행해도 안전합니다(기록은 request_id에서 중복 제거됨). 실행이 중간에 중단되어도 중단된 지점에서 재개됩니다.
샘플 출력:
데이터가 로컬에 있으면, 모델별, 일별, token별로 필요한 모든 분석은 자체 데이터베이스를 대상으로 실행되므로 그것을 위해 다시는 API를 조회할 필요가 없습니다. 이는 훨씬 더 빠르며, 이미 보존 기간을 벗어나 오래된 데이터를 원하게 되는 문제도 피할 수 있습니다.

Node.js 예제(단일 시간 창)

같은 아이디어입니다: 시간을 기준으로 분할하고, 순차적으로 페이지를 가져오며, 페이지네이션이 너무 깊어지면 창을 줄입니다.
Python requests 라이브러리와 Node.js fetch API는 모두 gzip을 자동으로 압축 해제하므로, 별도의 구성이 필요하지 않습니다. curl만 명시적인 --compressed 플래그가 필요합니다.

일반적인 시나리오

일일 정산(권장 방식)

위의 Python 스크립트를 하루에 한 번 실행하도록 예약하고 로그를 로컬 데이터베이스에 적재하십시오. 필요한 모든 세부 분석—총 지출, 모델별, token별—은 결국 자체 데이터베이스를 대상으로 하는 SQL 쿼리입니다. 이 방식이 적절한 이유는 세 가지입니다. 로컬 쿼리는 빠르고, 로그 보존 기간의 영향을 받지 않으며, 오래된 기록을 반복해서 다시 읽느라 API가 느려지는 일도 피할 수 있습니다. 한 모델의 기록만 동기화하려면 요청에 model_name 매개변수를 추가하십시오.

실패한 호출 찾기

데이터가 로컬에 있으면 자체 테이블을 직접 조회하십시오:
게이트웨이에서 거부된 요청(잘못된 매개변수 등)은 quota가 0이며 과금되지 않습니다. 로그의 error_code은 “호출이 실패했습니다”와 “호출은 성공했지만 결과가 마음에 들지 않았습니다”를 구분하는 데 도움이 됩니다.

지원용 요청 ID 제공

로그에서 문제가 되는 호출을 찾아 지원팀에 request_id를 제공하십시오. 그러면 처음부터 끝까지 정확한 요청을 식별할 수 있으므로, “어떤 모델에 대한 호출이 특정 시점쯤 실패했습니다”라고 설명하는 것보다 훨씬 효율적입니다.

자주 묻는 질문

먼저 다음 세 가지를 확인하십시오. 거의 모든 느린 쿼리는 이 중 하나에서 발생합니다.
  1. start_timestampend_timestamp를 전달하고 있습니까? 시간 범위를 생략하는 것은 이 API를 호출하는 가장 비용이 큰 방법입니다. 서버가 전체 기록을 검색합니다.
  2. 범위가 너무 오래되었거나 너무 넓습니까? 한 달 전 데이터를 쿼리하는 것은 어제 데이터를 쿼리하는 것보다 훨씬 많은 비용이 듭니다. 범위는 하루 미만으로 유지하고, 대용량의 경우 시간 단위로 분할하십시오.
  3. p가 수천 개에 도달했습니까? 페이지네이션 비용은 초선형적으로 증가합니다. 해결 방법은 하나의 큰 범위 내에서 더 깊이 페이지를 탐색하는 것이 아니라, 각 범위에 수십 페이지만 필요하도록 시간 범위를 줄이는 것입니다.
동일한 파라미터로 재시도해도 더 빨라지지 않습니다. 시간 초과 시에는 동일한 요청을 반복하는 대신 위와 같이 파라미터를 조정하십시오. 단순 재시도는 다시 기다리게 할 뿐입니다.
열 번 중 아홉 번은 파라미터의 철자가 snake_case인 page_size로 작성된 경우입니다.올바른 표기는 camelCase인 pageSize입니다. 이 엔드포인트에서 유일한 camelCase 파라미터이며, 나머지 모든 항목(model_name, token_name, start_timestamp, …)은 snake_case이므로 실수하기 쉽습니다. 오류는 발생하지 않으며, 서버는 해당 파라미터가 없는 것으로 처리하고 페이지당 10개 레코드로 대체합니다.
최대값은 5000이며, 이를 초과하면 명확한 오류가 반환됩니다. 대용량의 경우에도 응답이 빈 배열을 반환할 때까지 페이지네이션(p=0, p=1, …)해야 합니다. 위의 Python 및 Node.js 예제에는 이미 이 과정이 포함되어 있습니다.
예. request_id를 전달하면 해당 레코드만 반환됩니다.
특정 호출 하나를 조사할 때는 시간 범위를 가져와 직접 필터링하는 것보다 훨씬 빠릅니다.
아닙니다. 일부 필드는 플랫폼 내부 정보를 담고 있으며 일반 계정 관점에서는 비어 있거나 0입니다. 이는 예상된 동작이며, 정산 또는 문제 해결에 필요한 필드에는 영향을 주지 않습니다. quota, model_name, error_coderequest_id는 모두 완전히 채워집니다.
API는 그룹 식별자를 반환하는 반면, 콘솔은 그룹의 레이블을 표시합니다. 이 둘은 다를 수 있습니다. 예를 들어 API는 default를 반환하지만 콘솔에는 Default가 표시됩니다.전체 매핑은 공개 엔드포인트 https://api.apiyi.com/api/pricingusable_group 필드에서 제공되며, 식별자를 레이블에 매핑합니다. 보고서를 콘솔과 일치시키려면 이 매핑을 직접 적용하십시오.
quota를 사용하십시오. 이는 호출에 대해 실제로 차감된 금액이며 정산에 적합한 유일한 필드입니다. 이미지 및 동영상 생성과 같은 호출별 가격 책정 모델의 경우, 응답의 token 수는 가격 책정에 참여하지 않는 플레이스홀더 값일 수 있습니다. 이러한 모델은 other.billing_typeby_count를 보고합니다.
최근 30일만 쿼리할 수 있다고 가정하여 동기화 로직을 설계하십시오.실제로 쿼리 가능한 범위는 일반적으로 더 길지만, 보존 기간에 대해서는 어떠한 보장도 하지 않습니다. 이는 로그 정리 정책에 따라 변경되며, 변경 사항은 별도로 공지되지 않습니다. 30일을 계획의 최저 기준으로 삼으면 정책이 바뀌어도 정산이 중단되지 않습니다.또한 범위가 오래될수록 쿼리 비용이 더 커집니다. 데이터가 여전히 존재하더라도 해당 데이터에 도달하는 속도는 훨씬 느립니다.따라서 올바른 패턴은 하루에 한 번 자체 데이터베이스로 동기화하고, 과거 분석은 로컬에서 수행하는 것입니다. 장기적으로 보관해야 하는 항목은 직접 아카이브하십시오. 이 API로 다시 가져올 수 있다고 의존하지 마십시오.
원인: API는 gzip 압축 콘텐츠(Content-Encoding: gzip)를 반환하지만 curl이 이를 압축 해제하지 않습니다.해결 방법: --compressed 플래그를 추가하십시오.
Python requests 라이브러리와 Node.js fetch API는 자동으로 압축을 해제합니다.
비동기 동영상 작업(Seedance 및 유사 작업)은 ‘제출 시 선차감, 완료 시 차액 정산’ 방식으로 과금되므로 동영상 하나에 두 개의 항목이 남습니다. 즉, 선차감 항목(completion_tokens는 0, request_id 존재)과 정산 항목(completion_tokens는 실제 사용량, request_id는 비어 있음, quota는 차액만 해당)입니다. 어느 항목에도 task_id가 포함되지 않으므로, 이 API는 항목을 작업과 연결할 수 없습니다.동영상의 실제 비용을 확인하려면 task_id로 작업 API를 쿼리하십시오. 해당 API의 quota는 두 항목의 합계입니다.
해당 API의 페이지네이션 파라미터는 이 API와 반대로 snake_case page_size를 사용하며 p는 1부터 시작합니다. 실패한 작업도 quota에 선차감 내역이 표시되지만 실제 비용은 0입니다(로그에는 음수 type=11 환불 항목이 포함됩니다). 전체 안내: task_id로 Seedance 동영상의 실제 비용을 조회하는 방법.
아닙니다. 로그 쿼리 엔드포인트는 쿼터를 소모하지 않습니다.

중요 사항

시스템 token은 API key가 아니며, 둘은 서로 호환되지 않습니다
  • API key(sk-로 시작)는 /v1/* inference 엔드포인트용입니다. 이를 /api/log/self에 사용하면 401이 반환됩니다.
  • 시스템 token(접두사가 없는 평문 문자열)은 /api/* 관리 엔드포인트용입니다. 이를 /v1/chat/completions에 사용하면 잘못된 token 오류가 반환됩니다.
system token의 범위는 계정 전체에 적용되므로, 계정 비밀번호처럼 취급하십시오: 코드가 아니라 시크릿 매니저에 저장하고, 저장소에 절대 커밋하지 말며, 주기적으로 교체하십시오.
로그 응답에는 자신의 API key가 일반 텍스트로 포함됩니다각 로그 레코드에는 호출을 만든 token에 대한 정보가 들어 있습니다. 원시 로그 응답을 공개된 곳에 붙여넣거나, 스크린샷을 공유하거나, 제3자에게 넘기지 마십시오 — 내보내기 전에 민감한 필드를 제거하십시오.특히 이 평문에는 sk- 접두사가 없으므로, 일반적인 비밀 스캐너가 이를 감지하지 못할 수 있습니다. 자동 검사에만 의존하여 이를 잡아내려고 하지 마십시오.
권장 호출 패턴
  • 하루에 한 번 동기화하십시오 — 더 자주 할 필요가 없습니다. 각 실행은 새로 추가된 것만 가져옵니다
  • 10의 기본값이 아니라 pageSize을 1000–5000으로 사용하십시오 — 이 항목이 나머지를 모두 합친 것보다 더 중요합니다
  • 순차적으로 호출하십시오, 페이지 사이에 대략 1초 간격을 두고, 절대 동시에 실행하지 마십시오
  • 클라이언트 타임아웃을 60초로 설정하십시오(서버 측 쿼리 제한도 60초입니다)
  • 각 시간 창은 하루 이하로 유지하십시오. 대량 계정은 시간 단위로 분할하십시오
  • 타임아웃이 발생하면 재시도하기 전에 창을 줄이십시오 — 동일한 재시도는 더 빨라지지 않습니다
이것들은 엄격한 쿼터가 아니라, 자신의 데이터를 꺼내는 가장 빠른 방법일 뿐입니다. 이 패턴을 따르면 일반적인 계정은 하루치 로그를 1분 이내에 동기화할 수 있으며, 하루에 수십만 건의 호출을 하는 대규모 계정도 약 100개의 요청만 있으면 됩니다.
향후 이 엔드포인트에 요청 제한을 도입할 권리를 보유합니다.현재는 요청 제한이 없지만, 작업을 “무제한”에 맞춰 설계하지 마십시오. 위의 패턴 — 하루에 한 번, 순차적으로, 큰 pageSize — 을 따르면 향후 요청 제한의 영향을 받지 않습니다.

관련 문서