@allratestoday/sdk 1.2.1 → 1.3.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/README.md +468 -36
- package/dist/index.d.mts +167 -24
- package/dist/index.d.ts +167 -24
- package/dist/index.js +246 -34
- package/dist/index.mjs +246 -34
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
# @allratestoday/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@allratestoday/sdk)
|
|
4
|
+
[](https://codecov.io/gh/allratestoday/exchange-rates-api)
|
|
5
|
+
[](https://snyk.io/test/github/allratestoday/exchange-rates-api)
|
|
6
|
+
[](https://github.com/allratestoday/exchange-rates-api/blob/main/LICENSE)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[](https://www.npmjs.com/package/@allratestoday/sdk)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
**The most elegant way to access real-time mid-market exchange rates in Node.js and browsers**
|
|
11
|
+
|
|
12
|
+
## Why Choose This Client?
|
|
13
|
+
|
|
14
|
+
- **Lightning Fast**: Zero runtime dependencies, pure TypeScript performance
|
|
15
|
+
- **Real-Time Data**: Rates updated every 60 seconds from Reuters (Refinitiv) and interbank feeds
|
|
16
|
+
- **Mid-Market Rates**: The true interbank rate — no hidden spread or markup
|
|
17
|
+
- **160+ Currencies**: Major, minor, and exotic currency pairs
|
|
18
|
+
- **Type-Safe**: Full TypeScript support with intelligent autocomplete
|
|
19
|
+
- **Universal**: Works seamlessly in Node.js 18+ and modern browsers
|
|
20
|
+
- **Developer-Friendly**: Simple API, extensive documentation, and great DX
|
|
21
|
+
|
|
22
|
+
## Get Your API Key
|
|
23
|
+
|
|
24
|
+
Ready to start? Get your free API key from [allratestoday.com/register](https://allratestoday.com/register) — no credit card required. The free tier includes 300 requests/month.
|
|
6
25
|
|
|
7
26
|
## Installation
|
|
8
27
|
|
|
@@ -10,50 +29,299 @@ Real-time mid-market exchange rates for 160+ currencies, sourced from Reuters (R
|
|
|
10
29
|
npm install @allratestoday/sdk
|
|
11
30
|
```
|
|
12
31
|
|
|
32
|
+
```bash
|
|
33
|
+
yarn add @allratestoday/sdk
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @allratestoday/sdk
|
|
38
|
+
```
|
|
39
|
+
|
|
13
40
|
## Quick Start
|
|
14
41
|
|
|
15
|
-
Get
|
|
42
|
+
Get up and running in seconds:
|
|
16
43
|
|
|
17
44
|
```typescript
|
|
18
45
|
import AllRatesToday from '@allratestoday/sdk';
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
// Set your API key
|
|
48
|
+
const client = new AllRatesToday({ apiKey: 'YOUR_API_KEY' });
|
|
49
|
+
|
|
50
|
+
// Get latest exchange rates
|
|
51
|
+
const { rates } = await client.latest({ base: 'USD', symbols: ['EUR', 'GBP', 'JPY'] });
|
|
52
|
+
console.log(rates);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API Reference
|
|
56
|
+
|
|
57
|
+
- [Latest Rates](#-latest-exchange-rates) — Get current exchange rates
|
|
58
|
+
- [Historical Data](#-historical-exchange-rates) — Fetch rates for specific dates
|
|
59
|
+
- [Currency Conversion](#-currency-conversion) — Convert between currencies
|
|
60
|
+
- [Time Series](#-time-series-data) — Get rates over date ranges
|
|
61
|
+
- [Available Currencies](#-available-currencies) — List all supported currencies
|
|
62
|
+
- [Single Rate](#-single-rate) — Get one currency pair
|
|
63
|
+
- [Historical by Period](#-historical-rates-by-period) — Preset period lookups
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### Latest Exchange Rates
|
|
68
|
+
|
|
69
|
+
Get the most current exchange rates with a single call:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Get all rates from USD
|
|
73
|
+
const data = await client.latest();
|
|
74
|
+
console.log(data);
|
|
75
|
+
|
|
76
|
+
// Target specific currencies
|
|
77
|
+
const data = await client.latest({ base: 'USD', symbols: ['CHF', 'GBP', 'JPY'] });
|
|
78
|
+
console.log(data);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Response:**
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
{
|
|
85
|
+
base: 'USD',
|
|
86
|
+
date: '2026-04-09T14:30:00Z',
|
|
87
|
+
rates: {
|
|
88
|
+
CHF: 0.8821,
|
|
89
|
+
GBP: 0.7891,
|
|
90
|
+
JPY: 151.42
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
21
94
|
|
|
22
|
-
|
|
95
|
+
### Historical Exchange Rates
|
|
96
|
+
|
|
97
|
+
Travel back in time to get rates from any date:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// Using a string date
|
|
101
|
+
const data = await client.forDate('2026-01-15', { base: 'USD', symbols: ['EUR'] });
|
|
102
|
+
console.log(data);
|
|
103
|
+
|
|
104
|
+
// Using a Date object
|
|
105
|
+
const data = await client.forDate(new Date('2026-01-15'), { base: 'EUR', symbols: ['USD', 'GBP'] });
|
|
106
|
+
console.log(data);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Response:**
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
{
|
|
113
|
+
base: 'USD',
|
|
114
|
+
date: '2026-01-15',
|
|
115
|
+
rates: {
|
|
116
|
+
EUR: 0.9187
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Currency Conversion
|
|
122
|
+
|
|
123
|
+
Convert any amount between currencies — including historical conversions:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Current conversion
|
|
127
|
+
const result = await client.convert('USD', 'EUR', 1000);
|
|
128
|
+
console.log(result);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Response:**
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
{
|
|
135
|
+
from: 'USD',
|
|
136
|
+
to: 'EUR',
|
|
137
|
+
amount: 1000,
|
|
138
|
+
result: 923.4,
|
|
139
|
+
rate: 0.9234
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// Historical conversion — what was $1,000 worth on Jan 15?
|
|
145
|
+
const result = await client.convert('USD', 'EUR', 1000, { date: '2026-01-15' });
|
|
146
|
+
console.log(result);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Response:**
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
{
|
|
153
|
+
from: 'USD',
|
|
154
|
+
to: 'EUR',
|
|
155
|
+
amount: 1000,
|
|
156
|
+
result: 918.7,
|
|
157
|
+
rate: 0.9187,
|
|
158
|
+
date: '2026-01-15'
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Available Currencies
|
|
163
|
+
|
|
164
|
+
Discover all 160+ supported currency symbols and names:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
const data = await client.symbols();
|
|
168
|
+
console.log(data);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Response:**
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
{
|
|
175
|
+
symbols: {
|
|
176
|
+
AED: 'United Arab Emirates Dirham',
|
|
177
|
+
AFN: 'Afghan Afghani',
|
|
178
|
+
ALL: 'Albanian Lek',
|
|
179
|
+
AMD: 'Armenian Dram',
|
|
180
|
+
AUD: 'Australian Dollar',
|
|
181
|
+
BDT: 'Bangladeshi Taka',
|
|
182
|
+
BRL: 'Brazilian Real',
|
|
183
|
+
CAD: 'Canadian Dollar',
|
|
184
|
+
CHF: 'Swiss Franc',
|
|
185
|
+
CNY: 'Chinese Yuan',
|
|
186
|
+
EUR: 'Euro',
|
|
187
|
+
GBP: 'British Pound Sterling',
|
|
188
|
+
INR: 'Indian Rupee',
|
|
189
|
+
JPY: 'Japanese Yen',
|
|
190
|
+
KRW: 'South Korean Won',
|
|
191
|
+
USD: 'United States Dollar',
|
|
192
|
+
// ...160+ currencies
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Time Series Data
|
|
198
|
+
|
|
199
|
+
Get exchange rates over a date range for trend analysis and charting:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
const data = await client.timeSeries('2026-01-01', '2026-03-31', {
|
|
203
|
+
base: 'USD',
|
|
204
|
+
symbols: ['EUR', 'GBP'],
|
|
205
|
+
});
|
|
206
|
+
console.log(data);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
**Response:**
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
{
|
|
213
|
+
base: 'USD',
|
|
214
|
+
startDate: '2026-01-01',
|
|
215
|
+
endDate: '2026-03-31',
|
|
216
|
+
rates: {
|
|
217
|
+
'2026-01-01': {
|
|
218
|
+
EUR: 0.9187,
|
|
219
|
+
GBP: 0.7834
|
|
220
|
+
},
|
|
221
|
+
'2026-01-02': {
|
|
222
|
+
EUR: 0.9195,
|
|
223
|
+
GBP: 0.7841
|
|
224
|
+
},
|
|
225
|
+
'2026-01-03': {
|
|
226
|
+
EUR: 0.9201,
|
|
227
|
+
GBP: 0.7856
|
|
228
|
+
},
|
|
229
|
+
// ...
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Single Rate
|
|
235
|
+
|
|
236
|
+
Get a single exchange rate between two currencies:
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
23
239
|
const rate = await client.getRate('USD', 'EUR');
|
|
24
|
-
console.log(
|
|
240
|
+
console.log(rate);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Response:**
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
{
|
|
247
|
+
from: { currency: 'USD', amount: 1 },
|
|
248
|
+
to: { currency: 'EUR', amount: 0.9234 },
|
|
249
|
+
rate: 0.9234,
|
|
250
|
+
source: 'wise'
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
// With amount
|
|
256
|
+
const rate = await client.getRate('USD', 'EUR', 500);
|
|
257
|
+
console.log(`$500 = €${rate.to.amount}`);
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Historical Rates by Period
|
|
25
261
|
|
|
26
|
-
|
|
27
|
-
const result = await client.convert('USD', 'EUR', 100);
|
|
28
|
-
console.log(`$100 = €${result.result}`);
|
|
262
|
+
Get historical rates using preset periods — no date math needed:
|
|
29
263
|
|
|
30
|
-
|
|
264
|
+
```typescript
|
|
31
265
|
const history = await client.getHistoricalRates('USD', 'EUR', '30d');
|
|
32
|
-
console.log(history
|
|
266
|
+
console.log(history);
|
|
33
267
|
```
|
|
34
268
|
|
|
35
|
-
|
|
269
|
+
**Response:**
|
|
36
270
|
|
|
37
|
-
|
|
271
|
+
```javascript
|
|
272
|
+
{
|
|
273
|
+
source: 'USD',
|
|
274
|
+
target: 'EUR',
|
|
275
|
+
period: '30d',
|
|
276
|
+
current: { rate: 0.9234, time: '2026-04-09T14:30:00Z' },
|
|
277
|
+
rates: [
|
|
278
|
+
{ rate: 0.9198, time: '2026-03-10T00:00:00Z' },
|
|
279
|
+
{ rate: 0.9210, time: '2026-03-11T00:00:00Z' },
|
|
280
|
+
// ...
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
```
|
|
38
284
|
|
|
39
|
-
|
|
40
|
-
|--------|------|---------|-------------|
|
|
41
|
-
| `apiKey` | `string` | **required** | Your API key ([register free](https://allratestoday.com/register)) |
|
|
42
|
-
| `baseUrl` | `string` | `https://allratestoday.com` | API base URL |
|
|
43
|
-
| `timeout` | `number` | `10000` | Request timeout in ms |
|
|
285
|
+
**Available periods:** `1d` | `7d` | `30d` | `1y`
|
|
44
286
|
|
|
45
|
-
|
|
287
|
+
---
|
|
46
288
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
289
|
+
## Configuration
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
const client = new AllRatesToday({
|
|
293
|
+
apiKey: 'YOUR_API_KEY', // Required — get one free at allratestoday.com/register
|
|
294
|
+
baseUrl: 'https://allratestoday.com', // Optional — API base URL
|
|
295
|
+
timeout: 10000, // Optional — request timeout in ms
|
|
296
|
+
});
|
|
297
|
+
```
|
|
53
298
|
|
|
54
|
-
|
|
299
|
+
| Option | Type | Default | Description |
|
|
300
|
+
| --------- | -------- | --------------------------- | -------------------------------- |
|
|
301
|
+
| `apiKey` | `string` | — | Your API key |
|
|
302
|
+
| `baseUrl` | `string` | `https://allratestoday.com` | API base URL |
|
|
303
|
+
| `timeout` | `number` | `10000` | Request timeout in milliseconds |
|
|
55
304
|
|
|
56
|
-
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Per-Request API Key Override
|
|
308
|
+
|
|
309
|
+
Every method supports a per-request API key override — useful for multi-tenant apps:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
const client = new AllRatesToday({ apiKey: 'default_key' });
|
|
313
|
+
|
|
314
|
+
// Override for a specific request
|
|
315
|
+
const data = await client.latest({ apiKey: 'other_users_key' });
|
|
316
|
+
const result = await client.convert('USD', 'EUR', 100, { apiKey: 'tenant_key' });
|
|
317
|
+
const { symbols } = await client.symbols({ apiKey: 'another_key' });
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Error Handling
|
|
323
|
+
|
|
324
|
+
All errors are thrown as `AllRatesTodayError` with an optional HTTP status code:
|
|
57
325
|
|
|
58
326
|
```typescript
|
|
59
327
|
import AllRatesToday, { AllRatesTodayError } from '@allratestoday/sdk';
|
|
@@ -62,28 +330,192 @@ try {
|
|
|
62
330
|
const rate = await client.getRate('USD', 'INVALID');
|
|
63
331
|
} catch (err) {
|
|
64
332
|
if (err instanceof AllRatesTodayError) {
|
|
65
|
-
console.log(err.message); //
|
|
66
|
-
console.log(err.status); //
|
|
333
|
+
console.log(err.message); // "Currency not found"
|
|
334
|
+
console.log(err.status); // 404
|
|
67
335
|
}
|
|
68
336
|
}
|
|
69
337
|
```
|
|
70
338
|
|
|
339
|
+
| Status | Meaning |
|
|
340
|
+
| ------ | ------------------------------------ |
|
|
341
|
+
| — | Missing API key (thrown before request) |
|
|
342
|
+
| `401` | Invalid API key |
|
|
343
|
+
| `404` | Currency code not found |
|
|
344
|
+
| `429` | Rate limit exceeded |
|
|
345
|
+
| `500` | Server error |
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## TypeScript
|
|
350
|
+
|
|
351
|
+
The SDK is written in TypeScript and ships full type definitions. All interfaces are exported:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import AllRatesToday, {
|
|
355
|
+
AllRatesTodayError,
|
|
356
|
+
AllRatesTodayOptions,
|
|
357
|
+
RequestOptions,
|
|
358
|
+
RateResponse,
|
|
359
|
+
AuthRateResponse,
|
|
360
|
+
LatestOptions,
|
|
361
|
+
LatestResponse,
|
|
362
|
+
ForDateOptions,
|
|
363
|
+
ForDateResponse,
|
|
364
|
+
ConvertOptions,
|
|
365
|
+
ConvertResponse,
|
|
366
|
+
TimeSeriesOptions,
|
|
367
|
+
TimeSeriesResponse,
|
|
368
|
+
HistoricalRateResponse,
|
|
369
|
+
SymbolsResponse,
|
|
370
|
+
} from '@allratestoday/sdk';
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## CommonJS
|
|
376
|
+
|
|
377
|
+
```javascript
|
|
378
|
+
const AllRatesToday = require('@allratestoday/sdk').default;
|
|
379
|
+
|
|
380
|
+
const client = new AllRatesToday({ apiKey: 'YOUR_API_KEY' });
|
|
381
|
+
client.latest().then(data => console.log(data.rates));
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Examples
|
|
387
|
+
|
|
388
|
+
### Currency Dropdown (React)
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
import { useEffect, useState } from 'react';
|
|
392
|
+
import AllRatesToday from '@allratestoday/sdk';
|
|
393
|
+
|
|
394
|
+
const client = new AllRatesToday({ apiKey: 'YOUR_API_KEY' });
|
|
395
|
+
|
|
396
|
+
function CurrencySelect({ value, onChange }) {
|
|
397
|
+
const [currencies, setCurrencies] = useState([]);
|
|
398
|
+
|
|
399
|
+
useEffect(() => {
|
|
400
|
+
client.symbols().then(({ symbols }) => {
|
|
401
|
+
setCurrencies(
|
|
402
|
+
Object.entries(symbols).map(([code, name]) => ({ code, name }))
|
|
403
|
+
);
|
|
404
|
+
});
|
|
405
|
+
}, []);
|
|
406
|
+
|
|
407
|
+
return (
|
|
408
|
+
<select value={value} onChange={e => onChange(e.target.value)}>
|
|
409
|
+
{currencies.map(c => (
|
|
410
|
+
<option key={c.code} value={c.code}>{c.code} — {c.name}</option>
|
|
411
|
+
))}
|
|
412
|
+
</select>
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Price Display with Caching
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import AllRatesToday from '@allratestoday/sdk';
|
|
421
|
+
|
|
422
|
+
const client = new AllRatesToday({ apiKey: 'YOUR_API_KEY' });
|
|
423
|
+
let cache: { rates: Record<string, number>; time: number } | null = null;
|
|
424
|
+
const TTL = 5 * 60 * 1000; // 5 minutes
|
|
425
|
+
|
|
426
|
+
async function getPrice(amountUSD: number, currency: string): Promise<string> {
|
|
427
|
+
if (!cache || Date.now() - cache.time > TTL) {
|
|
428
|
+
const data = await client.latest({ base: 'USD' });
|
|
429
|
+
cache = { rates: data.rates, time: Date.now() };
|
|
430
|
+
}
|
|
431
|
+
const converted = (amountUSD * cache.rates[currency]).toFixed(2);
|
|
432
|
+
return `${converted} ${currency}`;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
console.log(await getPrice(99.99, 'EUR')); // "92.32 EUR"
|
|
436
|
+
console.log(await getPrice(99.99, 'GBP')); // "78.90 GBP"
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Historical Chart Data
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
import AllRatesToday from '@allratestoday/sdk';
|
|
443
|
+
|
|
444
|
+
const client = new AllRatesToday({ apiKey: 'YOUR_API_KEY' });
|
|
445
|
+
|
|
446
|
+
const data = await client.timeSeries('2026-01-01', '2026-04-01', {
|
|
447
|
+
base: 'USD',
|
|
448
|
+
symbols: ['EUR'],
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Format for charting libraries (Chart.js, Recharts, etc.)
|
|
452
|
+
const labels = Object.keys(data.rates).sort();
|
|
453
|
+
const values = labels.map(date => data.rates[date].EUR);
|
|
454
|
+
|
|
455
|
+
console.log({ labels, values });
|
|
456
|
+
// { labels: ['2026-01-01', '2026-01-02', ...], values: [0.92, 0.921, ...] }
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## Methods Reference
|
|
462
|
+
|
|
463
|
+
| Method | Description |
|
|
464
|
+
| ------ | ----------- |
|
|
465
|
+
| `latest(options?)` | Get latest rates for one or more currencies |
|
|
466
|
+
| `forDate(date, options?)` | Get rates for a specific historical date |
|
|
467
|
+
| `convert(from, to, amount, options?)` | Convert amount between currencies (supports historical date) |
|
|
468
|
+
| `timeSeries(start, end, options?)` | Get rates across a custom date range |
|
|
469
|
+
| `symbols(options?)` | List all 160+ supported currency codes and names |
|
|
470
|
+
| `getRate(from, to, amount?, options?)` | Get a single exchange rate |
|
|
471
|
+
| `getRates(source, target, options?)` | Get rates with full metadata |
|
|
472
|
+
| `getHistoricalRates(source, target, period?, options?)` | Historical rates by preset period (1d/7d/30d/1y) |
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Testing
|
|
477
|
+
|
|
478
|
+
Run isolated unit tests (no API calls needed):
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
npm test
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Run tests with coverage report:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
npm run test:coverage
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Watch mode for development:
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
npm run test:watch
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
71
498
|
## Pricing
|
|
72
499
|
|
|
73
|
-
| Plan
|
|
74
|
-
|
|
75
|
-
| Free
|
|
76
|
-
| Small
|
|
77
|
-
| Medium | 10,000
|
|
78
|
-
| Large
|
|
500
|
+
| Plan | Requests/Month | Price |
|
|
501
|
+
| ------ | -------------- | ---------- |
|
|
502
|
+
| Free | 300 | Free |
|
|
503
|
+
| Small | 5,000 | €4.99/mo |
|
|
504
|
+
| Medium | 10,000 | €9.99/mo |
|
|
505
|
+
| Large | 100,000 | €49.99/mo |
|
|
506
|
+
|
|
507
|
+
All plans get the same features: real-time rates (60s updates), 160+ currencies, any base currency, full API access. Plans differ only in request volume.
|
|
508
|
+
|
|
509
|
+
---
|
|
79
510
|
|
|
80
511
|
## Links
|
|
81
512
|
|
|
82
|
-
- [API Documentation](https://allratestoday.com/
|
|
513
|
+
- [API Documentation](https://allratestoday.com/developers)
|
|
83
514
|
- [Register (Free)](https://allratestoday.com/register)
|
|
84
515
|
- [Dashboard](https://allratestoday.com/profile)
|
|
85
516
|
- [Pricing](https://allratestoday.com/pricing)
|
|
86
517
|
- [Status](https://allratestoday.com/status)
|
|
518
|
+
- [GitHub](https://github.com/allratestoday/exchange-rates-api)
|
|
87
519
|
|
|
88
520
|
## License
|
|
89
521
|
|