The OAuth endpoints handle authentication flows for providers that use OAuth 2.0, including Anthropic (Claude), Google (Gemini), Codex, and others.
OAuth Flow Overview
- Client requests authorization URL from management API
- User opens URL and completes OAuth flow with provider
- Provider redirects to callback with
code and state
- Client posts callback data to management API
- Management API writes callback file for processing
- Client polls for authentication status
Supported Providers
- anthropic / claude - Anthropic Claude API
- codex / openai - OpenAI Codex API
- gemini / google - Google Gemini API
- antigravity / anti-gravity - AntiGravity API
- qwen - Qwen API
- iflow / i-flow - iFlow API
- kimi - Kimi API
Get Authorization URL
Get the OAuth authorization URL for a specific provider.
/v0/management/{provider}-auth-url
Available Endpoints
GET /v0/management/anthropic-auth-url
GET /v0/management/codex-auth-url
GET /v0/management/gemini-cli-auth-url
GET /v0/management/antigravity-auth-url
GET /v0/management/qwen-auth-url
GET /v0/management/kimi-auth-url
GET /v0/management/iflow-auth-url
Request
curl -H "X-Management-Key: YOUR_SECRET" \
http://localhost:8317/v0/management/anthropic-auth-url
Response
OAuth authorization URL to redirect user to
OAuth state parameter for CSRF protection (store this for callback validation)
Unix timestamp when the state expires (10 minutes from creation)
{
"auth_url": "https://console.anthropic.com/oauth/authorize?client_id=...&state=abc123",
"state": "abc123def456",
"expires_at": 1710172800
}
Submit OAuth Callback
/v0/management/oauth-callback
Submits the OAuth callback data received from the provider after user authorization.
Request
curl -X POST \
-H "X-Management-Key: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"provider": "anthropic",
"state": "abc123def456",
"code": "oauth_code_from_provider"
}' \
http://localhost:8317/v0/management/oauth-callback
Request Body
Response
Status of callback processing (“ok” or “error”)
Error Responses
Invalid State
{
"status": "error",
"error": "invalid state"
}
Unknown/Expired State
{
"status": "error",
"error": "unknown or expired state"
}
Already Completed
{
"status": "error",
"error": "oauth flow is not pending"
}
Provider Mismatch
{
"status": "error",
"error": "provider does not match state"
}
Get Authentication Status
/v0/management/get-auth-status
Check the status of OAuth authentication flows. Used for polling after submitting callback.
Request
curl -H "X-Management-Key: YOUR_SECRET" \
"http://localhost:8317/v0/management/get-auth-status?provider=anthropic"
Query Parameters
Check specific OAuth session by state
Response
List of active OAuth sessionsSession status (empty = pending, otherwise error message or “completed”)
Unix timestamp when session was created
Unix timestamp when session expires
{
"sessions": [
{
"provider": "anthropic",
"state": "abc123def456",
"status": "",
"created_at": 1710172200,
"expires_at": 1710172800
}
]
}
OAuth Session Management
Session Lifecycle
- Created - Session registered when auth URL requested
- Pending - Waiting for callback (status = "")
- Completed - Callback received and processed (session deleted)
- Error - Callback failed (status contains error message)
- Expired - Session TTL exceeded (automatically cleaned up)
Session TTL
- Default TTL: 10 minutes from creation
- Automatic cleanup: Expired sessions purged periodically
- State validation: Must be alphanumeric with
-, _, . only
- Max length: 128 characters
State Security
The state parameter:
- Must be provided in both auth URL request and callback
- Used for CSRF protection
- Cannot contain path separators (
/, \)
- Cannot contain
.. (path traversal)
- Must match pattern:
[a-zA-Z0-9._-]+
Complete OAuth Flow Example
Step 1: Request Authorization URL
# Get authorization URL
curl -H "X-Management-Key: YOUR_SECRET" \
http://localhost:8317/v0/management/anthropic-auth-url
# Response
{
"auth_url": "https://console.anthropic.com/oauth/authorize?...",
"state": "abc123def456",
"expires_at": 1710172800
}
Step 2: User Completes OAuth Flow
User opens auth_url in browser and authorizes the application.
Provider redirects to callback URL:
https://your-app.com/callback?code=oauth_code&state=abc123def456
Step 3: Submit Callback
curl -X POST \
-H "X-Management-Key: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"provider": "anthropic",
"state": "abc123def456",
"code": "oauth_code"
}' \
http://localhost:8317/v0/management/oauth-callback
# Response
{"status": "ok"}
Step 4: Poll for Completion
# Check authentication status
curl -H "X-Management-Key: YOUR_SECRET" \
"http://localhost:8317/v0/management/get-auth-status?state=abc123def456"
# Pending response
{
"sessions": [
{
"provider": "anthropic",
"state": "abc123def456",
"status": "",
"created_at": 1710172200,
"expires_at": 1710172800
}
]
}
# Completed (session removed)
{
"sessions": []
}
When callback is received, the management API writes a file:
Location: {auth-dir}/.oauth-{provider}-{state}.oauth
Format:
{
"code": "oauth_authorization_code",
"state": "abc123def456",
"error": ""
}
The authentication system monitors this directory and processes new OAuth files automatically.
Alternative: Submit via Redirect URL
You can submit the entire redirect URL instead of parsing code/state:
curl -X POST \
-H "X-Management-Key: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"provider": "anthropic",
"redirect_url": "https://your-app.com/callback?code=oauth_code&state=abc123def456"
}' \
http://localhost:8317/v0/management/oauth-callback
The API will parse the query parameters automatically.
Error Handling
Provider Errors
If the provider returns an error:
curl -X POST \
-H "X-Management-Key: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"provider": "anthropic",
"state": "abc123def456",
"error": "access_denied"
}' \
http://localhost:8317/v0/management/oauth-callback
The error is recorded in the OAuth session and written to the callback file.
Session Expiration
If the state has expired (>10 minutes since auth URL request):
{
"status": "error",
"error": "unknown or expired state"
}
The client must request a new authorization URL and restart the flow.
Next Steps