The API.
Create short links from your own code, decode any NOR Bit link, and read your links’ clicks. Free, with a key you get here in one click. No account.
Your API key
Copy or download it now: once you leave this page, it’s gone.
Use it as Authorization: Bearer …. Lost it, or it leaked? Mark it deleted with DELETE /keys/current and get a new one.
Quick start
export NORBIT_KEY=nbk_…
curl -X POST https://bit.normake.com/api/v1/links \
-H "Authorization: Bearer $NORBIT_KEY" \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/a/very/long/page"}'
- Base URL
https://bit.normake.com/api/v1- Authentication
Authorization: Bearer nbk_…on every request except getting a key.- Your links are yours
- Links you create belong to your key: only it sees their detailed statistics. Anyone can decode any link and see its total clicks.
- Limits
- 100 new links and 1000 requests per key per hour; new links also count per connection, whatever key they use. 3 new keys per connection per day. Over a limit:
429withRetry-After. - Errors
- Always
{"error": "code", "message": "…"}, with the usual HTTP status. Act onerror; showmessage. - Keys are never deleted
DELETE /keys/currentmarks a key deleted: it stops working for good. The links it made keep working.- From a browser
- CORS is open, so a page on any site can call the API. Anyone who can read that page can read your key, though: keep keys on servers.
- Import it
- openapi.json works in Postman, Insomnia, Swagger Editor and client generators.
Endpoints
Click one to see its parameters, examples and errors.
POST/keysGet an API keyno key
The key is in the response once: store it, it cannot be shown again. Up to 3 keys per connection per day.
No key needed.
Request body JSON
| Field | Type | About |
|---|---|---|
label optional |
string | A name to remember the key by, such as newsletter script. Up to 80 characters; longer is cut. Shown back in GET /keys/current. |
Example
{
"label": "newsletter script"
}
Response 201
{
"prefix": "nbk_Q2x9vT4a",
"label": "newsletter script",
"status": "active",
"created_at": "2026-10-03T09:00:00Z",
"last_used_at": null,
"revoked_at": null,
"links_created": 0,
"limits": {
"links_per_hour": 100,
"requests_per_hour": 1000
},
"key": "nbk_Q2x9vT4a8YbN1cR6dE3fG7hJ0kL5mP9sU2wX4zA"
}
Errors: 429
curl
curl -X POST https://bit.normake.com/api/v1/keys \
-H 'Content-Type: application/json' \
-d '{"label": "my script"}'
GET/keys/currentThis key
Its status, limits, and how many links it has made.
Response 200
{
"prefix": "nbk_Q2x9vT4a",
"label": "newsletter script",
"status": "active",
"created_at": "2026-10-03T09:00:00Z",
"last_used_at": "2026-10-03T09:15:00Z",
"revoked_at": null,
"links_created": 12,
"limits": {
"links_per_hour": 100,
"requests_per_hour": 1000
}
}
Errors: 401 429
curl
curl -X GET https://bit.normake.com/api/v1/keys/current \
-H "Authorization: Bearer $NORBIT_KEY"
DELETE/keys/currentMark this key deleted
The key stops working immediately and cannot be restored. It is kept, marked deleted, never removed. Links it made keep redirecting and keep counting clicks; their manage links still work in a browser.
Response 200
{
"prefix": "nbk_Q2x9vT4a",
"label": "newsletter script",
"status": "revoked",
"created_at": "2026-10-03T09:00:00Z",
"last_used_at": "2026-10-03T09:15:00Z",
"revoked_at": "2026-10-04T08:00:00Z",
"links_created": 12,
"limits": {
"links_per_hour": 100,
"requests_per_hour": 1000
}
}
Errors: 401 429
curl
curl -X DELETE https://bit.normake.com/api/v1/keys/current \
-H "Authorization: Bearer $NORBIT_KEY"
POST/linksCreate a short link
The link belongs to your key. manage_url opens its page with the owner's controls (pause, delete) in a browser; keep it private. What each field accepts, and what is refused, is in the table below.
Request body JSON
| Field | Type | About |
|---|---|---|
url required |
string | Where the link goes: an http:// or https:// address, up to 4,096 characters with its tags. https:// is added if there is no scheme. Refused: private or local addresses, addresses with a user name or password in them, other link shorteners, NOR Bit itself, and addresses Google Safe Browsing lists as harmful. |
alias optional |
string | Your own code instead of a random 7-character one: 3 to 40 letters, digits or hyphens, not starting or ending with a hyphen. Stored lowercase. 409 alias_taken if it is in use, or belonged to a deleted link. |
utm optional |
object | Campaign tags to add to the destination, so its own analytics can tell where visitors came from. Each replaces a tag of the same name already in url. |
utm.source optional |
string or null | Where visitors come from: newsletter, facebook, qr-poster. Written as utm_source. Up to 200 characters. |
utm.medium optional |
string or null | The kind of channel: email, social, qr, cpc. Written as utm_medium. Up to 200 characters. |
utm.campaign optional |
string or null | The campaign it belongs to: autumn-sale. Written as utm_campaign. Up to 200 characters. |
utm.term optional |
string or null | The paid search keyword, if there is one. Written as utm_term. Up to 200 characters. |
utm.content optional |
string or null | Which link, button or ad, to tell apart links in the same campaign: header-button. Written as utm_content. Up to 200 characters. |
Example
{
"url": "https://example.com/a/very/long/page",
"alias": "my-page",
"utm": {
"source": "newsletter",
"medium": "email"
}
}
Response 201
{
"code": "k7x2m9q",
"short_url": "https://normake.com/b/k7x2m9q",
"target_url": "https://example.com/a/very/long/page?utm_source=newsletter&utm_medium=email",
"status": "active",
"created_at": "2026-10-03T09:15:00Z",
"target_updated_at": null,
"utm": {
"source": "newsletter",
"medium": "email"
},
"clicks": 0,
"qr_scans": 0,
"last_click_at": null,
"owned": true,
"decode_url": "https://bit.normake.com/d/k7x2m9q",
"qr": {
"svg": "https://bit.normake.com/b/k7x2m9q/qr.svg",
"png": "https://bit.normake.com/b/k7x2m9q/qr.png"
},
"manage_url": "https://bit.normake.com/d/k7x2m9q#key=..."
}
Errors: 400 401 409 429
curl
curl -X POST https://bit.normake.com/api/v1/links \
-H "Authorization: Bearer $NORBIT_KEY" \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/a/very/long/page"}'
GET/links/{code}Decode a link
Where any NOR Bit link goes, its status and its total clicks. Works for every link, not only your own; owned says whether your key made it.
| Parameter | In | About |
|---|---|---|
code required | path | The part after /b/. Case-insensitive. |
Response 200
{
"code": "k7x2m9q",
"short_url": "https://normake.com/b/k7x2m9q",
"target_url": "https://example.com/a/very/long/page?utm_source=newsletter&utm_medium=email",
"status": "active",
"created_at": "2026-10-03T09:15:00Z",
"target_updated_at": null,
"utm": {
"source": "newsletter",
"medium": "email"
},
"clicks": 42,
"qr_scans": 17,
"last_click_at": "2026-10-03T11:02:00Z",
"owned": true,
"decode_url": "https://bit.normake.com/d/k7x2m9q",
"qr": {
"svg": "https://bit.normake.com/b/k7x2m9q/qr.svg",
"png": "https://bit.normake.com/b/k7x2m9q/qr.png"
}
}
Errors: 401 404 429
curl
curl -X GET https://bit.normake.com/api/v1/links/k7x2m9q \
-H "Authorization: Bearer $NORBIT_KEY"
PATCH/links/{code}Change where one of your links goes, or its campaign tags
For a page that moved: the short link, its QR code, its clicks and statistics all stay the same, and it redirects to the new address at once. Only the key that made the link can change it, and the same checks as creating apply.
Send url, utm, or both. utm alone retags the current destination; with url, the tags are added to the new one.
Changes are public in outline: target_updated_at shows when the destination last changed, on the link's page too. Every earlier destination is kept, in history from GET /links/{code}/stats. Sending the current destination changes nothing. A link switched off for abuse cannot be changed.
| Parameter | In | About |
|---|---|---|
code required | path | The part after /b/. Case-insensitive. |
Request body JSON
| Field | Type | About |
|---|---|---|
url optional |
string | The new destination, with the same rules as creating a link. Leave it out to keep the current one, for example to change only the tags. Up to 4,096 characters. |
utm optional |
object | Campaign tags to set on the destination: on the new url if you send one, otherwise on the current destination. |
utm.source optional |
string or null | Where visitors come from: newsletter, facebook, qr-poster. Written as utm_source. Up to 200 characters. |
utm.medium optional |
string or null | The kind of channel: email, social, qr, cpc. Written as utm_medium. Up to 200 characters. |
utm.campaign optional |
string or null | The campaign it belongs to: autumn-sale. Written as utm_campaign. Up to 200 characters. |
utm.term optional |
string or null | The paid search keyword, if there is one. Written as utm_term. Up to 200 characters. |
utm.content optional |
string or null | Which link, button or ad, to tell apart links in the same campaign: header-button. Written as utm_content. Up to 200 characters. |
Example
{
"url": "https://example.com/the/page/moved/here"
}
Response 200
{
"code": "k7x2m9q",
"short_url": "https://normake.com/b/k7x2m9q",
"target_url": "https://example.com/the/page/moved/here",
"status": "active",
"created_at": "2026-10-03T09:15:00Z",
"target_updated_at": "2026-10-05T14:20:00Z",
"utm": {},
"clicks": 42,
"qr_scans": 17,
"last_click_at": "2026-10-03T11:02:00Z",
"owned": true,
"decode_url": "https://bit.normake.com/d/k7x2m9q",
"qr": {
"svg": "https://bit.normake.com/b/k7x2m9q/qr.svg",
"png": "https://bit.normake.com/b/k7x2m9q/qr.png"
}
}
Errors: 400 401 403 404 409 429
curl
curl -X PATCH https://bit.normake.com/api/v1/links/k7x2m9q \
-H "Authorization: Bearer $NORBIT_KEY" \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/the/page/moved/here"}'
DELETE/links/{code}Delete one of your links
Permanent: the link stops redirecting and its statistics are deleted with it. Only the key that made the link can delete it.
Its code is retired, never given to anyone else: anyone who still has the old link (on a poster, in a QR code, in a message) is told it was deleted, instead of being sent somewhere new. A link that was reported or switched off can't be deleted (409 link_disabled).
| Parameter | In | About |
|---|---|---|
code required | path | The part after /b/. Case-insensitive. |
Errors: 401 403 404 409 429
curl
curl -X DELETE https://bit.normake.com/api/v1/links/k7x2m9q \
-H "Authorization: Bearer $NORBIT_KEY"
GET/links/{code}/statsStatistics for one of your links
Clicks per day (QR scans included and also counted separately), and all-time clicks by referring site, country and device. Only for links your key made.
Link-preview bots (WhatsApp, Messenger, Slack, …) are never counted. Nothing identifies a visitor: no IP addresses are stored.
| Parameter | In | About |
|---|---|---|
code required | path | The part after /b/. Case-insensitive. |
days | query | How many days of days to return. 0 is all time. One of 7, 30, 90, 365, 0. |
Response 200
{
"code": "k7x2m9q",
"short_url": "https://normake.com/b/k7x2m9q",
"target_url": "https://example.com/a/very/long/page?utm_source=newsletter&utm_medium=email",
"status": "active",
"created_at": "2026-10-03T09:15:00Z",
"target_updated_at": null,
"utm": {
"source": "newsletter",
"medium": "email"
},
"clicks": 42,
"qr_scans": 17,
"last_click_at": "2026-10-03T11:02:00Z",
"owned": true,
"decode_url": "https://bit.normake.com/d/k7x2m9q",
"qr": {
"svg": "https://bit.normake.com/b/k7x2m9q/qr.svg",
"png": "https://bit.normake.com/b/k7x2m9q/qr.png"
},
"days": [
{
"day": "2026-10-02",
"clicks": 30,
"qr": 12
},
{
"day": "2026-10-03",
"clicks": 12,
"qr": 5
}
],
"breakdown": {
"referrer": [
{
"value": "facebook.com",
"clicks": 25
},
{
"value": "",
"clicks": 17
}
],
"country": [
{
"value": "RO",
"clicks": 38
},
{
"value": "DE",
"clicks": 4
}
],
"device": [
{
"value": "phone",
"clicks": 35
},
{
"value": "desktop",
"clicks": 7
}
]
},
"history": []
}
Errors: 400 401 403 404 429
curl
curl -X GET https://bit.normake.com/api/v1/links/k7x2m9q/stats?days=90 \
-H "Authorization: Bearer $NORBIT_KEY"
GET/openapi.jsonThis descriptionno key
OpenAPI 3.1. Import it into Postman, Insomnia or a client generator.
No key needed.
Errors: none