BBramaDocs
Browse documentation

Kimi (subscription) kimi

Moonshot's Kimi coding backend spoken with a Kimi subscription from the shared pool. Routes are kimi/<model> over plain openai-chat; the pinned model is kimi/kimi-for-coding. Who may spend the account is the entitlement decision; the account itself is a subscription. Not to be confused with moonshot, the API-key platform route.

How we sign in

Kimi has no local CLI that can mint or refresh a subscription credential: the grant comes out of the kimi.com OAuth sign-in in a real browser. On this fleet that browser is Weles's, on Weles's own host: Weles exposes the sign-in as POST /reauth on its worker API, drives its stored sign-in row for the account, and writes the minted grant into the Skarbiec vault at provider:kimi:<subscription>. The proof is the vault bundle at a higher revision and a refresh that answers refreshed — never the login's own exit status.

Drivers: brama subscription login kimi --by weles --reason "<why>" on the host Weles runs on (cli), the renewal loop, Brama Desktop, or a signed donation through POST /v1/subscription-pool (donation).

The grant on disk

The simplest of the three subscription shapes — a flat OAuth object:

{
  "access_token":  "<short-lived bearer>",
  "refresh_token": "<rotating refresh token>",
  "expires_at":    1756150000
}

expires_at is epoch seconds, written back on every refresh from the token endpoint's expires_in; the gateway also accepts expiresAt, expires and expiry, and reads the access token's JWT exp claim when the blob states nothing (src/gateway/oauth_refresh.rs). The item carries the discovery tags (brama:subscription, brama:agent:<agent>, brama:provider:kimi, brama:id:<id>); the agent tag only records who banked the account. Losing the brama:subscription mark makes the account unroutable, and /readyz names it under unroutable_accounts.

How a request presents it

At final use the gateway redeems the vault item through the local entitlements router, reduces it to the access token, and sends Authorization: Bearer <access_token> — nothing provider-specific beyond that. No copy of the token outlives the request.

Refresh

Once a token expires the gateway posts grant_type=refresh_token with the stored refresh token and the public client id 17e5f671-d194-4dfb-9706-5516cb48c098 to https://auth.kimi.com/api/oauth/token, form-encoded. The answer is read whole. Completion and response handling follow the core request contract. Each brama maintain pass refreshes every active credential whose stated expiry has passed, single-flighted per subscription; a token is used until that instant. The refresh token rotates on issue, so a refreshed grant that cannot be written back to the vault is a failed refresh. brama subscription refresh kimi --reason "<why>" forces the same path now and journals the reason. Refreshing costs no plan quota.

When the provider disowns the grant

A refused refresh is definitive only on the provider's own evidence — invalid_grant, invalid_token, revoked, unauthorized_client, or a 401/403 with no stated reason. That records credential.state: needs_reauthorization with the provider's sentence as cause, blocks the account for 30 minutes, lists it burnt, and waits for the sign-in above; everything else is transient and left for the next sweep (subscription, runbook).

Plan usage

Kimi publishes a free usage report at https://api.kimi.com/coding/v1/usages, issued to exactly the OAuth bearer the chat route already presents — reading it costs no quota. The ledger records each window with its instant and source (subscription).

Endpoints

Chathttps://api.kimi.com/coding/v1/chat/completions
Model discoveryhttps://api.kimi.com/coding/v1/models, widening the pinned row kimi-for-coding
Token endpointhttps://auth.kimi.com/api/oauth/token (form wire)
Usage reporthttps://api.kimi.com/coding/v1/usages
Trusted hostapi.kimi.com
Base URL overrideBRAMA_PROVIDER_KIMI_BASE_URL, validated with the refusals in provider