はじめに
Notion Agent API のクレジット使用量フィールドが、整数ではなく小数でクレジットを返すようになりました。あわせて、フィールドごとの丸め規則(どちらも切り捨て)が固定されています。
フィールドの型は以前から number なので、スキーマ上は互換です。ただし**「クレジットは整数で返る」という前提でコードを書いていた場合**は、デシリアライズエラー、バリデーション失敗、表示や集計のズレが起きる可能性があります。
📌 影響を受ける人
- Agent API の
credits_used/total_credits_usedを取得して、コストの可視化・課金按分・アラートに使っている人- Go / Java / Kotlin / Swift / Rust など、静的型付け言語で
intとして型定義している人- 「クレジットは整数」という前提でバリデーションや UI 表示を作っている人
変更の全体像
影響を受けるエンドポイントとフィールドは次の3つです。
変更内容
⚠️ Breaking Change(整数前提の実装のみ)
型は以前からnumberでしたが、整数前提の実装は小数を受け取ると壊れる可能性があります。severity は high、対応が必要です。
丸め規則の一覧
| エンドポイント | フィールド | 丸め規則 | 例 |
|---|---|---|---|
| Retrieve a session | credits_used |
小数点以下最大2桁(切り捨て) | 12.456789 → 12.45 |
| Query sessions | credits_used |
小数点以下最大2桁(切り捨て) | 12.456789 → 12.45 |
| Retrieve agent insights | total_credits_used |
1以上は整数(切り捨て) | 12.7 → 12 |
| Retrieve agent insights | total_credits_used |
1未満は有効数字最大2桁(切り捨て) | 0.456789 → 0.45 |
ポイント
- 丸めは四捨五入ではなく切り捨てです。12.7 は 13 ではなく 12 になります。
- 丸めはフィールドごとに毎回同じ規則で行われるため、結果は決定的です。
-
total_credits_usedは値の大きさで規則が変わります。1未満は有効数字2桁、1以上は整数です。 - 切り捨てのため、セッション単位の
credits_usedを合算しても、total_credits_usedとは一致しない場合があります。請求の厳密な突合に使う場合は注意してください。
影響を受けやすい実装パターン
| パターン | 起きうる問題 |
|---|---|
int / long にデシリアライズしている |
パースエラー、または小数部の欠落 |
Number.isInteger() や整数正規表現で検証している |
正常なレスポンスが不正扱いになる |
表示や集計が整数前提(parseInt や整数への丸め) |
0.45 が 0 になるなど、少額が見えなくなる |
| 浮動小数点で合算している | 誤差が蓄積する |
影響と対応
対応チェックリスト
-
型定義の見直し:
intをfloat/double/decimalに変更する -
バリデーションの見直し: 整数チェックを外し、
0以上の数値かどうかを検証する -
表示の見直し: 少額(例: 0.45)が
0と表示されないようにする -
集計の見直し: 金額・クレジットの合算は
decimal系の型を使う。切り捨て済みの値なので、合算結果がtotal_credits_usedと完全一致するとは限らない -
テストの追加:
12.45、0.45、12のような値をテストデータに加える
💡 Tips
小数2桁の値は、100倍した整数(センチクレジット)として保持する方法もあります。誤差を避けつつ、既存の整数ベースの集計基盤を流用できます。ただしtotal_credits_usedは規則が異なるので、同じ変換を使ってよいか事前に確認してください。
CLAUDE.md への追記案
Claude Code などでこの API を扱うプロジェクトでは、次のような注意書きを残しておくと、整数前提のコードを生成されにくくなります。
## Notion API / Agent API 利用上の注意
- Agent APIの credits_used(Retrieve a session / Query sessions)は小数点以下最大2桁の小数で、切り捨てで返る。
- total_credits_used(Retrieve agent insights)は、1以上なら切り捨てた整数、1未満なら有効数字2桁(切り捨て)で返る。
- 整数を前提にした型定義・パース・集計は使わず、float/decimal として扱う。
コード例
TypeScript
Before(整数前提)
type Session = { id: string; credits_used: number };
function validate(s: Session) {
if (!Number.isInteger(s.credits_used)) {
throw new Error("credits_used must be an integer"); // 12.45 で例外
}
}
const label = `${Math.round(s.credits_used)} credits`; // 0.45 → "0 credits"
After(小数対応)
type Session = { id: string; credits_used: number };
function validate(s: Session) {
if (!Number.isFinite(s.credits_used) || s.credits_used < 0) {
throw new Error("credits_used must be a non-negative number");
}
}
// 表示は小数点以下2桁。API側で切り捨て済みなので再度丸めない
const label = `${s.credits_used.toFixed(2)} credits`;
Python(集計)
Before
total = sum(int(s["credits_used"]) for s in sessions) # 小数部が落ちる
After
from decimal import Decimal
# JSON を float 経由にしない: json.loads(..., parse_float=Decimal)
total = sum((s["credits_used"] for s in sessions), Decimal("0"))
Go(静的型付け言語の例)
Before
type Session struct {
CreditsUsed int `json:"credits_used"` // 12.45 でデコードエラー
}
After
type Session struct {
CreditsUsed float64 `json:"credits_used"`
}
まとめ
- Agent API のクレジット使用量が小数で返るようになった(型は以前から
number)。 -
credits_usedは小数点以下最大2桁、total_credits_usedは1以上なら整数・1未満なら有効数字最大2桁。どちらも切り捨て。 - 整数型でのデシリアライズ、整数前提のバリデーション、整数前提の表示・集計がある場合は修正が必要。
- 対応は、型を
float/decimalにする、検証を緩める、少額表示を確認する、の3点。 - 切り捨ての影響で合算値と
total_credits_usedがずれることがあるため、突合用途では仕様を踏まえて設計する。
コストの可視化やアラートを Agent API に依存している場合は、早めに自分のコードを確認しておくことをおすすめします。