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

# Log query API: export call logs and charges

> Call /api/log/self with your AccessToken to filter usage and top-up records by time, model, or API key, and page through them for reconciliation.

The log query API returns the same records as the Logs page in the console: the model, API key, token counts, and charge for every call. Use it for daily reconciliation, per-key usage reports, or loading charges into your own billing system.

| Item | Details |
| - | - |
| Endpoint | `GET https://api.laozhang.ai/api/log/self` |
| Authentication | Account AccessToken; see [Get an AccessToken](/en/api-capabilities/balance-query#get-an-accesstoken) |
| Pagination | 10 records per page; `p` starts at 0 |
| Quota | 500,000 quota = 1 USD |

<Warning>
  **An invalid token still returns HTTP 200.**

  * The body is `{"success": false, "message": "...access token is invalid."}` with no `data`.
  * Check `success` in your script. Relying on the status code alone makes an auth failure look like an empty log.
</Warning>

## Query parameters

| Parameter | Description |
| - | - |
| `p` | Page number, starting at `0` |
| `type` | Record type: `2` for usage, `1` for top-ups. Omit it to get every type. |
| `model_name` | Return only one model, such as `gpt-5.4-mini` |
| `token_name` | Return only one API key, by its name |
| `start_timestamp` | Start time in Unix seconds |
| `end_timestamp` | End time in Unix seconds |

The page size is fixed; `page_size` and `size` are ignored. The response has no total count, so keep requesting the next page until one returns fewer than 10 records.

## Send a request

Store the AccessToken in an environment variable:

```bash theme={null}
export LAOZHANG_ACCESS_TOKEN="your AccessToken"
```

Fetch the last hour of `gpt-5.4-mini` usage:

```bash theme={null}
END=$(date +%s)
START=$((END - 3600))

curl --compressed -s -G "https://api.laozhang.ai/api/log/self" \
  -H "Authorization: ${LAOZHANG_ACCESS_TOKEN}" \
  --data-urlencode "p=0" \
  --data-urlencode "type=2" \
  --data-urlencode "model_name=gpt-5.4-mini" \
  --data-urlencode "start_timestamp=${START}" \
  --data-urlencode "end_timestamp=${END}"
```

Send the AccessToken as is in `Authorization`; a `Bearer ` prefix also works.

## Response fields

```json theme={null}
{
  "success": true,
  "message": "",
  "data": [
    {
      "created_at": 1791992057,
      "type": 2,
      "model_name": "gpt-5.4-mini",
      "token_name": "prod-backend",
      "quota": 1531,
      "prompt_tokens": 1348,
      "completion_tokens": 456,
      "is_stream": false,
      "request_id": "20261014153321000000000000000000example",
      "other": "{\"model_ratio\":0.375,\"completion_ratio\":6,...}"
    }
  ]
}
```

| Field | Description |
| - | - |
| `created_at` | Record time in Unix seconds |
| `type` | `2` usage, `1` top-up |
| `model_name` | Model ID that was called |
| `token_name` | Name of the API key that made the call |
| `quota` | Charge for this record; divide by 500,000 for US dollars |
| `prompt_tokens`, `completion_tokens` | Input and output tokens; can be 0 for per-call models |
| `is_stream` | Whether the request was streamed |
| `request_id` | Request ID to quote when you contact support |
| `other` | Billing details as a JSON **string**; parse it a second time |

`other` holds the multipliers, cache hits, and tool charges. For [web search](/en/api-capabilities/web-search) requests, `web_search_billing` lists the number of searches and their cost. If you only need the total charge, read `quota`. Responses can contain other fields as well; ignore the ones you don't use.

## Export a day of usage and total it by model

This script walks every page and totals the charge per model. It needs Python 3.9 or later and `requests` (`python -m pip install requests`).

```python theme={null}
import os
import time
from collections import defaultdict

import requests

TOKEN = os.environ["LAOZHANG_ACCESS_TOKEN"]
URL = "https://api.laozhang.ai/api/log/self"
QUOTA_PER_USD = 500_000

end = int(time.time())
start = end - 24 * 3600
totals = defaultdict(int)
page = 0

while True:
    response = requests.get(
        URL,
        headers={"Authorization": TOKEN},
        params={"p": page, "type": 2, "start_timestamp": start, "end_timestamp": end},
        timeout=60,
    )
    response.raise_for_status()
    payload = response.json()
    if not payload.get("success"):
        raise RuntimeError(payload.get("message"))

    rows = payload["data"] or []
    for row in rows:
        totals[row["model_name"]] += row["quota"]
    if len(rows) < 10:
        break
    page += 1
    time.sleep(0.2)

for model, quota in sorted(totals.items(), key=lambda item: -item[1]):
    print(f"{model}: ${quota / QUOTA_PER_USD:.4f}")
```

A busy account can have thousands of pages per day. Fetch shorter time windows, or narrow the query with `model_name` or `token_name`.

## Errors

| Symptom | Cause and fix |
| - | - |
| HTTP 401 with `AUTH_REQUIRED` | The `Authorization` header is missing |
| HTTP 200 with `success: false` and "access token is invalid" | The AccessToken is wrong or was regenerated; get a new one in the console |
| Empty array | No records match the time range; check that timestamps are in seconds, not milliseconds |
| Garbled output or a `jq` error | The response is gzip-compressed; add `--compressed` to cURL |

## Related documentation

* Get an AccessToken and check your balance: [Balance API](/en/api-capabilities/balance-query)
* Create, disable, and delete API keys from code: [Token management API](/en/api-capabilities/token-management)
* Read charges on the console Logs page: [How to review and use call logs](/en/faq/call-logs)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.