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

# Bill Query

> Pull day-level consumption details and summaries from TenndaAI for reconciliation, cost analysis, and bill collection

## Overview

Two read-only billing endpoints: day summaries for net spend trends, and line items broken down by model × token type. Amounts are always `USD`, billing timezone is `utc+8`, and data is **T+1**.

<CardGroup cols={2}>
  <Card title="Consumption details" icon="receipt">
    `getDailyList`: grain `(bill day × account × model × token type)`. Max span **92 days** per request; `pageSize` capped at 100.
  </Card>

  <Card title="Day summary" icon="chart-line">
    `getDailySummary`: grain `(bill day × account)`. Max span **366 days** per request; `pageSize` capped at 400.
  </Card>
</CardGroup>

## Endpoints

| Endpoint    | Method / path                      | Use case                             |
| ----------- | ---------------------------------- | ------------------------------------ |
| Details     | `GET /api/logs/v2/getDailyList`    | Line-item reconciliation, cost split |
| Day summary | `GET /api/logs/v2/getDailySummary` | Daily trends, monthly overviews      |

| Item                | Value                               |
| ------------------- | ----------------------------------- |
| Base URL            | `https://client.tennda.ai/prod-api` |
| Format / encoding   | `application/json` · `UTF-8`        |
| Protocol            | `HTTPS`                             |
| Currency / timezone | `USD` · `utc+8`                     |

## Authentication

Send a Bearer credential in the request header — either option works:

```http theme={null}
Authorization: Bearer <access_token>
Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxx
```

