unlimit-keys 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Anirban Majumder
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,64 +1,204 @@
1
- # unlimit-keys
1
+ # 🔑 unlimit-keys
2
2
 
3
- A generic, distributed API key rotator that uses Redis to select the least recently used (LRU) key from a pool. Ideal for distributing load across multiple API keys to avoid rate limits, regardless of the provider (Google, OpenAI, Anthropic, etc.).
3
+ ## **Never get blocked by rate limits again!**
4
4
 
5
- ## Installation
5
+ Tired of hitting "Rate Limit Exceeded" errors? Use this tool to automatically rotate between your API keys. It picks the best key every time you make a request - so you can use AI services (Google Gemini, Groq, OpenAI, and more) without worrying about limits!
6
6
 
7
+ ## **What you get:**
8
+ - 🚀 Use APIs 3x more (with 3 keys), 10x more (with 10 keys), etc.
9
+ - 🔄 Automatic key rotation - no manual switching
10
+ - ✅ Works with ANY API (AI, weather, payment, search, etc.)
11
+ - ⚡ Super fast - handles thousands of requests per second
12
+ - 🔒 Works perfectly with serverless apps and high-traffic services
13
+
14
+ ## Quick Start 🚀
15
+
16
+ ### Installation
17
+
18
+ **Using npm:**
7
19
  ```bash
8
20
  npm install unlimit-keys
9
21
  ```
10
22
 
23
+ **Using pnpm:**
24
+ ```bash
25
+ pnpm add unlimit-keys
26
+ ```
27
+
11
28
  ## Setup
12
29
 
