A lightweight URL shortener API built with Wrangler and Firebase Realtime Database.
This project is intended for personal use and small-scale deployments, and runs with minimal resource usage.
Deploy your own instance using the button below:
-
Rate limiting: daily request quotas and burst traffic protection (anti-spam).
-
No duplicates: prevents storing identical URLs, saving database space.
-
No sign-up: no account creation, credit card, or personal data required.
-
GDPR compliant: built with privacy in mind.
-
Highly configurable: customize behavior to your needs.
-
Firebase backend: stores URL mappings in Firebase Realtime Database.
-
Minimal REST API: fast, efficient, and lightweight.
-
Serverless: runs on Cloudflare Workers free plan with strict resource limits.
| Endpoint | Rate limit | Maintainer | Privacy |
|---|---|---|---|
| https://nsh.nde-code.workers.dev/ | 1 req/IP/sec, 10 new links/IP/day | Me | privacy.md |
CORS is enabled only for the URL-posting endpoint, for clear security reasons.
Check the status page if you experience latency or other issues while using my public online instance.
Notes:
-
Feel free to use my public instance, but be aware of the limits.
-
Keep an eye on the repository to catch any changes to these limits.
-
The Firebase RTDB database is located in Belgium on my public instance, so users from distant countries may experience some latency.
-
I've enabled Smart Placement routing for a better experience.
In this section, I've used https://your-worker.org.workers.dev/ in the cURL command examples. If you've deployed your own instance of the project, replace it with your instance's domain. Otherwise, use my free public instance at https://nsh.nde-code.workers.dev/, as explained above.
Create a short URL from a long URL. Saves to database and applies rate limiting.
| Field | Type | Description |
|---|---|---|
long_url |
string | Required. Original URL to shorten (must be valid) |
Note: request fails if JSON contains unexpected fields or URL exceeds max length.
| Code | Description |
|---|---|
201 |
URL successfully shortened and saved |
200 |
URL already shortened previously (returns existing short link) |
400 |
Invalid body, missing long_url, unexpected field, or invalid URL |
409 |
Hash collision (different URL, same hash) |
429 |
Rate limit exceeded (time-based or daily write limit) |
500 |
Server error (config, environment, or generation failure) |
503 |
KV quota exceeded or database read failure |
507 |
Firebase entry limit reached |
curl -X POST "https://your-worker.org.workers.dev/post-url" \
-H "Content-Type: application/json" \
-d '{"long_url": "https://nde-code.github.io/"}'{
"success": "https://your-worker.org.workers.dev/url/11i7yev0000000"
}Redirect to the original long URL using the short code.
| Parameter | Type | Description |
|---|---|---|
code |
string | Required. Unique short ID |
| Code | Description |
|---|---|
301 |
Permanent redirect (verified link) |
302 |
Temporary redirect (unverified link) |
400 |
No valid ID in path |
404 |
Link not found in database |
500 |
Server error |
503 |
Request timeout or storage connection failure |
curl -i "https://your-worker.org.workers.dev/url/11i7yev0000000"Retrieve a paginated list of shortened links.
Security: requires valid admin key (see authentication).
| Parameter | Type | Description |
|---|---|---|
count |
number | Number of links to retrieve (default: config value, max: restricted) |
cursor |
string | Last item key from previous page (use next_cursor from response) |
| Code | Description |
|---|---|
200 |
Successfully returned URLs |
400 |
Invalid count or cursor parameter |
401 |
Invalid or missing API key |
429 |
Rate limit exceeded |
500 |
Server error |
503 |
Database retrieval failure |
curl "https://your-worker.org.workers.dev/urls?count=2" \
-H "x-api-key: YOUR_ADMIN_KEY"{
"urls": {
"11i7yev0000000": {
"long_url": "https://nde-code.github.io/",
"post_date": "2024-05-12T10:00:00.000Z",
"is_verified": true
},
"vgsyqs00000000": {
"long_url": "https://www.google.com/",
"post_date": "2024-05-12T11:30:00.000Z",
"is_verified": false
}
},
"next_cursor": "vgsyqs00000000",
"has_more": true
}Mark a shortened URL as verified.
Security: requires valid admin key (see authentication).
| Parameter | Type | Description |
|---|---|---|
code |
string | Required. Unique short ID |
| Code | Description |
|---|---|
200 |
Link verified successfully (or already verified) |
400 |
No valid ID in path |
401 |
Invalid or missing admin key |
404 |
Link not found |
429 |
Rate limit exceeded |
500 |
Server error |
503 |
Database update failure |
curl -X PATCH "https://your-worker.org.workers.dev/verify/11i7yev0000000" \
-H "x-api-key: YOUR_ADMIN_KEY"Remove a shortened URL and decrement the counter.
Security: requires valid admin key (see authentication).
| Parameter | Type | Description |
|---|---|---|
code |
string | Required. Unique short ID |
| Code | Description |
|---|---|
200 |
Link deleted successfully |
400 |
No valid ID in path |
401 |
Invalid or missing admin key |
404 |
Link not found |
429 |
Rate limit exceeded |
500 |
Server error |
503 |
Database deletion failure |
curl -X DELETE "https://your-worker.org.workers.dev/delete/11i7yev0000000" \
-H "x-api-key: YOUR_ADMIN_KEY"Recalculate and sync the metadata counter to match actual URLs in Firebase. Useful for fixing race conditions or desynchronization.
Security: requires valid admin or monitoring key (see authentication).
Note: the admin key can be used to manually resynchronize the counter when needed. The monitoring key is also accepted, allowing the endpoint to be called automatically by external monitoring tools (as with
/health) or scheduled services.
| Code | Description |
|---|---|
200 |
Counter resynced successfully (returns new count) |
401 |
Invalid or missing admin key |
429 |
Rate limit exceeded |
500 |
Server error |
503 |
Database communication failure |
curl -X PATCH "https://your-worker.org.workers.dev/sync-counter" \
-H "x-api-key: YOUR_ADMIN_KEY"{
"success": "Counter synchronized successfully.",
"new_count": 42
}Check service health: configuration, database connectivity, counter integrity, capacity, and KV storage.
Security: requires valid monitoring key (see authentication).
| Code | Description |
|---|---|
200 |
All systems operational |
206 |
Degraded but operational (one or more non-critical issues) |
503 |
Service unavailable (critical failure) |
curl -X GET "https://your-worker.org.workers.dev/health" \
-H "x-api-key: YOUR_MONITORING_KEY"{
"status": "healthy",
"timestamp": "2026-04-26T20:17:27.121Z",
"checks": {
"config_valid": true,
"firebase_reachable": true,
"counter_accessible": true,
"kv_store_available": true
},
"message": "All systems operational."
}Protected endpoints require either header format:
Authorization: Bearer <MONITORING_or_ADMIN_KEY>x-api-key: <MONITORING_or_ADMIN_KEY>
Note: trying to access the administration endpoints on my public instance is completely forbidden.
For setup, configuration, and deployment using Wrangler CLI, see the developer guide.
This project is licensed under the Apache License v2.0.
Created and maintained by Nde-Code.
Don't hesitate to open an issue or a pull request if you have any questions or would like to contribute.