A proxy server that makes OpenRouter's free models more reliable by handling API key rotation and rate limiting
When using OpenRouter's free models like DeepSeek Chat, you often encounter rate limits that can disrupt your workflow. This proxy server solves that by:
- Managing Multiple API Keys: Automatically rotates between your API keys when rate limits are hit
- Keeping Services Running: Tools like Aider and Roo-Code can keep working without interruption
- Handling Failures Gracefully: Smart retry logic and automatic recovery from errors
- Being OpenAI Compatible: Works as a drop-in replacement - just change the base URL
-
Get API Keys: Get one or more free API keys from OpenRouter
-
Install & Run:
git clone https://github.com/nexon33/Openrouter-Proxy-Server
cd Openrouter-Proxy-Server
npm install
node add-key.js # Add your API keys when prompted
node server.js- Use with Your Tools:
- For Aider:
aider --openai-api-base http://localhost:3000/v1 - For Roo-Code: Update settings with base URL
http://localhost:3000/v1 - For OpenAI SDK:
const openai = new OpenAI({
baseURL: 'http://localhost:3000/v1',
apiKey: 'dummy-key' // Real keys managed by proxy
});| Key Management π | Streaming π | Observability π |
|---|---|---|
| Smart API key rotation | Full streaming support | Comprehensive logging |
| Sticky session optimization | Automatic retry logic | Daily log rotation |
| JSON-based storage | Connection management | Error tracking |
| Rate limit handling | Chunk processing | Key status monitoring |
- Node.js 16+
- OpenRouter API key(s)
git clone https://github.com/yourrepo/Openrouter-Proxy-Server.git
cd Openrouter-Proxy-Server
npm install- Add API keys using the interactive script:
node add-key.js- Configure environment (
.env):
PORT=3000 # Default port
LOG_RETENTION_DAYS=14 # Keep logs for 14 days- Start the server:
node server.jsconst openai = new OpenAI({
baseURL: 'http://localhost:3000/v1',
apiKey: 'dummy-key' // Actual key managed by proxy
});
// Streaming response
const stream = await openai.chat.completions.create({
model: 'deepseek/deepseek-chat:free',
messages: [{ role: 'user', content: 'Hello' }],
stream: true
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || '');
}curl -X POST http://localhost:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer dummy-key" \
-d '{
"model": "deepseek/deepseek-chat:free",
"messages": [{"role": "user", "content": "Hello"}]
}'graph TD
A[New Request] --> B{Current Key<br>Available?}
B -->|Yes| C{Key in<br>Cooldown?}
B -->|No| D[Get Oldest<br>Available Key]
C -->|No| E[Use Current Key]
C -->|Yes| D
E --> F{Request<br>Success?}
F -->|Yes| G[Update Last Used]
F -->|No| H{Rate Limit<br>Error?}
H -->|Yes| I[Set Cooldown<br>Period]
H -->|No| J[Increment<br>Failure Count]
J --> K{Failures >= 5?}
K -->|Yes| L[Deactivate Key]
K -->|No| M[Save State]
D --> N{Valid Keys<br>Found?}
N -->|Yes| E
N -->|No| O[Return Error]
I --> D
L --> D
M --> D[Try Next Key]
The key rotation system implements:
- Sticky Sessions: Uses same key for consecutive requests when possible
- Smart Cooldown: Rate-limited keys enter cooldown based on rate limit headers
- Failure Tracking: Keys are deactivated after 5 consecutive failures
- Age-based Selection: Rotates to least recently used available key
- Automatic Recovery: Keys automatically reactivate after cooldown period
- Key Reactivation: Deactivated keys can be re-added through admin API
POST /v1/chat/completions
- OpenAI-compatible chat completions endpoint
- Supports both streaming and non-streaming responses
- Auto-retries on rate limits (max 3 attempts)
- Headers:
Content-Type: application/jsonAuthorization: Bearer dummy-key(actual key managed by proxy)
GET /v1/models
- Retrieves available models from OpenRouter
- Auto-retries on rate limits (max 3 attempts)
- Headers:
Authorization: Bearer dummy-key
POST /admin/keys
- Adds new API keys to the rotation pool
- Body:
{ "key": "your-openrouter-api-key" } - Protected endpoint (consider adding authentication)
-
Rate Limits
- Symptom: 429 status code
- Solution: System automatically rotates keys and retries
- Prevention: Add more API keys or increase request intervals
-
Streaming Disconnections
- Symptom: Stream ends unexpectedly
- Solution:
- Check network stability
- Use non-streaming mode for unreliable connections
- Implement client-side retry logic
-
No Available Keys
- Symptom: "No available API keys" error
- Solution:
- Add new keys via admin API
- Wait for cooldown period to end
- Check key status in logs
-
High Latency
- Symptom: Slow response times
- Solution:
- Add more API keys to rotation pool
- Monitor network conditions
- Consider server location relative to API
logs/requests-%DATE%.log: Request/response detailslogs/errors-%DATE%.log: Error stack traceslogs/keys-%DATE%.log: Key rotation events
graph TD
A[Client Request] --> B[Express Server]
B --> C[Request Logging]
C --> D[Key Manager]
D --> E[OpenRouter API]
D --> F[Key Storage]
E --> G[Response Handler]
G --> H[Stream Processor]
G --> I[Error Handler]
-
Express Server
- Handles HTTP routing
- Manages request/response lifecycle
- Implements error middleware
-
Key Manager
- Maintains key rotation logic
- Tracks key health and status
- Implements cooldown periods
-
Logging System
- Request logging middleware
- Error tracking
- Key event monitoring
-
Stream Handler
- Manages SSE connections
- Processes stream chunks
- Handles disconnections
- Separation of concerns
- Automatic recovery
- Comprehensive logging
- Efficient key utilization
- Graceful error handling
MIT Β© Adrian Belmans - See LICENSE for details