| Credential                                                          | Notes                            |
| ------------------------------------------------------------------- | -------------------------------- |
| [System access token](https://client.tennda.ai/#/profile?tab=token) | Console → Profile → Access token |
| [API Key](/en/interface-module/token-management)                    | Usually starts with `sk-`        |

Auth failure: HTTP `401`, business code `40100`.

<Warning>
  Never put a full key in URLs, frontend code, logs, or support tickets.
</Warning>

## Common response

```json theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "total": 128,
    "rows": []
  }
}
```

| Field        | Type          | Description                          |
| ------------ | ------------- | ------------------------------------ |
| `code`       | integer       | `0` = success; non-zero = failure    |
| `message`    | string        | Status message                       |
| `data`       | object / null | Payload; `null` on failure           |
| `data.total` | integer       | Total matching rows (for pagination) |
| `data.rows`  | array         | Current page                         |

### Business error codes

|  code | HTTP | Description                                                         |
| ----: | ---: | ------------------------------------------------------------------- |
|     0 |  200 | Success                                                             |
| 40001 |  400 | Bad parameter format (invalid date, non-positive page params, etc.) |
| 40002 |  400 | Missing required parameter                                          |
| 40003 |  400 | Invalid date range (start after end, or span over the limit)        |
| 40100 |  401 | Token missing, invalid, or expired                                  |
| 50000 |  500 | Internal server error                                               |

***

## Details · getDailyList

```
GET https://client.tennda.ai/prod-api/api/logs/v2/getDailyList
```

Returns rows keyed by `(bill day × account × model × token type)`.

### Request parameters

<ParamField query="startDate" type="string" required>
  Start date, `yyyy-MM-dd`
</ParamField>

<ParamField query="endDate" type="string" required>
  End date, `yyyy-MM-dd`; span with `startDate` must not exceed **92 days**
</ParamField>

<ParamField query="userId" type="string">
  Filter by account ID. Multi-sub-account visibility requires Enterprise Management — see [Conventions](#conventions). Omit to return accounts visible to the current credential.
</ParamField>

<ParamField query="userName" type="string">
  Filter by account name (exact). Same Enterprise Management rules; omit to return accounts visible to the current credential.
</ParamField>

<ParamField query="pageSize" type="string" required>
  Positive integer string, `1 ~ 100`; values over 100 are capped at 100
</ParamField>

<ParamField query="pageNum" type="string" required>
  Positive integer string, starting at `1`
</ParamField>

<Note>
  Pagination is by detail row; `data.total` is the total number of matching detail rows.
</Note>

### Response fields (`data.rows[]`)

| Field                   | Type   | Description                                                                                                                                          |
| ----------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `billMonth`             | string | Billing month, `yyyyMM`                                                                                                                              |
| `billDay`               | string | Billing day, `yyyy-MM-dd`                                                                                                                            |
| `billingDateTimezone`   | string | Always `utc+8`                                                                                                                                       |
| `account`               | string | Account name                                                                                                                                         |
| `modelType`             | string | Model family, e.g. `claude`, `gpt`, `gemini`                                                                                                         |
| `modelName`             | string | Model name                                                                                                                                           |
| `tokenType`             | string | Token type — see below                                                                                                                               |
| `tokenCount`            | string | Token count for this type (integer as string)                                                                                                        |
| `tokenUnit`             | string | Always `million` (priced per million tokens)                                                                                                         |
| `currency`              | string | Always `USD`                                                                                                                                         |
| `subtotalBeforeTax`     | string | Pre-discount, pre-tax (8 decimals)                                                                                                                   |
| `subtotalAfterDiscount` | string | Post-discount, pre-tax (8 decimals)                                                                                                                  |
| `totalAmountAfterTax`   | string | Post-discount, post-tax (8 decimals)                                                                                                                 |
| `price`                 | string | Pre-discount unit price per million tokens (8 decimals). `subtotalBeforeTax = price × tokenCount ÷ 1,000,000`; may be omitted when `tokenCount` is 0 |
| `entryType`             | string | `normal` = normal consumption                                                                                                                        |

### `tokenType`

| Value                                    | Meaning                       |
| ---------------------------------------- | ----------------------------- |
| `textInputTokens`                        | Text input                    |
| `textOutputTokens`                       | Text output                   |
| `reasoningTokens`                        | Reasoning / thinking          |
| `cacheCreationTokens5m`                  | Cache creation (5-minute TTL) |
| `cacheCreationTokens1h`                  | Cache creation (1-hour TTL)   |
| `cacheTokens`                            | Cache hit (read)              |
| `imageInputTokens` / `imageOutputTokens` | Image in / out                |
| `audioInputTokens` / `audioOutputTokens` | Audio in / out                |
| `videoInputTokens` / `videoOutputTokens` | Video in / out                |

<Note>
  Sort: `billDay` desc, then `account`, `modelName`, `tokenType`, `currency` asc.
</Note>

### Request example

```bash theme={null}
curl "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList?startDate=2026-07-27&endDate=2026-07-27&pageSize=100&pageNum=1" \
  -H "Authorization: Bearer <your_token>"
```

### Response example

```json theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "total": 23,
    "rows": [
      {
        "billMonth": "202607",
        "billDay": "2026-07-27",
        "billingDateTimezone": "utc+8",
        "account": "your_account",
        "modelType": "claude",
        "modelName": "claude-opus-4-8",
        "tokenType": "textOutputTokens",
        "tokenCount": "2931",
        "tokenUnit": "million",
        "currency": "USD",
        "subtotalBeforeTax": "0.07327564",
        "subtotalAfterDiscount": "0.07327564",
        "totalAmountAfterTax": "0.07327564",
        "price": "25.00021836",
        "entryType": "normal"
      }
    ]
  }
}
```

***

## Day summary · getDailySummary

```
GET https://client.tennda.ai/prod-api/api/logs/v2/getDailySummary
```

Day-level net spend. Lighter payload — suited for overviews and trend reports.

### Request parameters

<ParamField query="startDate" type="string" required>
  Start date, `yyyy-MM-dd`
</ParamField>

<ParamField query="endDate" type="string" required>
  End date, `yyyy-MM-dd`; span with `startDate` must not exceed **366 days**
</ParamField>

<ParamField query="userId" type="string">
  Filter by account ID (same Enterprise Management rules as details)
</ParamField>

<ParamField query="userName" type="string">
  Filter by account name, exact (same Enterprise Management rules as details)
</ParamField>

<ParamField query="pageSize" type="string" required>
  Positive integer string, `1 ~ 400`; values over 400 are capped at 400
</ParamField>

<ParamField query="pageNum" type="string" required>
  Positive integer string, starting at `1`
</ParamField>

<Note>
  Pagination is by `(bill day × account)`; `data.total` is the combination count.
</Note>

### Response fields (`data.rows[]`)

| Field                   | Type   | Description                                        |
| ----------------------- | ------ | -------------------------------------------------- |
| `billMonth`             | string | Billing month, `yyyyMM`                            |
| `billDay`               | string | Billing day, `yyyy-MM-dd`                          |
| `billingDateTimezone`   | string | Always `utc+8`                                     |
| `account`               | string | Account name                                       |
| `currency`              | string | Always `USD`                                       |
| `subtotalBeforeTax`     | string | Day total, pre-discount pre-tax net (8 decimals)   |
| `subtotalAfterDiscount` | string | Day total, post-discount pre-tax net (8 decimals)  |
| `totalAmountAfterTax`   | string | Day total, post-discount post-tax net (8 decimals) |

<Note>
  Sort: `billDay` desc, then `account` asc.
</Note>

### Request example

```bash theme={null}
curl "https://client.tennda.ai/prod-api/api/logs/v2/getDailySummary?startDate=2026-07-01&endDate=2026-07-27&pageSize=31&pageNum=1" \
  -H "Authorization: Bearer <your_token>"
```

### Response example

```json theme={null}
{
  "code": 0,
  "message": "success",
  "data": {
    "total": 2,
    "rows": [
      {
        "billMonth": "202607",
        "billDay": "2026-07-27",
        "billingDateTimezone": "utc+8",
        "account": "your_account",
        "currency": "USD",
        "subtotalBeforeTax": "0.26569400",
        "subtotalAfterDiscount": "0.26569400",
        "totalAmountAfterTax": "0.26569400"
      }
    ]
  }
}
```

***

## Conventions

1. **Amounts**: Always `string` with 8 decimal places — use Decimal / BigDecimal; do not convert to binary floats.
2. **Consistency**: For the same bill day and account, each day-summary amount equals the sum of the matching detail amounts that day (sum across pages).
3. **Zero days**: Days with no consumption in the range are omitted.
4. **Freshness**: Bills are **T+1** — the latest day is queryable the next day.
5. **Account scope**: Default is own account only. A primary account with **Enterprise Management** can see all sub-accounts — omit `userId` / `userName` for all, or pass them to filter; a sub-account credential only sees itself. Contact a TenndaAI admin to enable Enterprise Management.
6. **Out-of-range pages**: When `pageNum` exceeds total pages, `rows` is empty while `total` remains the true total.
