# Check health status
curl http://localhost:8080/health
# Proxy a request to Anthropic
curl -X POST http://localhost:8080/v1/anthropic/v1/messages \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 100
}'
# Proxy a request to OpenAI
curl -X POST http://localhost:8080/v1/openai/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# List all accounts
curl http://localhost:8080/api/accounts
# View dashboard
open http://localhost:8080ccflare provides a RESTful HTTP API for managing accounts, monitoring usage, and proxying requests to Anthropic and OpenAI. The API runs on port 8080 by default and requires no authentication.
http://localhost:8080
All API responses are in JSON format with Content-Type: application/json.
Check the health status of the ccflare service.
Response:
{
"status": "ok",
"accounts": 5,
"timestamp": "2024-12-17T10:30:45.123Z",
"strategy": "session",
"providers": ["anthropic", "openai"]
}Example:
curl http://localhost:8080/healthProxy requests to upstream provider APIs. The /v1/{provider} prefix is stripped exactly once before forwarding upstream. Requests are routed using the configured load balancing strategy across accounts matching the target provider.
Supported Providers:
/v1/anthropic/*→https://api.anthropic.com/*/v1/openai/*→https://api.openai.com/v1/*/v1/kimi/*→https://api.kimi.com/coding/v1/*POST /v1/grok/responses→https://cli-chat-proxy.grok.com/v1/responses
Grok accepts only POST /v1/grok/responses; other Grok paths and methods are
rejected locally.
Headers:
- All standard provider API headers are supported
Authorizationheader is managed by ccflare (no need to provide)
Request Body: Same as the upstream provider API requirements for the specific endpoint.
Response: Proxied response from the upstream provider API, including streaming responses.
Automatic Failover: If a request fails or an account is rate limited, ccflare automatically retries with the next available account according to the configured load balancing strategy. This ensures high availability and reliability.
Examples:
# Anthropic
curl -X POST http://localhost:8080/v1/anthropic/v1/messages \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 100
}'
# OpenAI chat completions
curl -X POST http://localhost:8080/v1/openai/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# OpenAI responses
curl -X POST http://localhost:8080/v1/openai/responses \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o",
"input": "Hello!"
}'Compatibility routes keep the client-facing Anthropic/OpenAI schema while routing
through a connected provider family chosen from the model prefix.
Model Prefix Rules:
openai/<model-id>→ preferscodex, thenopenaianthropic/<model-id>→ prefersclaude-code, thenanthropic
Unprefixed models use the compatibility route's native family. Kimi models are
not translated by compatibility routes; send their native Chat Completions
payloads to POST /v1/kimi/chat/completions instead. A kimi/ model on any
compatibility endpoint returns 400 with that guidance.
Empty or non-string model values are rejected with 400.
Examples:
# Ask for an Anthropic model through the OpenAI chat schema
curl -X POST http://localhost:8080/v1/ccflare/openai/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# Ask for an OpenAI model through the Anthropic Messages schema
curl -X POST http://localhost:8080/v1/ccflare/anthropic/messages \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"max_tokens": 100,
"messages": [{"role": "user", "content": "Hello!"}]
}'Behavior:
- HTTP only; websocket upgrades are not supported on
/v1/ccflare/* - requests use the same load-balancing and failover logic as native provider routes
- responses are translated back into the requested client schema, including SSE streams
- if no usable accounts exist in the requested family, ccflare returns
503
List all configured accounts with their current status.
Response:
[
{
"id": "uuid-here",
"name": "account1",
"provider": "anthropic",
"auth_method": "api_key",
"base_url": null,
"requestCount": 150,
"totalRequests": 1500,
"lastUsed": "2024-12-17T10:25:30.123Z",
"created": "2024-12-01T08:00:00.000Z",
"weight": 1,
"paused": false,
"tokenStatus": "valid",
"tokenExpiresAt": null,
"rateLimitStatus": {
"code": "ok",
"isLimited": false,
"until": null
},
"rateLimitReset": "2024-12-17T10:30:00.000Z",
"rateLimitRemaining": 100,
"sessionInfo": {
"active": true,
"startedAt": "2024-12-17T10:00:00.000Z",
"requestCount": 25
},
"quota": null
}
]Example:
curl http://localhost:8080/api/accountsFetch live provider-native quota data for one selected OAuth account. The account is addressed directly by its ccflare account ID; load balancing, paused state, and current inference rate-limit state do not affect which credentials are queried.
Supported providers:
claude-code— collects Anthropic OAuth usage and profile datacodex— collects ChatGPT usage, account-check, and reset-credit datakimi— collects Kimi Coding usage limitsgrok— collects Grok Build included and enabled on-demand credit usage
The large Codex profile-history probe is intentionally omitted because it does not provide current quota windows.
The handler refreshes missing, expired, expiry-less, or nearly expired OAuth credentials before querying. A fully unauthorized collective response also triggers one refresh-and-retry. Rotated tokens are persisted but are never included in the API response.
If the token endpoint reports invalid_grant or HTTP 401/403, the endpoint
returns 401 with a clear instruction to sign that account in again. Temporary
token endpoint and network failures remain upstream 502 errors.
Response:
{
"account": {
"id": "uuid-here",
"name": "claude-work",
"provider": "claude-code"
},
"state": "ok",
"collectedAt": "2026-07-25T08:30:00.000Z",
"windows": [
{
"id": "claude-code:account:5h",
"label": "5-hour limit",
"period": "5h",
"scope": "account",
"usedPercent": 31
}
],
"sources": {
"usage": {
"state": "ok",
"status": 200,
"data": {
"five_hour": {
"utilization": 31
}
}
},
"profile": {
"state": "ok",
"status": 200,
"data": {
"subscription_type": "max"
}
}
}
}state is:
okwhen every provider probe succeedspartialwhen at least one probe succeeds and another failsfailedwhen every probe fails
A partial report is returned with 200 so callers can use the successful
sources. If every source fails, the endpoint returns 502 and places the same
secret-safe report in details. Unknown account IDs return 404. Accounts
from other providers return 501 with an explicit not-implemented message.
Upstream payload fields named like credentials are redacted recursively. Provider profile/account sources can still contain non-secret identifying or subscription information. Because the management API itself has no authentication, do not expose it to untrusted networks without an authentication layer.
windows is an additive normalized projection used by the dashboard. Raw
provider data remains in sources; malformed provider fields are ignored per
window. Requests with usable normalized windows persist the latest snapshot for
GET /api/accounts. Failed or unparseable refreshes retain the last successful
windows as stale.
The server refreshes every supported account after listening and once per hour. Callers may still use this endpoint for an immediate refresh.
Example:
curl http://localhost:8080/api/accounts/uuid-here/quotaClear the selected account's local rate-limit gate and associated status,
reset, and remaining metadata. This does not change upstream quota or the
cached quota snapshot. A later provider response can immediately mark the
account as rate limited again. Unknown account IDs return 404.
Fetch the live provider-native model catalog for one selected OAuth account. Like the quota endpoint, the account is addressed directly by its ccflare account ID; load balancing, paused state, and current inference rate-limit state do not affect which credentials are queried.
Supported providers:
codex— queriesGET https://chatgpt.com/backend-api/codex/models?client_version=<version>once per known Codex CLI version (currently0.145.0and0.144.1), mirroring how the real Codex CLI discovers its cataloggrok— queries the account base URL's authoritativeGET /modelscatalog with the verified OAuth subject and official Grok Build client headers; an upstream failure returns no hardcoded catalog entries
All other providers return 501 with an explicit not-implemented message.
The response is tiered by client version, newest first. The newest tier
keeps its full catalog. Every model+effort combo that a newer tier also
advertises is culled from older tiers (culledCount records how many), so an
older tier only lists models — or individual reasoning efforts — that require
that older client version. Models known to exist but not advertised by the
remote catalog (currently codex-auto-review) are appended to the newest
successful tier with "hidden": true.
The handler refreshes missing, expired, expiry-less, or nearly expired OAuth credentials before querying. A fully unauthorized response also triggers one refresh-and-retry. Rotated tokens are persisted but are never included in the API response.
If the token endpoint reports invalid_grant or HTTP 401/403, the endpoint
returns 401 with a clear instruction to sign that account in again. Temporary
token endpoint and network failures remain upstream 502 errors.
Response:
{
"account": {
"id": "uuid-here",
"name": "codex-main",
"provider": "codex"
},
"state": "ok",
"collectedAt": "2026-07-25T08:30:00.000Z",
"versions": [
{
"clientVersion": "0.145.0",
"state": "ok",
"status": 200,
"culledCount": 0,
"models": [
{
"slug": "gpt-5.5",
"displayName": "GPT-5.5",
"defaultReasoningLevel": "medium",
"supportedReasoningLevels": [
{ "effort": "low", "description": "Fastest responses" },
{ "effort": "medium" }
]
},
{
"slug": "codex-auto-review",
"displayName": "Codex Auto Review",
"supportedReasoningLevels": [],
"hidden": true
}
]
},
{
"clientVersion": "0.144.1",
"state": "ok",
"status": 200,
"culledCount": 2,
"models": [
{
"slug": "gpt-5.1-codex",
"supportedReasoningLevels": [{ "effort": "medium" }]
}
]
}
]
}state is ok when every version fetch succeeds, partial when at least
one succeeds, and failed when every one fails. Partial reports return 200;
fully failed reports return 502 with the secret-safe report in details.
Unknown account IDs return 404.
The catalog changes only when OpenAI ships model or client gating changes. Poll no more often than every 15 minutes.
Example:
curl http://localhost:8080/api/accounts/uuid-here/modelsOAuth and auth endpoints are provider-scoped. The {provider} path segment determines which provider's OAuth flow is used (for example claude-code, codex, kimi, or grok).
Initialize an OAuth flow for adding a new account.
Request:
{
"name": "myaccount"
}Response:
{
"success": true,
"message": "OAuth flow initiated for 'myaccount'",
"data": {
"authUrl": "https://claude.ai/oauth/authorize?...",
"sessionId": "uuid-here",
"provider": "claude-code"
}
}Example:
curl -X POST http://localhost:8080/api/auth/claude-code/init \
-H "Content-Type: application/json" \
-d '{"name": "myaccount"}'Complete the OAuth flow after user authorization.
Request:
{
"sessionId": "uuid-from-init-response",
"code": "authorization-code-from-oauth"
}Response:
{
"success": true,
"message": "Account 'myaccount' added successfully!",
"data": {
"provider": "claude-code"
}
}Example:
curl -X POST http://localhost:8080/api/auth/claude-code/complete \
-H "Content-Type: application/json" \
-d '{"sessionId": "uuid-here", "code": "auth-code"}'Check the status of an in-progress OAuth session.
Example:
curl http://localhost:8080/api/auth/session/uuid-here/statusBrowser redirect target for the OAuth flow. This is the callback URL that the OAuth provider redirects to after the user authorizes. Not called directly by API consumers.
Codex and Grok normally use a loopback listener owned by oauth-flow, allowing
the stored session to complete automatically while dashboard clients continue
polling status. Grok's redirect is http://127.0.0.1:1456/callback; it validates
state plus the signed OIDC ID token and returns a small success or failure page.
Remove an account.
Response:
{
"success": true,
"message": "Account 'account-name' removed successfully"
}Example:
curl -X DELETE http://localhost:8080/api/accounts/uuid-hereUpdate an account (e.g., rename or change base_url).
Request:
{
"name": "new-name",
"base_url": "https://custom-endpoint.example.com"
}Response:
{
"success": true,
"message": "Account updated"
}Example:
curl -X PATCH http://localhost:8080/api/accounts/uuid-here \
-H "Content-Type: application/json" \
-d '{"name": "new-name"}'Rename an account.
Request:
{
"name": "new-name"
}Example:
curl -X POST http://localhost:8080/api/accounts/uuid-here/rename \
-H "Content-Type: application/json" \
-d '{"name": "new-name"}'Pause an account temporarily.
Response:
{
"success": true,
"message": "Account 'myaccount' paused"
}Example:
curl -X POST http://localhost:8080/api/accounts/uuid-here/pauseResume a paused account.
Response:
{
"success": true,
"message": "Account 'myaccount' resumed"
}Example:
curl -X POST http://localhost:8080/api/accounts/uuid-here/resumeGet overall usage statistics.
Response:
{
"totalRequests": 5000,
"successRate": 98.5,
"activeAccounts": 4,
"avgResponseTime": 1250.5,
"totalTokens": 1500000,
"totalCostUsd": 125.50,
"avgTokensPerSecond": null,
"topModels": [
{"model": "claude-3-opus-20240229", "count": 3000},
{"model": "claude-3-sonnet-20240229", "count": 2000}
]
}Example:
curl http://localhost:8080/api/statsReset all usage statistics.
Response:
{
"success": true,
"message": "Statistics reset successfully"
}Example:
curl -X POST http://localhost:8080/api/stats/resetGet recent request summary.
Query Parameters:
limit- Number of requests to return (default: 50)
Response:
[
{
"id": "request-uuid",
"timestamp": "2024-12-17T10:30:45.123Z",
"method": "POST",
"path": "/v1/anthropic/v1/messages",
"accountUsed": "account1",
"statusCode": 200,
"success": true,
"errorMessage": null,
"responseTimeMs": 1234,
"failoverAttempts": 0,
"model": "claude-sonnet-4-20250514",
"promptTokens": 50,
"completionTokens": 100,
"totalTokens": 150,
"inputTokens": 50,
"outputTokens": 100,
"cacheReadInputTokens": 0,
"cacheCreationInputTokens": 0,
"costUsd": 0.0125,
"agentUsed": null,
"tokensPerSecond": null
}
]Example:
curl "http://localhost:8080/api/requests?limit=100"Get detailed request information for one exact stored request ID. Request and response bodies are base64-encoded to handle binary data and special characters. Unknown IDs return 404. Known pending requests, WebSocket requests, and records with missing or malformed stored payloads return a valid metadata-only RequestPayload fallback.
Response:
{
"id": "request-uuid",
"request": {
"headers": {...},
"body": "base64-encoded-body"
},
"response": {
"status": 200,
"headers": {...},
"body": "base64-encoded-body"
},
"meta": {
"trace": {
"timestamp": 1234567890,
"method": "POST",
"path": "/v1/anthropic/v1/messages"
},
"account": {
"id": "uuid",
"name": "account1"
},
"transport": {
"success": true,
"pending": false,
"retry": 0
}
}
}Example:
curl "http://localhost:8080/api/requests/request-uuid/detail"Return a stored conversation by exact request ID or by client session ID. Exact request IDs take precedence; otherwise ccflare resolves identifier to the most recent request whose client_session_id matches, including values supplied through x-ccflare-session-id.
The response depends on the resolved request transport:
- HTTP requests return the existing
application/jsonarray of request payloads in response-chain ancestor order. - WebSocket requests return a finite
application/x-ndjsonsnapshot containing one rawWebSocketTranscriptEntryper line, ordered by persisted chunk and frame sequence.
The WebSocket export flattens internal chunk boundaries while preserving lifecycle entries, direction, frame type, encoding, raw UTF-8 text, and base64 binary data. It has no total size cap and is streamed with bounded server memory. For an active connection, the response includes everything persisted when the export begins and then closes; use /transcript/stream to follow new frames live.
WebSocket responses include X-Ccflare-Conversation-Kind, X-Ccflare-Conversation-Active, and, when data exists, first/last frame sequence headers. A known WebSocket request with no persisted entries returns 200 with an empty body.
Return persisted transcript chunks for one WebSocket request. Chunks contain provider-neutral ordered entries with direction, timestamp, text/binary frame type, encoding, and raw data. Provider-specific interpretation is performed by consumers when displayed.
Query parameters:
after— return entries after this frame sequence (default0)limit— maximum chunk rows to return (default100, maximum500)
The response includes transcript bounds, a continuation cursor, and whether the WebSocket request remains active.
Stream newly persisted chunks for one WebSocket request via SSE. Event IDs are the last frame sequence in each emitted chunk. Reconnects may use the standard Last-Event-ID header or an initial after query parameter. The endpoint replays persisted data before switching to live delivery and deduplicates by frame sequence.
Stream metadata-only real-time request events via Server-Sent Events (SSE). The stream emits ingress, start, and completed summary events; it never includes stored request or response bodies. WebSocket connection start/final metadata appears here, while frame payloads use the request-scoped transcript stream.
Response: SSE stream with request events
Example:
curl -N http://localhost:8080/api/requests/streamGet current configuration.
Response:
{
"lbStrategy": "session",
"port": 8080,
"sessionDurationMs": 18000000
}Example:
curl http://localhost:8080/api/configGet current load balancing strategy.
Response:
{
"strategy": "session"
}Example:
curl http://localhost:8080/api/config/strategyUpdate load balancing strategy.
Request:
{
"strategy": "session"
}Response:
{
"success": true,
"strategy": "session"
}Available Strategies:
session- Session-based routing that maintains 5-hour sessions with individual accounts to avoid rate limits and account bans
Example:
curl -X POST http://localhost:8080/api/config/strategy \
-H "Content-Type: application/json" \
-d '{"strategy": "session"}'List all available load balancing strategies.
Response:
["session"]Example:
curl http://localhost:8080/api/strategiesGet detailed analytics data.
Query Parameters:
range- Time range:1h,6h,24h,7d,30d(default:24h)accounts- Filter by account names (comma-separated list)models- Filter by model names (comma-separated list)status- Filter by request status:all,success,error(default:all)mode- Display mode:normal,cumulative(default:normal). Cumulative mode shows running totals over timemodelBreakdown- Include per-model time series data:true,false(default:false)
Response:
{
"meta": {
"range": "24h",
"bucket": "1h",
"cumulative": false
},
"totals": {
"requests": 5000,
"successRate": 98.5,
"activeAccounts": 4,
"avgResponseTime": 1250.5,
"totalTokens": 1500000,
"totalCostUsd": 125.50,
"avgTokensPerSecond": null
},
"timeSeries": [
{
"ts": 1734430800000,
"requests": 100,
"tokens": 15000,
"costUsd": 1.25,
"successRate": 98,
"errorRate": 2,
"cacheHitRate": 15,
"avgResponseTime": 1200,
"avgTokensPerSecond": null
}
],
"tokenBreakdown": {
"inputTokens": 500000,
"cacheReadInputTokens": 100000,
"cacheCreationInputTokens": 50000,
"outputTokens": 850000
},
"modelDistribution": [
{"model": "claude-3-opus-20240229", "count": 3000}
],
"accountPerformance": [
{"name": "account1", "requests": 2500, "successRate": 99}
],
"costByModel": [
{"model": "claude-3-opus-20240229", "costUsd": 100.50, "requests": 3000, "totalTokens": 1200000}
],
"modelPerformance": [
{
"model": "claude-3-opus-20240229",
"avgResponseTime": 1300,
"p95ResponseTime": 2500,
"errorRate": 1.5,
"avgTokensPerSecond": null,
"minTokensPerSecond": null,
"maxTokensPerSecond": null
}
]
}Examples:
# Basic analytics for last 7 days
curl "http://localhost:8080/api/analytics?range=7d"
# Analytics filtered by specific accounts
curl "http://localhost:8080/api/analytics?range=24h&accounts=account1,account2"
# Analytics for specific models with success status only
curl "http://localhost:8080/api/analytics?range=24h&models=claude-3-opus-20240229,claude-3-sonnet-20240229&status=success"
# Combined filters
curl "http://localhost:8080/api/analytics?range=7d&accounts=premium1,premium2&models=claude-3-opus-20240229&status=error"Queue background data cleanup based on configured retention settings. Returns
202 Accepted immediately with data.status set to accepted or
already_running. Returns 503 when the maintenance worker is unavailable.
Example:
curl -X POST http://localhost:8080/api/maintenance/cleanupCompact the database to reclaim disk space.
Example:
curl -X POST http://localhost:8080/api/maintenance/compactGet current data retention settings.
Response:
{
"payloadDays": 7,
"requestDays": 30
}Example:
curl http://localhost:8080/api/config/retentionUpdate data retention settings.
Request:
{
"payloadDays": 14,
"requestDays": 90
}Example:
curl -X POST http://localhost:8080/api/config/retention \
-H "Content-Type: application/json" \
-d '{"payloadDays": 14, "requestDays": 90}'Stream real-time logs via Server-Sent Events (SSE).
Response: SSE stream with log events
Example:
curl -N http://localhost:8080/api/logs/streamGet historical logs.
Response:
[
{
"timestamp": "2024-12-17T10:30:45.123Z",
"level": "info",
"component": "proxy",
"message": "Request completed",
"metadata": {...}
}
]Example:
curl http://localhost:8080/api/logs/historyAll API errors follow a consistent format:
{
"error": "Error message",
"details": {
// Optional additional error details
}
}- 200 OK - Request successful
- 400 Bad Request - Invalid request parameters
- 404 Not Found - Resource not found
- 429 Too Many Requests - Rate limited
- 500 Internal Server Error - Server error
- 502 Bad Gateway - Upstream provider error
- 503 Service Unavailable - All accounts failed
When an account hits rate limits, ccflare automatically fails over to the next available account. If all accounts are rate limited, a 503 error is returned.
Rate limit information is included in account responses:
rateLimitStatus- Current status (e.g., "allowed", "allowed_warning", "rate_limited")rateLimitReset- When the rate limit resetsrateLimitRemaining- Remaining requests (if available)
The proxy endpoints support streaming responses for compatible Claude API calls. When making a streaming request:
- Include
"stream": truein your request body - The response will be
Content-Type: text/event-stream - Each chunk is delivered as a Server-Sent Event
Streaming Response Capture: ccflare automatically captures streaming response bodies for analytics and debugging purposes:
- Captured data is limited to
CF_STREAM_BODY_MAX_BYTES(default: 256KB) - The capture process doesn't interfere with the client's stream
- Captured bodies are stored base64-encoded in the request history
- If the response exceeds the size limit, it's marked as truncated in metadata
Example:
curl -X POST http://localhost:8080/v1/anthropic/v1/messages \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-20250514",
"messages": [{"role": "user", "content": "Write a poem"}],
"max_tokens": 100,
"stream": true
}'A web dashboard is available at:
http://localhost:8080/ # Dashboard
The dashboard provides a visual interface for:
- Monitoring account status and usage
- Viewing real-time analytics
- Managing configuration
- Examining request history
ccflare can be configured using the following environment variables:
PORT- Server port (default: 8080)LB_STRATEGY- Load balancing strategy (default: session)SESSION_DURATION_MS- Session duration in milliseconds (default: 18000000 / 5 hours)CLIENT_ID- OAuth client ID for Anthropic authentication (default: 9d1c250a-e61b-44d9-88ed-5944d1962f5e)CF_STREAM_BODY_MAX_BYTES- Maximum bytes to capture from streaming responses (default: 262144 / 256KB)RETRY_ATTEMPTS- Number of retry attempts for failed requests (default: 3)RETRY_DELAY_MS- Initial delay between retries in milliseconds (default: 1000)RETRY_BACKOFF- Exponential backoff multiplier for retries (default: 2)
In addition to environment variables, ccflare supports configuration through a JSON file. The config file location varies by platform:
- macOS/Linux:
~/.config/ccflare/ccflare.json(or$XDG_CONFIG_HOME/ccflare/ccflare.json) - Windows:
%LOCALAPPDATA%\ccflare\ccflare.json(or%APPDATA%\ccflare\ccflare.json)
Supported Configuration Keys:
{
"lb_strategy": "session",
"client_id": "your-oauth-client-id",
"retry_attempts": 3,
"retry_delay_ms": 1000,
"retry_backoff": 2,
"session_duration_ms": 18000000,
"port": 8080,
"stream_body_max_bytes": 262144
}Note: Environment variables take precedence over config file settings.
The following strategy is available:
session- Session-based routing that maintains 5-hour sessions with individual accounts
-
No Authentication: The API endpoints do not require authentication. ccflare manages the OAuth tokens internally for proxying to Claude.
-
Automatic Failover: When a request fails or an account is rate limited, ccflare automatically tries the next available account. If no accounts are available, requests are forwarded without authentication as a fallback.
-
Token Refresh: Access tokens are automatically refreshed when they expire.
-
Request Logging: All requests are logged with detailed metrics including tokens used, cost, and response times. Database writes are performed asynchronously to avoid blocking request processing.
-
Session Affinity: The "session" strategy maintains sticky sessions for consistent routing within a time window.
-
Rate Limit Tracking: Rate limit information is automatically extracted from responses and stored for each account, including reset times and remaining requests.
-
Provider Filtering: Accounts are automatically filtered by provider when selecting for requests, ensuring compatibility.