账单查询
curl --request GET \
--url https://client.tennda.ai/prod-api/api/logs/v2/getDailyListimport requests
url = "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://client.tennda.ai/prod-api/api/logs/v2/getDailyList', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://client.tennda.ai/prod-api/api/logs/v2/getDailyList")
.asString();require 'uri'
require 'net/http'
url = URI("https://client.tennda.ai/prod-api/api/logs/v2/getDailyList")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body接口模块
账单查询
按账单日拉取消费明细与日汇总,便于 TenndaAI 对账、成本分析与账单采集
GET
/
prod-api
/
api
/
logs
/
v2
/
getDailyList
账单查询
curl --request GET \
--url https://client.tennda.ai/prod-api/api/logs/v2/getDailyListimport requests
url = "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://client.tennda.ai/prod-api/api/logs/v2/getDailyList', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://client.tennda.ai/prod-api/api/logs/v2/getDailyList"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://client.tennda.ai/prod-api/api/logs/v2/getDailyList")
.asString();require 'uri'
require 'net/http'
url = URI("https://client.tennda.ai/prod-api/api/logs/v2/getDailyList")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body简介
开放两套只读账单接口:按日汇总看净额走势,按明细落到「模型 × Token 类型」。金额统一USD,计费时区 utc+8,数据为 T+1。
消费明细
getDailyList:粒度 (账单日 × 账号 × 模型 × Token 类型),单次查询跨度 ≤ 92 天,pageSize 上限 100。日汇总
getDailySummary:粒度 (账单日 × 账号),单次查询跨度 ≤ 366 天,pageSize 上限 400。接口一览
| 接口 | 方法 / 路径 | 用途 |
|---|---|---|
| 消费明细 | GET /api/logs/v2/getDailyList | 明细对账、成本拆分 |
| 日汇总 | GET /api/logs/v2/getDailySummary | 日趋势、月报概览 |
| 项 | 值 |
|---|---|
| Base URL | https://client.tennda.ai/prod-api |
| 格式 / 编码 | application/json · UTF-8 |
| 协议 | HTTPS |
| 币种 / 时区 | USD · utc+8 |
鉴权
请求头携带 Bearer 凭证,以下两种任选其一:Authorization: Bearer <access_token>
Authorization: Bearer sk-xxxxxxxxxxxxxxxxxxxx
401,业务码 40100。
完整 Key 勿写入 URL、前端、日志或工单。
通用响应
{
"code": 0,
"message": "success",
"data": {
"total": 128,
"rows": []
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
code | integer | 0 成功,非 0 失败 |
message | string | 提示信息 |
data | object / null | 业务体;失败时为 null |
data.total | integer | 满足条件的总条数(分页用) |
data.rows | array | 当前页数据 |
业务错误码
| code | HTTP | 说明 |
|---|---|---|
| 0 | 200 | 成功 |
| 40001 | 400 | 参数格式错误(日期非法、分页非正整数等) |
| 40002 | 400 | 缺少必填参数 |
| 40003 | 400 | 日期区间非法(起止颠倒或超跨度上限) |
| 40100 | 401 | Token 缺失、无效或过期 |
| 50000 | 500 | 服务器内部错误 |
消费明细 · getDailyList
GET https://client.tennda.ai/prod-api/api/logs/v2/getDailyList
(账单日 × 账号 × 模型 × Token 类型) 拆分的消费行。
请求参数
string
必填
开始日期,
yyyy-MM-ddstring
必填
结束日期,
yyyy-MM-dd;与 startDate 跨度不超过 92 天string
按账号名精确筛选(企业管理规则同上);不传则返回当前凭证可见账号
string
必填
正整数字符串,
1 ~ 100;超过 100 按 100string
必填
正整数字符串,从
1 起分页单位是「明细行」;
data.total 为明细总条数。响应字段(data.rows[])
| 字段 | 类型 | 说明 |
|---|---|---|
billMonth | string | 账单月,yyyyMM |
billDay | string | 账单日,yyyy-MM-dd |
billingDateTimezone | string | 固定 utc+8 |
account | string | 账号名 |
modelType | string | 模型分类,如 claude、gpt、gemini |
modelName | string | 模型名称 |
tokenType | string | Token 类型,见下表 |
tokenCount | string | 该类型 Token 数量(整数字符串) |
tokenUnit | string | 固定 million(按百万 Token 计价) |
currency | string | 固定 USD |
subtotalBeforeTax | string | 折前税前金额(8 位小数) |
subtotalAfterDiscount | string | 折后税前金额(8 位小数) |
totalAmountAfterTax | string | 折后税后金额(8 位小数) |
price | string | 每百万 Token 折前单价(8 位小数)。subtotalBeforeTax = price × tokenCount ÷ 1,000,000;tokenCount 为 0 时可能省略 |
entryType | string | normal 表示正常消费 |
tokenType
| 值 | 含义 |
|---|---|
textInputTokens | 文本输入 |
textOutputTokens | 文本输出 |
reasoningTokens | 推理 / 思考 |
cacheCreationTokens5m | 缓存创建(5 分钟 TTL) |
cacheCreationTokens1h | 缓存创建(1 小时 TTL) |
cacheTokens | 缓存命中(读取) |
imageInputTokens / imageOutputTokens | 图片输入 / 输出 |
audioInputTokens / audioOutputTokens | 音频输入 / 输出 |
videoInputTokens / videoOutputTokens | 视频输入 / 输出 |
排序:
billDay 降序,再按 account、modelName、tokenType、currency 升序。请求示例
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>"
响应示例
{
"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"
}
]
}
}
日汇总 · getDailySummary
GET https://client.tennda.ai/prod-api/api/logs/v2/getDailySummary
请求参数
string
必填
开始日期,
yyyy-MM-ddstring
必填
结束日期,
yyyy-MM-dd;与 startDate 跨度不超过 366 天string
按账号 ID 筛选(企业管理规则同明细接口)
string
按账号名精确筛选(企业管理规则同明细接口)
string
必填
正整数字符串,
1 ~ 400;超过 400 按 400string
必填
正整数字符串,从
1 起分页单位是「账单日 × 账号」;
data.total 为组合总数。响应字段(data.rows[])
| 字段 | 类型 | 说明 |
|---|---|---|
billMonth | string | 账单月,yyyyMM |
billDay | string | 账单日,yyyy-MM-dd |
billingDateTimezone | string | 固定 utc+8 |
account | string | 账号名 |
currency | string | 固定 USD |
subtotalBeforeTax | string | 当日折前税前净额(8 位小数) |
subtotalAfterDiscount | string | 当日折后税前净额(8 位小数) |
totalAmountAfterTax | string | 当日折后税后净额(8 位小数) |
排序:
billDay 降序,再按 account 升序。请求示例
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>"
响应示例
{
"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"
}
]
}
}
约定
- 金额:一律
string,保留 8 位小数,请用 Decimal / BigDecimal,勿转二进制浮点。 - 一致性:同一账单日、同一账号下,日汇总各金额 = 当日明细对应字段之和(需跨页累加)。
- 零消费:区间内无消费的日期不返回。
- 时效:账单 T+1,最新一日次日可查。
- 账号范围:默认仅本账号。开通「企业管理」的主账号可查全部子账号——不传
userId/userName返回全部,传入则筛选;子账号凭证仅能查自己。开通请联系 TenndaAI 管理员。 - 越界页:
pageNum超出总页数时rows为空,total仍为真实总数。
