Skip to content

Commit 5597c4c

Browse files
committed
add: readme lengkap dengan arsitektur, flowchart, erd, api reference, dan panduan
el-pablos <yeteprem.end23juni@gmail.com>
1 parent dee941c commit 5597c4c

1 file changed

Lines changed: 380 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
# claude-api
2+
3+
> Proxy server buat nge-pool multiple Anthropic API key dengan auto rotation, retry cerdas, dan monitoring dashboard. Terinspirasi dari arsitektur copilot-api.
4+
5+
[![CI](https://github.com/el-pablos/claude-api/actions/workflows/ci.yml/badge.svg)](https://github.com/el-pablos/claude-api/actions/workflows/ci.yml)
6+
![License](https://img.shields.io/badge/license-MIT-blue)
7+
![Version](https://img.shields.io/badge/version-1.0.0-green)
8+
9+
---
10+
11+
## kenapa perlu ini?
12+
13+
kalo kamu punya beberapa API key Anthropic dan pengen:
14+
15+
- **auto rotate** key saat kena rate limit
16+
- **load balance** request ke multiple key
17+
- **monitor** penggunaan tiap key dari dashboard
18+
- **drop-in replacement** — cukup ganti `ANTHROPIC_BASE_URL` di Claude Code
19+
20+
maka ini solusinya.
21+
22+
---
23+
24+
## arsitektur
25+
26+
```
27+
┌─────────────────────────────────────────────────┐
28+
│ Client │
29+
│ (Claude Code / Anthropic SDK) │
30+
└────────────────────┬────────────────────────────┘
31+
│
32+
│ ANTHROPIC_BASE_URL=http://localhost:4141
33+
▼
34+
┌─────────────────────────────────────────────────┐
35+
│ claude-api proxy │
36+
│ │
37+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
38+
│ │ Logger │→│ Auth │→│ Error │ │
39+
│ │Middleware │ │Middleware│ │ Handler │ │
40+
│ └──────────┘ └──────────┘ └──────────┘ │
41+
│ │ │
42+
│ ┌─────────▼──────────┐ │
43+
│ │ Account Pool │ │
44+
│ │ Manager │ │
45+
│ │ │ │
46+
│ │ ┌──┐ ┌──┐ ┌──┐ │ │
47+
│ │ │K1│ │K2│ │K3│ │ ← API Keys │
48+
│ │ └──┘ └──┘ └──┘ │ │
49+
│ │ │ │
50+
│ │ Strategies: │ │
51+
│ │ • round-robin │ │
52+
│ │ • weighted │ │
53+
│ │ • least-used │ │
54+
│ │ • priority │ │
55+
│ │ • random │ │
56+
│ └─────────┬──────────┘ │
57+
│ │ │
58+
│ ┌─────────▼──────────┐ │
59+
│ │ Proxy Handler │ │
60+
│ │ + Retry Logic │ │
61+
│ └─────────┬──────────┘ │
62+
└─────────────────────┼───────────────────────────┘
63+
│
64+
▼
65+
┌────────────────────┐
66+
│ api.anthropic.com │
67+
└────────────────────┘
68+
```
69+
70+
---
71+
72+
## flowchart request
73+
74+
```mermaid
75+
flowchart TD
76+
A[Client Request] --> B[Logger Middleware]
77+
B --> C[Auth Check]
78+
C --> D[Account Pool Manager]
79+
D --> E{Ada account active?}
80+
E -->|Ya| F[Select API Key by Strategy]
81+
E -->|Tidak| G[Return 503]
82+
F --> H[Forward ke Anthropic API]
83+
H --> I{Response OK?}
84+
I -->|200| J[Return ke Client]
85+
I -->|429 Rate Limit| K[Mark Rate Limited]
86+
K --> L{Retry tersisa?}
87+
L -->|Ya| D
88+
L -->|Tidak| G
89+
I -->|401/403 Auth Error| M[Mark Invalid]
90+
M --> L
91+
I -->|5xx Server Error| N[Mark Failed]
92+
N --> L
93+
```
94+
95+
---
96+
97+
## data model
98+
99+
```mermaid
100+
erDiagram
101+
POOL_STATE {
102+
array accounts
103+
int currentIndex
104+
string lastSelectedId
105+
object config
106+
}
107+
108+
API_KEY_ACCOUNT {
109+
string id PK
110+
string name
111+
string apiKey
112+
string status
113+
object usage
114+
object rateLimit
115+
object metadata
116+
object health
117+
int inFlight
118+
}
119+
120+
USAGE {
121+
int total
122+
int success
123+
int failed
124+
}
125+
126+
RATE_LIMIT {
127+
int hit
128+
timestamp resetAt
129+
}
130+
131+
METADATA {
132+
timestamp createdAt
133+
timestamp lastUsedAt
134+
int priority
135+
int weight
136+
}
137+
138+
POOL_STATE ||--o{ API_KEY_ACCOUNT : contains
139+
API_KEY_ACCOUNT ||--|| USAGE : has
140+
API_KEY_ACCOUNT ||--|| RATE_LIMIT : has
141+
API_KEY_ACCOUNT ||--|| METADATA : has
142+
```
143+
144+
---
145+
146+
## cara install
147+
148+
```bash
149+
# clone repo
150+
git clone https://github.com/el-pablos/claude-api.git
151+
cd claude-api
152+
153+
# install dependencies
154+
npm install
155+
156+
# copy env example
157+
cp env.example .env
158+
159+
# edit .env — minimal set ENCRYPTION_KEY
160+
# ENCRYPTION_KEY harus 32 karakter atau lebih
161+
162+
# jalankan development
163+
npm run dev
164+
165+
# atau production
166+
npm start
167+
```
168+
169+
---
170+
171+
## cara pakai
172+
173+
### 1. tambah API key via dashboard
174+
175+
buka `http://localhost:4141/dashboard`, klik "Add Account", masukin:
176+
177+
- **Name**: label buat key (misal `work-key-1`)
178+
- **API Key**: `sk-ant-api03-xxxxx`
179+
- **Priority**: 1-100 (default 50)
180+
- **Weight**: 1-10 (default 1)
181+
182+
### 2. atau via API
183+
184+
```bash
185+
curl -X POST http://localhost:4141/api/dashboard/accounts \
186+
-H "Content-Type: application/json" \
187+
-H "Authorization: Bearer your-secret-key" \
188+
-d '{
189+
"name": "key-1",
190+
"apiKey": "sk-ant-api03-your-key-here",
191+
"priority": 50,
192+
"weight": 1
193+
}'
194+
```
195+
196+
### 3. arahkan Claude Code ke proxy
197+
198+
```bash
199+
# set environment variable
200+
export ANTHROPIC_BASE_URL=http://localhost:4141
201+
export ANTHROPIC_API_KEY=dummy-key
202+
203+
# jalankan Claude Code seperti biasa
204+
claude
205+
```
206+
207+
atau di config Claude Code:
208+
209+
```json
210+
{
211+
"apiBaseUrl": "http://localhost:4141"
212+
}
213+
```
214+
215+
---
216+
217+
## konfigurasi
218+
219+
semua konfigurasi via environment variable:
220+
221+
| Variable | Default | Deskripsi |
222+
| --------------------- | --------------------------- | ---------------------------------------------------------------------------- |
223+
| `PORT` | `4141` | Port server |
224+
| `HOST` | `0.0.0.0` | Host binding |
225+
| `API_SECRET_KEY` | - | Secret key untuk dashboard API |
226+
| `ENCRYPTION_KEY` | - | Key enkripsi credential (min 32 chars) |
227+
| `POOL_STRATEGY` | `round-robin` | Strategi pool: `round-robin`, `weighted`, `least-used`, `priority`, `random` |
228+
| `MAX_RETRIES` | `3` | Max retry per request |
229+
| `RATE_LIMIT_COOLDOWN` | `60000` | Cooldown rate limit (ms) |
230+
| `CLAUDE_BASE_URL` | `https://api.anthropic.com` | Target Anthropic API |
231+
| `CLAUDE_API_TIMEOUT` | `300000` | Timeout request (ms) |
232+
| `DASHBOARD_ENABLED` | `true` | Enable dashboard |
233+
| `DASHBOARD_USERNAME` | `admin` | Username dashboard |
234+
| `DASHBOARD_PASSWORD` | - | Password dashboard (kosong = no auth) |
235+
236+
---
237+
238+
## pool strategies
239+
240+
### round-robin (default)
241+
242+
request didistribusi merata ke semua key secara berurutan. key yang rate limited otomatis di-skip.
243+
244+
### weighted
245+
246+
mirip round-robin tapi key dengan weight lebih tinggi dapat lebih banyak request. key dengan weight 3 dapat 3x lebih banyak dari weight 1.
247+
248+
### least-used
249+
250+
selalu pilih key yang paling sedikit sedang memproses request (in-flight). cocok kalau response time bervariasi.
251+
252+
### priority
253+
254+
selalu coba key dengan priority tertinggi dulu. turun ke priority lebih rendah kalau yang tinggi lagi not available.
255+
256+
### random
257+
258+
pilih key secara acak dari yang available. simple dan unpredictable.
259+
260+
---
261+
262+
## API reference
263+
264+
### proxy endpoints
265+
266+
| Method | Path | Deskripsi |
267+
| ------ | -------------- | ------------------------------- |
268+
| `POST` | `/v1/messages` | Proxy ke Anthropic Messages API |
269+
| `GET` | `/v1/models` | List available models |
270+
271+
### health endpoints
272+
273+
| Method | Path | Deskripsi |
274+
| ------ | ------------------ | ---------------------------- |
275+
| `GET` | `/health` | Simple health check |
276+
| `GET` | `/health/detailed` | Detailed pool + metrics info |
277+
| `GET` | `/health/live` | Kubernetes liveness probe |
278+
| `GET` | `/health/ready` | Kubernetes readiness probe |
279+
280+
### dashboard API
281+
282+
| Method | Path | Deskripsi |
283+
| -------- | ---------------------------------------------- | ------------------- |
284+
| `GET` | `/api/dashboard/stats` | Pool statistics |
285+
| `GET` | `/api/dashboard/accounts` | List semua account |
286+
| `GET` | `/api/dashboard/accounts/:id` | Detail account |
287+
| `POST` | `/api/dashboard/accounts` | Tambah account baru |
288+
| `PUT` | `/api/dashboard/accounts/:id` | Update account |
289+
| `DELETE` | `/api/dashboard/accounts/:id` | Hapus account |
290+
| `POST` | `/api/dashboard/accounts/:id/disable` | Disable account |
291+
| `POST` | `/api/dashboard/accounts/:id/enable` | Enable account |
292+
| `POST` | `/api/dashboard/accounts/:id/reset-rate-limit` | Reset rate limit |
293+
| `GET` | `/api/dashboard/metrics` | Real-time metrics |
294+
| `GET` | `/api/dashboard/logs` | Recent request logs |
295+
| `GET` | `/api/dashboard/config` | Pool config |
296+
| `PUT` | `/api/dashboard/config` | Update config |
297+
298+
---
299+
300+
## testing
301+
302+
```bash
303+
# semua test
304+
npm test
305+
306+
# unit test aja
307+
npm run test:unit
308+
309+
# dengan coverage
310+
npm run test:coverage
311+
312+
# watch mode
313+
npm run test:watch
314+
```
315+
316+
---
317+
318+
## troubleshooting
319+
320+
**semua key kena rate limit**
321+
322+
- proxy return 503 dengan pesan "No available accounts in pool"
323+
- tunggu cooldown period (default 60 detik) atau tambah key baru
324+
- cek dashboard buat liat status tiap key
325+
326+
**key di-mark invalid**
327+
328+
- biasanya karena API key salah atau expired
329+
- cek key di Anthropic Console
330+
- enable kembali via dashboard setelah fix
331+
332+
**streaming tidak jalan**
333+
334+
- pastikan client support SSE
335+
- proxy forward streaming response as-is dari Anthropic
336+
337+
**dashboard tidak bisa diakses**
338+
339+
- cek `DASHBOARD_ENABLED=true`
340+
- kalau pake password, set `DASHBOARD_PASSWORD` di .env
341+
342+
---
343+
344+
## development
345+
346+
```bash
347+
# dev mode (auto-reload)
348+
npm run dev
349+
350+
# typecheck
351+
npm run typecheck
352+
353+
# build
354+
npm run build
355+
```
356+
357+
---
358+
359+
## tech stack
360+
361+
- **Runtime**: Node.js 20+
362+
- **Framework**: Hono
363+
- **Language**: TypeScript
364+
- **Testing**: Vitest
365+
- **Dashboard**: Alpine.js + Tailwind CSS + Chart.js
366+
- **CI/CD**: GitHub Actions
367+
368+
---
369+
370+
## kontributor
371+
372+
| | Nama | Role |
373+
| --- | ------------- | -------------------- |
374+
| | **el-pablos** | Creator & Maintainer |
375+
376+
---
377+
378+
## license
379+
380+
MIT License - bebas dipakai, dimodifikasi, dan didistribusikan.

0 commit comments

Comments
 (0)