You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Response includes the **plaintext**`api_key` once, plus `key_id` and `tier_name`.
241
+
-`GET /api/v1/admin/api-keys` – list existing keys and their tiers.
242
+
-`PATCH /api/v1/admin/api-keys/{key_id}` – update `tier_name`, `is_active`, or `name`.
243
+
-`DELETE /api/v1/admin/api-keys/{key_id}` – revoke (deactivate) a key.
244
+
-`GET /api/v1/admin/api-tiers` – list all tiers, limits, and descriptions.
245
+
246
+
The admin endpoints are intended for trusted operators only; do **not** expose them directly to the public internet without appropriate protections (e.g., network restrictions, stronger auth).
247
+
248
+
#### Rate limiting behavior
249
+
250
+
Rate limiting is enforced by middleware in front of all non-admin API routes:
251
+
252
+
- Configuration is controlled via environment variables:
RATE_LIMIT_REDIS_DB=2 # Redis database used for rate limiting
257
+
REDIS_HOST=redis # Redis host
258
+
REDIS_PORT=6379 # Redis port
259
+
REDIS_PASSWORD=optional_password
260
+
```
261
+
262
+
- For each request, the middleware:
263
+
- Resolves the caller’s **tier** from the API key (if provided) or falls back to the `anonymous` tier.
264
+
- Uses Redis to track the number of requests per minute per `(tier_name, identifier)`, where `identifier` is the API key hash or client IP (via `X-Forwarded-For` or socket address).
265
+
- Enforces the tier’s `requests_per_minute` limit.
266
+
267
+
When rate limiting is enabled, responses include:
268
+
269
+
-`X-RateLimit-Limit` – the allowed number of requests per minute for the current tier (or `unlimited`).
270
+
-`X-RateLimit-Remaining` – remaining requests in the current window (or `unlimited`).
271
+
-`X-RateLimit-Reset` – UNIX timestamp when the window resets.
272
+
273
+
If a client exceeds its rate limit:
274
+
275
+
- The API returns **HTTP 429 Too Many Requests** with a JSON body describing the error.
276
+
- The response includes `Retry-After` and `X-RateLimit-*` headers indicating when to retry.
277
+
278
+
### Enrichment with User Agent Parsing
279
+
280
+
API usage logs are automatically enriched in the background with:
281
+
282
+
-**User agent parsing**: Browser, operating system, and device type
283
+
284
+
This enrichment happens asynchronously via Celery tasks to avoid blocking API requests.
285
+
286
+
**Note**: IP geocoding (country, region, city, latitude, longitude) has been removed due to licensing complexity with geocoding databases.
287
+
288
+
#### Backfilling Enrichment Data
289
+
290
+
To enrich existing API usage logs that were created before enrichment was enabled, you can use the batch enrichment task:
291
+
292
+
```python
293
+
from app.tasks.api_usage_enrichment import enrich_api_usage_logs_batch
294
+
295
+
# Enrich 100 logs at a time
296
+
enrich_api_usage_logs_batch.delay(batch_size=100)
297
+
```
298
+
299
+
This can be run repeatedly until all logs are enriched.
300
+
181
301
## AI Summarization
182
302
183
303
The API uses OpenAI's ChatGPT API to generate summaries and identify geographic named entities of historical maps and geographic datasets. To use this feature:
@@ -279,8 +399,8 @@ Data from Who's On First. [License](https://whosonfirst.org/docs/licenses/)
279
399
-[X] Search - basic faceting
280
400
-[X] Performance - Redis caching
281
401
-[X] Search - facet include/exclude
282
-
-[] Search - facet alpha and numerical pagination, and search within facets
283
-
-[] Search - advanced/fielded search
402
+
-[X] Search - facet alpha and numerical pagination, and search within facets
0 commit comments