apogeoapi 1.0.0 → 1.0.2
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/CHANGELOG.md +59 -52
- package/EXAMPLES.md +666 -666
- package/README.md +532 -532
- package/dist/index.d.ts +11 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -14
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -4
- package/dist/types/index.js.map +1 -1
- package/dist/utils/http-client.d.ts.map +1 -1
- package/dist/utils/http-client.js +5 -5
- package/dist/utils/http-client.js.map +1 -1
- package/package.json +44 -44
package/README.md
CHANGED
|
@@ -1,532 +1,532 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
Official TypeScript SDK for
|
|
4
|
-
|
|
5
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm install
|
|
22
|
-
|
|
23
|
-
# or with yarn
|
|
24
|
-
yarn add
|
|
25
|
-
|
|
26
|
-
# or with pnpm
|
|
27
|
-
pnpm add
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
##
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
import {
|
|
34
|
-
|
|
35
|
-
// Initialize with API key (recommended)
|
|
36
|
-
const client = new
|
|
37
|
-
apiKey: 'geoapi_live_xxxxx'
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- [
|
|
57
|
-
- [
|
|
58
|
-
- [
|
|
59
|
-
- [
|
|
60
|
-
- [
|
|
61
|
-
- [
|
|
62
|
-
- [
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
console.log(usa.
|
|
126
|
-
console.log(usa.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
console.log('
|
|
187
|
-
console.log('
|
|
188
|
-
console.log('
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
'
|
|
271
|
-
'https://myapp.com/
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
console.log(
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
'usage.
|
|
329
|
-
'
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
console.log('
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
console.error('
|
|
389
|
-
console.error('
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
//
|
|
431
|
-
// [SDK]
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
console.log(`
|
|
468
|
-
console.log(`
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
- [
|
|
527
|
-
- [
|
|
528
|
-
- [Support](mailto:support@
|
|
529
|
-
|
|
530
|
-
---
|
|
531
|
-
|
|
532
|
-
**Made with
|
|
1
|
+
# apogeoapi — JavaScript/TypeScript SDK
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for ApogeoAPI — professional geographic data API with comprehensive country, state, and city information, IP geolocation, and exchange rates.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/apogeoapi)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Full TypeScript Support** - Complete type definitions with autocomplete
|
|
11
|
+
- **Auto-Retry Logic** - Automatic retry with exponential backoff
|
|
12
|
+
- **Error Handling** - Typed error responses
|
|
13
|
+
- **Rate Limit Handling** - Respects retry-after headers
|
|
14
|
+
- **Multiple Auth Methods** - API Key or JWT token
|
|
15
|
+
- **Comprehensive Coverage** - All API endpoints covered
|
|
16
|
+
- **Zero Config** - Works out of the box with sensible defaults
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install apogeoapi
|
|
22
|
+
|
|
23
|
+
# or with yarn
|
|
24
|
+
yarn add apogeoapi
|
|
25
|
+
|
|
26
|
+
# or with pnpm
|
|
27
|
+
pnpm add apogeoapi
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { ApogeoAPI } from 'apogeoapi';
|
|
34
|
+
|
|
35
|
+
// Initialize with API key (recommended)
|
|
36
|
+
const client = new ApogeoAPI({
|
|
37
|
+
apiKey: 'geoapi_live_xxxxx'
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Get all countries
|
|
41
|
+
const countries = await client.geo.getCountries();
|
|
42
|
+
console.log(`Total countries: ${countries.length}`);
|
|
43
|
+
|
|
44
|
+
// Search for cities
|
|
45
|
+
const cities = await client.geo.searchCities('New York', 10);
|
|
46
|
+
console.log(cities);
|
|
47
|
+
|
|
48
|
+
// Get usage statistics
|
|
49
|
+
const dashboard = await client.account.getDashboard();
|
|
50
|
+
console.log(`API calls this month: ${dashboard.usage.requestsThisMonth}`);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Table of Contents
|
|
54
|
+
|
|
55
|
+
- [Authentication](#authentication)
|
|
56
|
+
- [Geography API](#geography-api)
|
|
57
|
+
- [Account Management](#account-management)
|
|
58
|
+
- [API Keys Management](#api-keys-management)
|
|
59
|
+
- [Billing & Subscriptions](#billing--subscriptions)
|
|
60
|
+
- [Webhooks](#webhooks)
|
|
61
|
+
- [Error Handling](#error-handling)
|
|
62
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Authentication
|
|
67
|
+
|
|
68
|
+
### API Key (Recommended for Client-Side)
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
const client = new ApogeoAPI({
|
|
72
|
+
apiKey: 'geoapi_live_xxxxx'
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### JWT Token (After Login)
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
const client = new ApogeoAPI({
|
|
80
|
+
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Or set token after initialization
|
|
84
|
+
client.setToken('new_token_here');
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Register & Login
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Register new user
|
|
91
|
+
const { user, access_token, refresh_token } = await client.auth.register({
|
|
92
|
+
email: 'user@example.com',
|
|
93
|
+
password: 'securePassword123',
|
|
94
|
+
username: 'johndoe'
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Login
|
|
98
|
+
const tokens = await client.auth.login({
|
|
99
|
+
email: 'user@example.com',
|
|
100
|
+
password: 'securePassword123'
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Token is automatically set after login
|
|
104
|
+
console.log('Logged in as:', tokens.user.username);
|
|
105
|
+
|
|
106
|
+
// Refresh token
|
|
107
|
+
const newTokens = await client.auth.refreshToken({
|
|
108
|
+
refresh_token: tokens.refresh_token
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Geography API
|
|
115
|
+
|
|
116
|
+
### Countries
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// Get all countries
|
|
120
|
+
const countries = await client.geo.getCountries();
|
|
121
|
+
|
|
122
|
+
// Get country by ISO code
|
|
123
|
+
const usa = await client.geo.getCountryByIso('US');
|
|
124
|
+
console.log(usa.name); // "United States"
|
|
125
|
+
console.log(usa.capital); // "Washington"
|
|
126
|
+
console.log(usa.currency); // "USD"
|
|
127
|
+
|
|
128
|
+
// Search countries
|
|
129
|
+
const matching = await client.geo.searchCountries('united', 5);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### States/Provinces
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// Get all states of a country
|
|
136
|
+
const usStates = await client.geo.getStates('US');
|
|
137
|
+
console.log(`US has ${usStates.length} states`);
|
|
138
|
+
|
|
139
|
+
// Get specific state
|
|
140
|
+
const california = await client.geo.getStateById(1234);
|
|
141
|
+
console.log(california.name); // "California"
|
|
142
|
+
|
|
143
|
+
// Search states
|
|
144
|
+
const texasMatch = await client.geo.searchStates('texas', 1);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Cities
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
// Get cities of a state
|
|
151
|
+
const californiaCities = await client.geo.getCities(1234, 100, 0);
|
|
152
|
+
|
|
153
|
+
// Get specific city
|
|
154
|
+
const city = await client.geo.getCityById(5678);
|
|
155
|
+
console.log(`${city.name}, ${city.state.name}`);
|
|
156
|
+
|
|
157
|
+
// Search cities
|
|
158
|
+
const newYorkCities = await client.geo.searchCities('New York', 10);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Universal Search
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// Search across all types
|
|
165
|
+
const results = await client.geo.search({
|
|
166
|
+
query: 'san',
|
|
167
|
+
limit: 20,
|
|
168
|
+
offset: 0,
|
|
169
|
+
type: 'city' // optional: 'country' | 'state' | 'city'
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
console.log(`Found ${results.total} results`);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Account Management
|
|
178
|
+
|
|
179
|
+
### Dashboard
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Get complete dashboard
|
|
183
|
+
const dashboard = await client.account.getDashboard();
|
|
184
|
+
|
|
185
|
+
console.log('User:', dashboard.user.username);
|
|
186
|
+
console.log('Tier:', dashboard.subscription.tier);
|
|
187
|
+
console.log('Usage:', dashboard.usage.requestsThisMonth, '/', dashboard.usage.monthlyQuota);
|
|
188
|
+
console.log('API Keys:', dashboard.apiKeys.active, '/', dashboard.apiKeys.max);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Profile
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Update profile
|
|
195
|
+
await client.account.updateProfile({
|
|
196
|
+
username: 'new_username',
|
|
197
|
+
email: 'newemail@example.com'
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Change password
|
|
201
|
+
await client.account.changePassword({
|
|
202
|
+
currentPassword: 'oldpass123',
|
|
203
|
+
newPassword: 'newpass456'
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Usage Statistics
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Get usage for date range
|
|
211
|
+
const stats = await client.account.getUsage({
|
|
212
|
+
startDate: new Date('2024-01-01'),
|
|
213
|
+
endDate: new Date('2024-01-31'),
|
|
214
|
+
groupBy: 'day' // or 'month'
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
stats.forEach(stat => {
|
|
218
|
+
console.log(`${stat.date}: ${stat.requests} requests`);
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## API Keys Management
|
|
225
|
+
|
|
226
|
+
### List & Create
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// List all API keys
|
|
230
|
+
const keys = await client.apiKeys.list();
|
|
231
|
+
|
|
232
|
+
// Create new API key
|
|
233
|
+
const newKey = await client.apiKeys.create({
|
|
234
|
+
name: 'Production Server',
|
|
235
|
+
expiresAt: new Date('2025-12-31')
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
console.log('Save this key:', newKey.key);
|
|
239
|
+
// Key is only shown once!
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Update & Delete
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Rename key
|
|
246
|
+
await client.apiKeys.update(keyId, {
|
|
247
|
+
name: 'Production Server v2'
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Revoke key (deactivate)
|
|
251
|
+
await client.apiKeys.revoke(keyId);
|
|
252
|
+
|
|
253
|
+
// Reactivate key
|
|
254
|
+
await client.apiKeys.activate(keyId);
|
|
255
|
+
|
|
256
|
+
// Delete permanently
|
|
257
|
+
await client.apiKeys.delete(keyId);
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Billing & Subscriptions
|
|
263
|
+
|
|
264
|
+
### Upgrade Plan
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
// Create checkout session
|
|
268
|
+
const checkout = await client.billing.createCheckoutSession(
|
|
269
|
+
'professional', // tier
|
|
270
|
+
'https://myapp.com/success', // success URL
|
|
271
|
+
'https://myapp.com/cancel' // cancel URL
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
// Redirect user to payment page
|
|
275
|
+
window.location.href = checkout.url;
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Manage Subscription
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// Access billing portal
|
|
282
|
+
const portal = await client.billing.createPortalSession(
|
|
283
|
+
'https://myapp.com/account' // return URL
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
// Redirect user to billing portal
|
|
287
|
+
window.location.href = portal.url;
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Invoices
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// Get all invoices
|
|
294
|
+
const invoices = await client.billing.getInvoices(10);
|
|
295
|
+
|
|
296
|
+
invoices.forEach(invoice => {
|
|
297
|
+
console.log(`${invoice.created}: $${invoice.amount/100} - ${invoice.status}`);
|
|
298
|
+
console.log(`PDF: ${invoice.invoice_pdf}`);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Get specific invoice
|
|
302
|
+
const invoice = await client.billing.getInvoice('in_xxxxx');
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Cancel Subscription
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// Cancel at period end
|
|
309
|
+
await client.billing.cancelSubscription();
|
|
310
|
+
// User keeps access until period ends
|
|
311
|
+
|
|
312
|
+
// Reactivate before period ends
|
|
313
|
+
await client.billing.reactivateSubscription();
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Webhooks
|
|
319
|
+
|
|
320
|
+
### Create Webhook
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// Create webhook
|
|
324
|
+
const webhook = await client.webhooks.create({
|
|
325
|
+
url: 'https://myapp.com/webhooks/apogeoapi',
|
|
326
|
+
events: [
|
|
327
|
+
'usage.quota_warning',
|
|
328
|
+
'usage.quota_exceeded',
|
|
329
|
+
'subscription.updated'
|
|
330
|
+
]
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
console.log('Webhook ID:', webhook.id);
|
|
334
|
+
console.log('Secret:', webhook.secret); // Use to validate payloads
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Manage Webhooks
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
// List all webhooks
|
|
341
|
+
const webhooks = await client.webhooks.list();
|
|
342
|
+
|
|
343
|
+
// Update webhook
|
|
344
|
+
await client.webhooks.update(webhookId, {
|
|
345
|
+
url: 'https://myapp.com/new-webhook-url',
|
|
346
|
+
events: ['subscription.created', 'subscription.canceled']
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Test webhook
|
|
350
|
+
const result = await client.webhooks.test(webhookId);
|
|
351
|
+
console.log('Test success:', result.success);
|
|
352
|
+
|
|
353
|
+
// Deactivate
|
|
354
|
+
await client.webhooks.deactivate(webhookId);
|
|
355
|
+
|
|
356
|
+
// Delete
|
|
357
|
+
await client.webhooks.delete(webhookId);
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Delivery Logs
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
// Get webhook delivery logs
|
|
364
|
+
const logs = await client.webhooks.getLogs(webhookId, 50);
|
|
365
|
+
|
|
366
|
+
logs.forEach(log => {
|
|
367
|
+
console.log(`${log.createdAt}: ${log.event} - ${log.success ? 'OK' : 'FAIL'}`);
|
|
368
|
+
if (!log.success) {
|
|
369
|
+
console.log(` Status: ${log.statusCode}`);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Error Handling
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
import { ApogeoAPI, ApogeoAPIError } from 'apogeoapi';
|
|
380
|
+
|
|
381
|
+
const client = new ApogeoAPI({ apiKey: 'xxx' });
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const country = await client.geo.getCountryByIso('INVALID');
|
|
385
|
+
} catch (error) {
|
|
386
|
+
if (error instanceof ApogeoAPIError) {
|
|
387
|
+
console.error('Status:', error.statusCode);
|
|
388
|
+
console.error('Message:', error.message);
|
|
389
|
+
console.error('Response:', error.response);
|
|
390
|
+
|
|
391
|
+
// Handle specific errors
|
|
392
|
+
if (error.statusCode === 404) {
|
|
393
|
+
console.log('Country not found');
|
|
394
|
+
} else if (error.statusCode === 429) {
|
|
395
|
+
console.log('Rate limit exceeded, retry after:', error.response?.retryAfter);
|
|
396
|
+
} else if (error.statusCode === 403) {
|
|
397
|
+
console.log('Quota exceeded or invalid API key');
|
|
398
|
+
}
|
|
399
|
+
} else {
|
|
400
|
+
console.error('Unexpected error:', error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Advanced Configuration
|
|
408
|
+
|
|
409
|
+
### Custom Configuration
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
const client = new ApogeoAPI({
|
|
413
|
+
apiKey: 'geoapi_live_xxxxx',
|
|
414
|
+
baseURL: 'https://api.apogeoapi.com/v1',
|
|
415
|
+
timeout: 30000, // 30 seconds
|
|
416
|
+
retries: 3, // retry failed requests 3 times
|
|
417
|
+
debug: true // enable debug logging
|
|
418
|
+
});
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### Debug Mode
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
const client = new ApogeoAPI({
|
|
425
|
+
apiKey: 'xxx',
|
|
426
|
+
debug: true
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// Logs all requests and retries
|
|
430
|
+
// [SDK] GET /geo/countries
|
|
431
|
+
// [SDK] Response 200 from /geo/countries
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Using Different Environments
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
// Development
|
|
438
|
+
const devClient = new ApogeoAPI({
|
|
439
|
+
apiKey: process.env.DEV_API_KEY,
|
|
440
|
+
baseURL: 'http://localhost:3000/v1'
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Production
|
|
444
|
+
const prodClient = new ApogeoAPI({
|
|
445
|
+
apiKey: process.env.PROD_API_KEY,
|
|
446
|
+
baseURL: 'https://api.apogeoapi.com/v1'
|
|
447
|
+
});
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Examples
|
|
453
|
+
|
|
454
|
+
### Complete Application Example
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
import { ApogeoAPI } from 'apogeoapi';
|
|
458
|
+
|
|
459
|
+
const client = new ApogeoAPI({
|
|
460
|
+
apiKey: process.env.GEO_API_KEY!
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
async function main() {
|
|
464
|
+
// 1. Get dashboard
|
|
465
|
+
const dashboard = await client.account.getDashboard();
|
|
466
|
+
console.log(`Welcome ${dashboard.user.username}!`);
|
|
467
|
+
console.log(`You're on the ${dashboard.subscription.tier} plan`);
|
|
468
|
+
console.log(`Usage: ${dashboard.usage.usagePercentage}%`);
|
|
469
|
+
|
|
470
|
+
// 2. Query geography data
|
|
471
|
+
const countries = await client.geo.getCountries();
|
|
472
|
+
console.log(`\nTotal countries: ${countries.length}`);
|
|
473
|
+
|
|
474
|
+
// 3. Search for specific location
|
|
475
|
+
const cities = await client.geo.searchCities('Paris', 5);
|
|
476
|
+
console.log(`\nCities named Paris:`);
|
|
477
|
+
cities.forEach(city => {
|
|
478
|
+
console.log(`- ${city.name}, ${city.state?.name}, ${city.country?.name}`);
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// 4. Check usage
|
|
482
|
+
const usage = await client.account.getUsage({
|
|
483
|
+
startDate: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
|
|
484
|
+
endDate: new Date(),
|
|
485
|
+
groupBy: 'day'
|
|
486
|
+
});
|
|
487
|
+
console.log(`\nLast 30 days usage:`, usage.length, 'days');
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
main().catch(console.error);
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## TypeScript Support
|
|
496
|
+
|
|
497
|
+
Full TypeScript support with complete type definitions:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
import { ApogeoAPI, Country, City, Tier, WebhookEvent } from 'apogeoapi';
|
|
501
|
+
|
|
502
|
+
const client = new ApogeoAPI({ apiKey: 'xxx' });
|
|
503
|
+
|
|
504
|
+
// All responses are fully typed
|
|
505
|
+
const country: Country = await client.geo.getCountryByIso('US');
|
|
506
|
+
const cities: City[] = await client.geo.searchCities('London', 10);
|
|
507
|
+
|
|
508
|
+
// Enums are typed
|
|
509
|
+
const tier: Tier = 'professional';
|
|
510
|
+
const events: WebhookEvent[] = ['usage.quota_warning', 'subscription.updated'];
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## Contributing
|
|
516
|
+
|
|
517
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
518
|
+
|
|
519
|
+
## License
|
|
520
|
+
|
|
521
|
+
MIT © ApogeoAPI
|
|
522
|
+
|
|
523
|
+
## Links
|
|
524
|
+
|
|
525
|
+
- [API Documentation](https://api.apogeoapi.com/api/docs)
|
|
526
|
+
- [npm Package](https://www.npmjs.com/package/apogeoapi)
|
|
527
|
+
- [Website](https://apogeoapi.com)
|
|
528
|
+
- [Support](mailto:support@apogeoapi.com)
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
**Made with care by the ApogeoAPI Team**
|