13
- ### 1. Environment Variables
30
+ ### 1. Get Redis (Free!) 🗄️
31
+
32
+ We use [Upstash Redis](https://upstash.com/) - it's free and perfect for this. Follow their setup guide to get your Redis URL and token.
14
33
 
15
- Create a `.env.local` file with your Redis credentials and API keys:
34
+ Create a `.env.local` file with your keys:
16
35
 
17
36
  ```env
18
- # Upstash Redis credentials
37
+ # Upstash Redis (get from https://upstash.com - it's free!)
19
38
  REDIS_URL=https://your-redis-url.upstash.io
20
39
  REDIS_TOKEN=your-token
21
40
 
22
- # Comma-separated or newline-separated API keys
41
+ # Your API keys (comma or newline separated)
23
42
  API_KEYS="key1,key2,key3"
24
43
  ```
25
44
 
26
- ### 2. Sync Keys to Redis
45
+ ### 2. Save Your Keys 📝
27
46
 
28
- Run the sync script to load your API keys into the global Redis pool:
47
+ Run this once to save all your keys to Redis:
29
48
 
49
+ **Using npm:**
30
50
  ```bash
31
51
  npx unlimit-keys sync
32
52
  ```
33
53
 
34
- ## Usage
54
+ **Using pnpm:**
55
+ ```bash
56
+ pnpm dlx unlimit-keys sync
57
+ ```
58
+
59
+ ## How to Use It
35
60
 
36
- ### Programmatic API
61
+ ### Option 1: In Your Code 💻
37
62
 
38
63
  ```typescript
39
64
  import { getLeastUsedKey } from 'unlimit-keys';
40
65
 
41
- // Get the least recently used key
66
+ // Get the best key to use right now
42
67
  const apiKey = await getLeastUsedKey();
43
- console.log(apiKey);
68
+ console.log("Using API Key:", apiKey);
69
+
70
+ // Use it with your AI service
71
+ const response = await fetch('https://api.example.com/chat', {
72
+ headers: { 'Authorization': \`Bearer \${apiKey}\` }
73
+ });
44
74
  ```
45
75
 
46
- ### CLI
76
+ ### Option 2: Command Line 📱
47
77
 
48
78
  ```bash
49
- # Get the least recently used key via CLI
50
79
  npx unlimit-keys get-key
51
80
  ```
52
81
 
53
- ## How It Works
82
+ ## Real Examples 📚
83
+
84
+ ### Using with Google Gemini 🤖
85
+
86
+ ```typescript
87
+ import { getLeastUsedKey } from 'unlimit-keys';
88
+
89
+ async function askGemini(question: string) {
90
+ const apiKey = await getLeastUsedKey();
91
+
92
+ const response = await fetch('https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-latest:generateContent', {
93
+ method: 'POST',
94
+ headers: {
95
+ 'Content-Type': 'application/json',
96
+ 'x-goog-api-key': apiKey
97
+ },
98
+ body: JSON.stringify({
99
+ contents: [{ parts: [{ text: question }] }]
100
+ })
101
+ });
102
+
103
+ return response.json();
104
+ }
105
+
106
+ // Use many times without rate limits!
107
+ await askGemini('What is AI?');
108
+ await askGemini('How do I code?');
109
+ ```
110
+
111
+ ### Using with Groq ⚡
112
+
113
+ ```typescript
114
+ import { getLeastUsedKey } from 'unlimit-keys';
115
+ import Groq from 'groq-sdk';
116
+
117
+ async function askGroq(question: string) {
118
+ const apiKey = await getLeastUsedKey();
119
+
120
+ const client = new Groq({ apiKey });
121
+ const message = await client.messages.create({
122
+ model: 'mixtral-8x7b-32768',
123
+ max_tokens: 1024,
124
+ messages: [{ role: 'user', content: question }]
125
+ });
126
+
127
+ return message;
128
+ }
129
+
130
+ await askGroq('Tell me a joke');
131
+ ```
132
+
133
+ ### Using with Google AI SDK 🎯
134
+
135
+ ```typescript
136
+ import { getLeastUsedKey } from 'unlimit-keys';
137
+ import { GoogleGenerativeAI } from '@google/generative-ai';
138
+
139
+ async function askWithSDK(question: string) {
140
+ const apiKey = await getLeastUsedKey();
141
+ const genAI = new GoogleGenerativeAI(apiKey);
142
+
143
+ const model = genAI.getGenerativeModel({ model: 'gemini-flash-latest' });
144
+ const result = await model.generateContent(question);
145
+
146
+ return result.response.text();
147
+ }
148
+
149
+ await askWithSDK('What is machine learning?');
150
+ ```
151
+
152
+ ### Using with Regular APIs 🌍
153
+
154
+ Not just for AI! Works with any API that uses keys. Here's an example with a weather API:
155
+
156
+ ```typescript
157
+ import { getLeastUsedKey } from 'unlimit-keys';
158
+
159
+ async function getWeather(city: string) {
160
+ const apiKey = await getLeastUsedKey();
161
+
162
+ const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`, {
163
+ method: 'GET'
164
+ });
165
+
166
+ return response.json();
167
+ }
168
+
169
+ // Make lots of weather requests without hitting rate limits!
170
+ await getWeather('London');
171
+ await getWeather('New York');
172
+ await getWeather('Tokyo');
173
+ ```
174
+
175
+ ## Supported Services 🌐
176
+
177
+ **AI & ML Services:**
178
+ - 🤖 [Google Gemini](https://ai.google.dev/)
179
+ - ⚡ [Groq](https://www.groq.com/)
180
+ - 🧠 [OpenAI](https://openai.com/)
181
+ - 🤖 [Anthropic Claude](https://www.anthropic.com/)
182
+
183
+ **Other APIs:**
184
+ - Weather APIs
185
+ - Payment APIs
186
+ - Search APIs
187
+ - Translation APIs
188
+ - And literally any API that uses keys!
189
+
190
+ **Works with anything that has API rate limits!**
191
+
192
+ ## How It Works Behind the Scenes 🔧
193
+
194
+ 1. **You have multiple keys** - Like 3 API keys
195
+ 2. **We pick the best one** - We use the key that's been used the least recently
196
+ 3. **We use it** - You make your API call
197
+ 4. **We update the score** - We mark that key as just-used so we don't pick it again
198
+ 5. **Repeat!** - Next time you call us, we pick a different key
54
199
 
55
- 1. **Key Pool**: Keys are stored in a single Redis Sorted Set (`API_KEYS`).
56
- 2. **LRU Rotation**: When you request a key, the library atomically:
57
- * Finds the key with the lowest score (oldest usage timestamp).
58
- * Updates that key's score to the current timestamp.
59
- * Returns the key.
60
- 3. **Concurrency**: Atomic Lua scripts ensure no race conditions, even with high concurrency across serverless functions.
200
+ This spreads out your requests so you hit rate limits slower!
61
201
 
62
202
  ## License
63
203
 
64
- ISC
204
+ MIT
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ const program = new commander_1.Command();
17
17
  program
18
18
  .name('unlimit-keys')
19
19
  .description('Distributed LRU API key rotation using Redis')
20
- .version('0.1.5');
20
+ .version(require('../package.json').version);
21
21
  program
22
22
  .command('get-key')
23
23
  .description('Get the least recently used API key')
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,yCAAoC;AACpC,8DAA2D;AAC3D,2DAAsD;AAEtD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,GAAS,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAA,iCAAe,GAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAA,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,GAAS,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,IAAA,2BAAW,GAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAA,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,yCAAoC;AACpC,8DAA2D;AAC3D,2DAAsD;AAEtD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,8CAA8C,CAAC;KAC3D,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC;AAE/C,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,GAAS,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAA,iCAAe,GAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAA,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8CAA8C,CAAC;KAC3D,MAAM,CAAC,GAAS,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,IAAA,2BAAW,GAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAA,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "unlimit-keys",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "An API key rotation system using Redis",
5
5
  "author": "Anirban Majumder <anirbanmajumder.404@gmail.com>",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/Anirban-Majumder/unlimit-keys.git"
8
+ "url": "git+https://github.com/Anirban-Majumder/unlimit-keys.git"
9
9
  },
10
10
  "bugs": {
11
11
  "url": "https://github.com/Anirban-Majumder/unlimit-keys/issues"
@@ -31,7 +31,7 @@
31
31
  }
32
32
  },
33
33
  "bin": {
34
- "unlimit-keys": "./dist/cli.js"
34
+ "unlimit-keys": "dist/cli.js"
35
35
  },
36
36
  "files": [
37
37
  "dist"