# API changes: July 12, 2026

[← Changelog](/docs/changelog) · [July 2026](/docs/changelog/2026-07)

### NEW-0712-1: The AI quota exhaustion response now points to the top-up path

The `402 ai_quota_exhausted` error with `reason: wallet_empty` now additionally returns the `hint` and `topupUrl` fields. `hint` is a short English message: the monthly AI quota and the account balance are exhausted, and an account admin can top up the balance to resume. `topupUrl` is a link the admin opens to top up. The fields are additive: the existing response fields (`reason`, `resetAt`) are unchanged, and the `reason: breaker` and `reason: wallet_off` branches do not carry them. This lets an agent client relay the top-up path to the human. The error is returned by model calls, see [POST /v1/chat/completions](/docs/ai/chat/completions).

### FIX-0712-2: `sleep-now` on a server with a long-past computed wake now sleeps honestly

**Before**

For a server with an enabled wake schedule, `POST /v1/infra/servers/:id/sleep-now` could return `{ data: { slept: false, reason: "WAKE_IMMINENT" } }` forever when the denormalized "next wake" was left far in the past (the server was woken outside the scheduler and the stamp was never recomputed). The server never slept and kept its plan running around the clock.

**After**

A stamp older than a dynamic window (grace = margin + typical lead) is treated as stale rather than "imminent": `sleep-now` sleeps the server honestly and answers `{ success: true }`, after which the scheduler quietly rolls the anchor forward to the future window without waking it. `WAKE_IMMINENT` stays a normal response only for a genuinely near wake.
