docs/grok.md
Grok uses xAI's official Grok Build CLI (grok, released 2026-05-14). Usage data is
fetched via the ACP JSON-RPC x.ai/billing extension method over grok agent stdio
when available, then via the Grok CLI billing REST API using the local login token.
The grok.com billing gRPC-web endpoint remains a best-effort fallback.
grok agent stdio only.~/.grok/auth.json or a pasted bearer / GROK_OAUTH_TOKEN. CLI-proxy credits, then bearer gRPC. No cookies.Cookie: / name=value → cookies, xai- management keys rejected..oauth pipeline.~/.grok/auth.json (primary identity source)
email, team_id, first_name/last_name, plan-hint (auth_mode),
and the optional principal_type for the identity row in the menu.grok agent stdio ACP JSON-RPC (best-effort, currently disabled in grok 0.1.210)
grok agent stdio and call initialize + x.ai/billing (no params).x.ai/billing extension method
is only wired in the interactive TUI; the agent-stdio surface returns
-32601 Method not found. Personal/unknown principals continue to the web
fallback, while a team principal degrades to identity-only with an explicit
unsupported-team-usage diagnostic. When xAI exposes billing on the agent
protocol, no code change is required./v1/settings for subscription_tier_display so the
billed plan is not lost just because the CLI route succeeded first. The
settings lookup is optional enrichment with a 2-second budget.\/ in method
names. Foundation.JSONSerialization.data defaults to escaping forward
slashes, so payloads must be re-encoded with \/ → / before being
written to stdin or grok will silently drop them (12s client-side
timeout instead of the expected error response).~/.grok/auth.json token exists, GETs
https://cli-chat-proxy.grok.com/v1/billing?format=credits with
Authorization: Bearer <token>, x-xai-token-auth: xai-grok-cli, and
Accept: application/json.config.creditUsagePercent, falling back to
onDemandUsed.val / onDemandCap.val * 100. A parseable current period
without either value represents unknown usage. The reset timestamp comes from
config.currentPeriod.end, then config.billingPeriodEnd.creditUsagePercent. Before that
answer is accepted, CodexBar retries the grok.com bearer gRPC path (step 4,
still without cookies) and adopts its percent when it has one, keeping the
credits period and plan metadata, with the proxy's authoritative reset taking
precedence over a conflicting gRPC timestamp. When grok.com has no percent
either, or the retry fails, usage stays unknown and the card reports an explicit
unavailable-usage diagnostic — an absent value is never reported as 0%.
Only a percentage that grok.com actually put on the wire is adopted: that
parser reports its own no-usage-yet frame (a period with no percentage field)
as 0, and promoting that reading would recreate the fabricated 0%. The retry
also runs under a 6-second budget, because period-only payloads recur on every
refresh and a grok.com outage must not delay the credits answer already in hand.https://cli-chat-proxy.grok.com/v1/settings
with the same bearer headers and reads subscription_tier_display
(SuperGrok Heavy vs SuperGrok). Cookie mode does not call the proxy.
If the proxy fails, OAuth retries the grok.com bearer gRPC path, still
without cookies. Cookie/gRPC fallbacks are a different browser session and
do not reuse the auth-file settings tier. The request uses a 2-second timeout
and BoundedTaskJoin, so a stuck settings call cannot delay already-fetched
usage by 15 seconds. Settings timeouts, request failures, and 200 responses
that omit subscription_tier_display all drop the plan overlay and fall
back to the OIDC SuperGrok label. There is no process-lifetime tier cache.https://grok.com/grok_api_v2.GrokBuildBilling/GetGrokCreditsConfig.no-credentials; signing in through Chrome alone cannot provide that proof
to CodexBar, so grok login is the recommended recovery path.~/.grok/auth.json token is available, CodexBar first sends it with each
browser session, then retries that session with cookies only.CODEXBAR_ALLOW_BROWSER_COOKIE_IMPORT=1 is set. An explicit
codexbar cookie refresh --provider grok also opts in for that refresh.~/.grok/auth.json is still used for identity and as a last best-effort
bearer-only probe after browser sessions fail. Expired tokens are not sent.credit_usage_percent is treated as zero usage. This keeps
billing visible when grok agent stdio returns Method not found.~/.grok/sessions/<encoded-cwd>/<session-id>/signals.json files (last 30 days).totalTokensBeforeCompaction, contextTokensUsed, modelsUsed,
and the most recent session timestamp.~/.grok/auth.json (path overridable via GROK_HOME). This remains
the preferred identity source when grok login has written a non-expired token.https://auth.x.ai::<client-id> (SuperGrok), falling back to
https://accounts.x.ai/sign-in (legacy session).key (bearer token), refresh_token, expires_at,
auth_mode, email, team_id, user_id, first_name/last_name.
principal_type is optional because older auth files do not include it.grok login and expire after ~7 days; refresh is handled by
the CLI itself (CodexBar does not refresh; it just reads the cached credential).auth.json is missing or expired, paste a SuperGrok bearer into Grok token
accounts or set GROK_OAUTH_TOKEN. Cookie-shaped values and xai- management
keys are rejected. The pasted token uses the same CLI-proxy credits URL.subscriptionTier maps SuperGrok vs SuperGrok Heavy on the plan badge.
SuperGrok Heavy with no creditUsagePercent is unknown usage, not 0%.initialize params:
{
"protocolVersion": "1",
"clientCapabilities": {
"fs": { "readTextFile": false, "writeTextFile": false },
"terminal": false
}
}
x.ai/billing result shape (all monetary values are { val: <cents> }):
{
"billingCycle": {
"billingPeriodStart": "2026-05-01T00:00:00Z",
"billingPeriodEnd": "2026-06-01T00:00:00Z"
},
"monthlyLimit": { "val": 99900 },
"onDemandCap": { "val": 0 },
"on_demand_enabled": false,
"disabledByConfig": false,
"usage": {
"includedUsed": { "val": 12345 },
"onDemandUsed": { "val": 0 },
"totalUsed": { "val": 12345 }
}
}
"Authentication required to fetch billing data. Run 'grok login' to authenticate.".initialize, 12s for x.ai/billing. CodexBar terminates the
child grok process on timeout to avoid leaking subprocesses.UsageSnapshotusedPercent = usage.totalUsed.val / monthlyLimit.val * 100;
resetsAt = billingCycle.billingPeriodEnd.usedPercent from the JSON percent or on-demand ratio;
resetsAt from the current-period end or billing-period end.usedPercent and resetsAt parsed from the gRPC-web
billing protobuf.resetsAt matches a common cycle, falling back to the registered
"Credits" label otherwise. Settings and history views continue to use
"Credits" as the stable metric name.accountEmail from credential email.accountOrganization from credential team_id.loginMethod = CLI settings subscription_tier_display when present
(SuperGrok Heavy or SuperGrok), on both the CLI RPC route and the
CLI-proxy web route. Otherwise "SuperGrok" for OIDC and the raw auth_mode
for other login modes.~/.grok/sessions/)Each session directory contains signals.json with fields like:
{
"turnCount": 1,
"contextTokensUsed": 2968,
"contextWindowTokens": 512000,
"totalTokensBeforeCompaction": 0,
"modelsUsed": ["grok-build"],
"primaryModelId": "grok-build",
"sessionDurationSeconds": 47
}
CodexBar aggregates these into a GrokLocalSessionSummary (session count, total
tokens, last session time, primary model, per-day token buckets) and exposes it for
diagnostics even when the RPC path is unavailable.
Those local daily token buckets also feed the shared Usage & Spend catalog so an enabled Grok subscription is counted instead of omitted. SuperGrok/X Premium+ credits remain a quota window on the usage bar; they are never converted into dollars. Local session scans run on the dedicated background usage-scan queue; menu cards and spend views reuse the already-published snapshot instead of walking the session directory whenever they render.
xAI has not exposed a Statuspage-style status feed yet. The "View Status" link
points to https://status.x.ai.
Sources/CodexBarCore/Providers/Grok/GrokProviderDescriptor.swiftSources/CodexBarCore/Providers/Grok/GrokAuth.swiftSources/CodexBarCore/Providers/Grok/GrokPlan.swiftSources/CodexBarCore/Providers/Grok/GrokRPCClient.swiftSources/CodexBarCore/Providers/Grok/GrokCreditsProxyFetcher.swiftSources/CodexBarCore/Providers/Grok/GrokCLISettingsFetcher.swiftSources/CodexBarCore/Providers/Grok/GrokWebBillingFetcher.swiftSources/CodexBarCore/Providers/Grok/GrokStatusProbe.swiftSources/CodexBarCore/Providers/Grok/GrokLocalSessionScanner.swiftSources/CodexBar/Providers/Grok/GrokProviderImplementation.swift