> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gravitex.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 로그 조회

> API 호출 로그, 소비 로그, 충전 로그 등을 페이지 단위로 조회

<Info>
  현재 자격 증명 범위 내의 호출, 소비, 충전, 관리, 오류, 환불, 테스트 크레딧 로그를 페이지 단위로 조회합니다.
</Info>

## 엔드포인트

* **HTTP 메서드**: `GET`
* **URL**: `https://maas.gravitex.ai/prod-api/api/logs/v2/page`
* **인증 헤더**: `Authorization`
* **언어 헤더**: `Accept-Language`; `zh-CN`, `en-US` 지원
* **시간 형식**: `yyyy-MM-dd HH:mm:ss`
* **최대 시간 범위**: 31일
* **기본 페이지네이션**: `page=1`, `pageSize=30`
* **최대 페이지 크기**: 1000

## 인증

다음 형식을 모두 지원합니다:

```http theme={null}
Authorization: Bearer sk-your_api_key
Authorization: sk-your_api_key
```

| 자격 증명                                                      | 조회 범위                       | `tokenName` 동작                                         |
| ---------------------------------------------------------- | --------------------------- | ------------------------------------------------------ |
| [시스템 액세스 토큰](https://maas.gravitex.ai/#/profile?tab=token) | 해당 사용자의 로그                  | 요청의 `tokenName`으로 퍼지 매칭                                |
| [API Key](/cn/interface-module/token-management)           | 해당 사용자이며 현재 API Key에 속하는 로그 | 서버가 현재 API Key 이름으로 정확한 일치를 강제하며, 요청의 `tokenName`은 무시됨 |

<Warning>
  URL, 프론트엔드 코드, 로그, 지원 티켓에 전체 키를 기록하지 마세요.
</Warning>

## 쿼리 파라미터

<ParamField query="page" type="integer" default="1">
  페이지 번호; 값이 ≤ 0이면 1로 처리
</ParamField>

<ParamField query="pageSize" type="integer" default="30">
  페이지 크기; 값이 ≤ 0이면 30으로 처리; 최대 1000
</ParamField>

<ParamField query="tokenName" type="string">
  API 키 이름. [시스템 액세스 토큰](https://maas.gravitex.ai/#/profile?tab=token)으로 인증 시 퍼지 매칭; [API key](/cn/interface-module/token-management) 인증에서는 사용 불가 — 서버는 항상 현재 API 키의 로그만 반환
</ParamField>

<ParamField query="modelName" type="string">
  모델 이름, 정확한 일치; 여러 모델은 쉼표로 구분
</ParamField>

<ParamField query="requestId" type="string">
  요청 ID, 정확한 일치
</ParamField>

<ParamField query="ip" type="string">
  요청 IP, 정확한 일치
</ParamField>

<ParamField query="useTimeMin" type="integer">
  최소 소요 시간(초), 경계값 포함
</ParamField>

<ParamField query="useTimeMax" type="integer">
  최대 소요 시간(초), 경계값 포함
</ParamField>

<ParamField query="startTime" type="string">
  시작 시간, 형식 `yyyy-MM-dd HH:mm:ss`, 경계값 포함
</ParamField>

<ParamField query="endTime" type="string">
  종료 시간, 형식 `yyyy-MM-dd HH:mm:ss`, 경계값 포함
</ParamField>

<ParamField query="types" type="string">
  로그 유형, 쉼표로 구분; 허용 값: `1,2,3,5,6,8`
</ParamField>

### 로그 유형

|   값 | 유형      |
| --: | ------- |
| `1` | 충전      |
| `2` | 소비      |
| `3` | 관리      |
| `5` | 오류      |
| `6` | 환불      |
| `8` | 테스트 크레딧 |

## Accept-Language

`billingProcessText`에만 영향을 줍니다:

| 헤더                       | 언어  |
| ------------------------ | --- |
| `Accept-Language: zh-CN` | 중국어 |
| `Accept-Language: en-US` | 영어  |
| 생략 또는 기타 값               | 중국어 |

## 요청 예시

<Tabs>
  <Tab title="curl">
    ```bash theme={null}
    curl --get 'https://maas.gravitex.ai/prod-api/api/logs/v2/page' \
      --header 'Authorization: Bearer your_api_key' \
      --header 'Accept-Language: en-US' \
      --data-urlencode 'page=1' \
      --data-urlencode 'pageSize=30' \
      --data-urlencode 'startTime=2026-07-01 00:00:00' \
      --data-urlencode 'endTime=2026-07-21 23:59:59' \
      --data-urlencode 'types=2,5'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const params = new URLSearchParams({
      page: '1',
      pageSize: '30',
      startTime: '2026-07-01 00:00:00',
      endTime: '2026-07-21 23:59:59',
      types: '2,5',
    });

    const response = await fetch(
      `https://maas.gravitex.ai/prod-api/api/logs/v2/page?${params}`,
      {
        method: 'GET',
        headers: {
          Authorization: 'Bearer your_api_key',
          'Accept-Language': 'en-US',
        },
      },
    );

    const result = await response.json();
    if (result.code !== 200) {
      throw new Error(result.msg);
    }

    console.log(result.data.total, result.data.rows);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    url = "https://maas.gravitex.ai/prod-api/api/logs/v2/page"
    headers = {
        "Authorization": "Bearer your_api_key",
        "Accept-Language": "en-US",
    }
    params = {
        "page": 1,
        "pageSize": 30,
        "startTime": "2026-07-01 00:00:00",
        "endTime": "2026-07-21 23:59:59",
        "types": "2,5",
    }

    response = requests.get(url, headers=headers, params=params, timeout=30)
    response.raise_for_status()
    result = response.json()

    if result.get("code") != 200:
        raise RuntimeError(result.get("msg"))

    print("Total records:", result["data"]["total"])
    for item in result["data"]["rows"]:
        print(item["requestId"], item["modelName"], item["quotaDollar"])
    ```
  </Tab>
</Tabs>

## 응답 구조

```json theme={null}
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "total": 1,
    "rows": [
      {
        "id": "7485162150730129409",
        "createdAt": 1784601721,
        "createTime": "2026-07-21 10:42:01",
        "type": 2,
        "requestId": "request_example_001",
        "ip": "203.0.113.10",
        "requestPath": "/v1/messages",
        "isStream": 1,
        "streamStatus": "正常 (eof)",
        "useTime": 2,
        "firstTokenTime": 1043,
        "modelName": "claude-sonnet-5",
        "tokenName": "default",
        "quotaDollar": "0.006098",
        "billingType": "token_ratio",
        "billingCountMode": "上游返回",
        "requestConversion": "Claude Messages",
        "textInputTokens": 2804,
        "textOutputTokens": 49,
        "cacheCreationTokens5m": null,
        "cacheCreationTokens1h": null,
        "cacheTokens": 0,
        "audioInput": null,
        "audioOutput": null,
        "imageInputTokens": null,
        "imageOutputTokens": null,
        "videoOutputTokens": null,
        "requestedSeconds": null,
        "imageCount": null,
        "videoResolution": null,
        "videoAudio": null,
        "videoHasInputVideo": null,
        "toolCallBilling": null,
        "billingProcessText": "Input price: ..., final cost: $0.006098"
      }
    ]
  }
}
```

<Note>
  `quotaDollar`는 십진수 문자열로 반환됩니다. Decimal/BigDecimal을 사용하고, 이진 부동소수점은 피하세요.
</Note>

## 응답 필드

| 필드                      | 타입           | 설명                          |
| ----------------------- | ------------ | --------------------------- |
| `code`                  | integer      | `200` = 성공, `401` = 인증 실패   |
| `msg`                   | string       | 메시지                         |
| `data.total`            | integer      | 일치하는 전체 레코드 수(페이지 수가 아님)    |
| `data.rows`             | array        | 현재 페이지 행                    |
| `id`                    | string/long  | 로그 ID; 클라이언트에서는 문자열로 처리     |
| `createdAt`             | integer      | Unix 타임스탬프(초)               |
| `createTime`            | string       | 포맷된 생성 시간                   |
| `type`                  | integer      | 로그 유형                       |
| `requestId`             | string/null  | 요청 ID                       |
| `ip`                    | string/null  | 요청 IP                       |
| `requestPath`           | string/null  | 요청 경로                       |
| `isStream`              | integer/null | 스트리밍 여부                     |
| `streamStatus`          | string/null  | 스트림 상태                      |
| `useTime`               | integer/null | 총 소요 시간(초)                  |
| `firstTokenTime`        | integer/null | 첫 토큰까지 시간(ms)               |
| `modelName`             | string/null  | 모델 이름                       |
| `tokenName`             | string/null  | 토큰 이름                       |
| `quotaDollar`           | decimal/null | 고객 청구 금액(USD)               |
| `billingType`           | string/null  | 청구 유형                       |
| `billingCountMode`      | string/null  | 청구 카운트 모드                   |
| `requestConversion`     | string/null  | 요청 프로토콜 변환                  |
| `textInputTokens`       | integer/null | 텍스트 입력 토큰                   |
| `textOutputTokens`      | integer/null | 텍스트 출력 토큰                   |
| `cacheCreationTokens5m` | integer/null | 5분 캐시 생성 토큰                 |
| `cacheCreationTokens1h` | integer/null | 1시간 캐시 생성 토큰                |
| `cacheTokens`           | integer/null | 캐시 히트 토큰                    |
| `audioInput`            | integer/null | 오디오 입력 계량                   |
| `audioOutput`           | integer/null | 오디오 출력 계량                   |
| `imageInputTokens`      | integer/null | 이미지 입력 토큰                   |
| `imageOutputTokens`     | integer/null | 이미지 출력 토큰                   |
| `videoOutputTokens`     | integer/null | 비디오 출력 토큰                   |
| `requestedSeconds`      | integer/null | 요청된 시간(초)                   |
| `imageCount`            | integer/null | 이미지 수                       |
| `videoResolution`       | string/null  | 비디오 해상도                     |
| `videoAudio`            | boolean/null | 오디오 출력 여부                   |
| `videoHasInputVideo`    | boolean/null | 입력 비디오 포함 여부                |
| `toolCallBilling`       | array/null   | 도구 호출 청구 상세                 |
| `billingProcessText`    | string/null  | `Accept-Language`에 따른 청구 내역 |

## 오류 응답

<Tabs>
  <Tab title="Authorization 누락 또는 무효">
    ```json theme={null}
    {
      "code": 401,
      "msg": "Authorization header missing or invalid",
      "data": null
    }
    ```
  </Tab>

  <Tab title="빈 키">
    ```json theme={null}
    {
      "code": 401,
      "msg": "Authorization key is empty",
      "data": null
    }
    ```
  </Tab>

  <Tab title="무효 또는 비활성 키">
    ```json theme={null}
    {
      "code": 401,
      "msg": "无效或已禁用的密钥",
      "data": null
    }
    ```
  </Tab>

  <Tab title="잘못된 시간 형식">
    ```json theme={null}
    {
      "code": 500,
      "msg": "startTime 格式错误，请使用 yyyy-MM-dd HH:mm:ss",
      "data": null
    }
    ```
  </Tab>

  <Tab title="범위가 31일 초과">
    ```json theme={null}
    {
      "code": 500,
      "msg": "时间范围不能超过1个月",
      "data": null
    }
    ```
  </Tab>
</Tabs>

## 호출 권장사항

1. 액세스 토큰 또는 API 키는 서버에 안전하게 저장하고, 전체 키를 절대 로그에 남기지 마세요.
2. 시간 범위는 최대 31일을 권장합니다.
3. 페이지 이동 시 `data.total`을 확인하세요 — 페이지 수로 취급하지 마세요.
4. 응답 본문의 `code`를 확인하세요; HTTP 200만으로 판단하지 마세요.
5. 금액은 Decimal/BigDecimal로 처리하고, 이진 부동소수점으로 재계산하지 마세요.
