diff --git a/apps/token-server/config.ts b/apps/token-server/config.ts
--- a/apps/token-server/config.ts
+++ b/apps/token-server/config.ts
@@ -2,6 +2,14 @@
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
+interface TokenServerRateLimits {
+    windowMs: number;
+    limit: number;
+    standardHeaders: 'draft-6' | 'draft-7';
+    legacyHeaders: boolean;
+    message: string;
+}
+
 interface TokenServerConfig {
     port: Number;
     chronikUrls: string[];
@@ -13,6 +21,7 @@
     rejectedDir: string;
     maxUploadSize: number;
     whitelist: string[];
+    limiter: TokenServerRateLimits;
     iconSizes: number[];
 }
 
@@ -42,6 +51,14 @@
         'chrome-extension://aleabaopoakgpbijdnicepefdiglggfl', // dev extension
         'chrome-extension://obldfcmebhllhjlhjbnghaipekcppeag', // prod extension
     ],
+    limiter: {
+        windowMs: 120 * 60 * 1000, // 120 minutes
+        limit: 3, // Limit each IP to 10 requests per `window`
+        standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
+        legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
+        message:
+            'If you really need some eCash, throw up a diff. reviews.bitcoinabc.org',
+    },
     iconSizes: [32, 64, 128, 256, 512],
 };
 
diff --git a/apps/token-server/index.ts b/apps/token-server/index.ts
--- a/apps/token-server/index.ts
+++ b/apps/token-server/index.ts
@@ -10,6 +10,7 @@
 import { initializeTelegramBot } from './src/telegram';
 import fs from 'fs';
 import { Ecc, initWasm } from 'ecash-lib';
+import { rateLimit } from 'express-rate-limit';
 
 // Connect to available in-node chronik servers
 const chronik = new ChronikClient(config.chronikUrls);
@@ -32,6 +33,7 @@
             telegramBot,
             fs,
             ecc,
+            rateLimit(config.limiter),
         );
         console.log(`Express server started on port ${config.port}`);
 
diff --git a/apps/token-server/src/routes.ts b/apps/token-server/src/routes.ts
--- a/apps/token-server/src/routes.ts
+++ b/apps/token-server/src/routes.ts
@@ -20,7 +20,7 @@
 import { alertNewTokenIcon } from '../src/telegram';
 import cashaddr from 'ecashaddrjs';
 import { Ecc } from 'ecash-lib';
-import { rateLimit } from 'express-rate-limit';
+import { RateLimitRequestHandler } from 'express-rate-limit';
 
 /**
  * routes.ts
@@ -50,16 +50,6 @@
     },
 };
 
-// Basic IP rate limiting
-const limiter = rateLimit({
-    windowMs: 60 * 60 * 1000, // 10 minutes
-    limit: 10, // Limit each IP to 10 requests per `window` (here, per 10 minutes).
-    standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
-    legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
-    message:
-        'If you really need some eCash, throw up a diff. reviews.bitcoinabc.org',
-});
-
 /**
  * Standard IP logger function to be called by all endpoints
  * @param request express request
@@ -75,6 +65,7 @@
     telegramBot: TelegramBot,
     fs: any,
     ecc: Ecc,
+    limiter: RateLimitRequestHandler,
 ): http.Server => {
     // Initialize express
     const app: Express = express();
diff --git a/apps/token-server/test/routes.test.ts b/apps/token-server/test/routes.test.ts
--- a/apps/token-server/test/routes.test.ts
+++ b/apps/token-server/test/routes.test.ts
@@ -19,6 +19,7 @@
     MOCK_UTXO_TOKEN,
 } from './vectors';
 import { Ecc, initWasm } from 'ecash-lib';
+import { rateLimit } from 'express-rate-limit';
 
 describe('routes.js', async function () {
     let ecc: Ecc;
@@ -159,6 +160,14 @@
             mockedTgBot as unknown as TelegramBot,
             fs,
             ecc,
+            // We need higher rate limits so we do not rate limit ourselves in the tests
+            rateLimit({
+                windowMs: 60000,
+                limit: 100, // Limit each IP to 10 requests per `window`
+                standardHeaders: 'draft-7', // draft-6: `RateLimit-*` headers; draft-7: combined `RateLimit` header
+                legacyHeaders: false, // Disable the `X-RateLimit-*` headers.
+                message: 'You have rate limited your own unit tests.',
+            }),
         );
     });
     afterEach(async () => {