Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 3151231032497ed786b88a0a
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
public/openapi.json
{
"openapi": "3.1.0",
"info": {
"title": "Links API",
"version": "1.1.0",
"summary": "Free short links and QR codes that never expire, a free alternative to Bitly.",
"description": "Shorten a link with one call: no account and no API key. Creating a link returns its short link, QR code, a private edit link and an ownerKey. Send the ownerKey in the x-owner-key header to read clicks (total and per day) or change the link. Links are free with no limits and never expire; only their owner can turn one off. Errors are JSON with an error sentence that says what to change. Full guide: https://links-free.openapps.xyz/llms.txt",
"contact": {
"name": "OpenApps",
"url": "https://free-apps.openapps.xyz/"
}
},
"servers": [
{
"url": "https://functions.bounded.sh/apps/3151231032497ed786b88a0a/api"
}
],
"externalDocs": {
"description": "llms.txt",
"url": "https://links-free.openapps.xyz/llms.txt"
},
"paths": {
"/": {
"get": {
"operationId": "describe",
"summary": "Describe the API and its routes",
"responses": {
"200": {
"description": "Name, docs links and routes",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"about": {
"type": "string"
},
"docs": {
"type": "string"
},
"openapi": {
"type": "string"
},
"routes": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"example": {
"name": "Links by OpenApps",
"about": "Free short links and QR codes that never expire. No account and no key to create a link; the owner key you get back lets you read clicks and change the link.",
"docs": "https://links-free.openapps.xyz/llms.txt",
"openapi": "https://links-free.openapps.xyz/openapi.json",
"routes": [
"POST /links {url, code?} -> the short link, its QR code, a private edit link and the owner key"
]
}
}
}
}
}
}
},
"/links": {
"post": {
"operationId": "createLink",
"summary": "Shorten a link",
"description": "Makes a short link. Leave out code for a random 7-character ending. Give the person the shortUrl, the qrSvg image link and the editUrl, their private page to change the link and see its clicks.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateLink"
},
"example": {
"url": "https://example.com/menus/autumn-2026",
"code": "autumn-menu"
}
}
}
},
"responses": {
"201": {
"description": "The new link, with its private edit link and owner key",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewLink"
},
"example": {
"code": "autumn-menu",
"shortUrl": "https://links-free.openapps.xyz/autumn-menu",
"url": "https://example.com/menus/autumn-2026",
"clicks": 0,
"disabled": false,
"createdAt": "2026-10-19T04:00:00.000Z",
"qrSvg": "https://functions.bounded.sh/apps/3151231032497ed786b88a0a/api/qr/autumn-menu.svg",
"editUrl": "https://links-free.openapps.xyz/e/autumn-menu#k=OWNER_KEY",
"ownerKey": "OWNER_KEY"
}
}
}
},
"400": {
"description": "The address or ending is not valid",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "That does not look like a web address."
}
}
}
},
"409": {
"description": "The ending is taken",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "\"autumn-menu\" is taken. Try another ending."
}
}
}
}
}
}
},
"/links/{code}": {
"get": {
"operationId": "getLink",
"summary": "Read a link, its clicks and clicks per day (owner)",
"parameters": [
{
"name": "code",
"in": "path",
"required": true,
"description": "The short link's ending, 3 to 32 letters, numbers, dashes or underscores.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{3,32}$"
},
"example": "autumn-menu"
},
{
"name": "x-owner-key",
"in": "header",
"required": true,
"description": "The ownerKey returned when the link was made. Anyone with it can edit the link, so keep it private.",
"schema": {
"type": "string"
},
"example": "OWNER_KEY"
}
],
"responses": {
"200": {
"description": "The link with clicksByDay: opens per UTC day over the last 90 days, oldest first, days with no opens left out",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LinkWithDays"
},
"example": {
"code": "autumn-menu",
"shortUrl": "https://links-free.openapps.xyz/autumn-menu",
"url": "https://example.com/menus/autumn-2026",
"clicks": 12,
"disabled": false,
"createdAt": "2026-10-19T04:00:00.000Z",
"qrSvg": "https://functions.bounded.sh/apps/3151231032497ed786b88a0a/api/qr/autumn-menu.svg",
"clicksByDay": [
{
"date": "2026-10-18",
"clicks": 5
},
{
"date": "2026-10-19",
"clicks": 7
}
]
}
}
}
},
"401": {
"description": "No owner key sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "Send the link's owner key in the x-owner-key header."
}
}
}
},
"403": {
"description": "Wrong owner key",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "That owner key does not match this link."
}
}
}
},
"404": {
"description": "No such link",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "This link does not exist."
}
}
}
}
}
},
"patch": {
"operationId": "updateLink",
"summary": "Change where a link goes, or turn it off or on (owner)",
"parameters": [
{
"name": "code",
"in": "path",
"required": true,
"description": "The short link's ending, 3 to 32 letters, numbers, dashes or underscores.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{3,32}$"
},
"example": "autumn-menu"
},
{
"name": "x-owner-key",
"in": "header",
"required": true,
"description": "The ownerKey returned when the link was made. Anyone with it can edit the link, so keep it private.",
"schema": {
"type": "string"
},
"example": "OWNER_KEY"
}
],
"description": "The short link and its QR code stay the same, so printed codes open the new address.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateLink"
},
"example": {
"url": "https://example.com/menus/winter-2026"
}
}
}
},
"responses": {
"200": {
"description": "The updated link",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Link"
},
"example": {
"code": "autumn-menu",
"shortUrl": "https://links-free.openapps.xyz/autumn-menu",
"url": "https://example.com/menus/winter-2026",
"clicks": 0,
"disabled": false,
"createdAt": "2026-10-19T04:00:00.000Z",
"qrSvg": "https://functions.bounded.sh/apps/3151231032497ed786b88a0a/api/qr/autumn-menu.svg"
}
}
}
},
"400": {
"description": "Nothing to change, or a value is not valid",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "Send url, disabled, or both."
}
}
}
},
"401": {
"description": "No owner key sent",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "Send the link's owner key in the x-owner-key header."
}
}
}
},
"403": {
"description": "Wrong owner key",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "That owner key does not match this link."
}
}
}
},
"404": {
"description": "No such link",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "This link does not exist."
}
}
}
}
}
}
},
"/go/{code}": {
"get": {
"operationId": "resolveLink",
"summary": "Where a short link goes (counts one click)",
"description": "What the short link itself does when someone opens it. Calling it counts one click, so do not use it to check a link.",
"parameters": [
{
"name": "code",
"in": "path",
"required": true,
"description": "The short link's ending, 3 to 32 letters, numbers, dashes or underscores.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{3,32}$"
},
"example": "autumn-menu"
}
],
"responses": {
"200": {
"description": "The destination",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri"
}
}
},
"example": {
"url": "https://example.com/menus/autumn-2026"
}
}
}
},
"404": {
"description": "No such link",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "This link does not exist."
}
}
}
},
"410": {
"description": "Its owner turned it off",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "This link was turned off by its owner."
}
}
}
}
}
}
},
"/qr/{code}.svg": {
"get": {
"operationId": "qrCode",
"summary": "The QR code of a short link as an SVG image",
"description": "The code encodes the short link, so it keeps working when the destination changes.",
"parameters": [
{
"name": "code",
"in": "path",
"required": true,
"description": "The short link's ending, 3 to 32 letters, numbers, dashes or underscores.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{3,32}$"
},
"example": "autumn-menu"
},
{
"name": "color",
"in": "query",
"required": false,
"description": "Hex color without #. Colors too light to scan are refused.",
"schema": {
"type": "string",
"pattern": "^#?[0-9a-fA-F]{6}$",
"default": "111111"
},
"example": "2e5ec4"
}
],
"responses": {
"200": {
"description": "An SVG image on white",
"content": {
"image/svg+xml": {
"schema": {
"type": "string"
}
}
}
},
"400": {
"description": "The color is not valid or too light",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "That color is too light for phones to scan. Pick a darker one."
}
}
}
},
"404": {
"description": "No such link",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
},
"example": {
"error": "This link does not exist."
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Error": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"description": "A sentence for a person that says what to change."
}
}
},
"CreateLink": {
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"maxLength": 2000,
"description": "An http or https address. \"example.com/page\" becomes \"https://example.com/page\"."
},
"code": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{3,32}$",
"description": "Optional custom ending. Reserved: api, e, new, admin, about, help, assets, art, fonts, __bounded."
}
}
},
"UpdateLink": {
"type": "object",
"minProperties": 1,
"properties": {
"url": {
"type": "string",
"maxLength": 2000,
"description": "The new destination."
},
"disabled": {
"type": "boolean",
"description": "true turns the link off; false turns it back on."
}
}
},
"Link": {
"type": "object",
"required": [
"code",
"shortUrl",
"url",
"clicks",
"disabled",
"createdAt",
"qrSvg"
],
"properties": {
"code": {
"type": "string"
},
"shortUrl": {
"type": "string",
"format": "uri"
},
"url": {
"type": "string",
"format": "uri"
},
"clicks": {
"type": "integer",
"minimum": 0,
"description": "Opens since the link was made."
},
"disabled": {
"type": "boolean"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"qrSvg": {
"type": "string",
"format": "uri",
"description": "The QR code image link."
}
}
},
"NewLink": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"type": "object",
"required": [
"editUrl",
"ownerKey"
],
"properties": {
"editUrl": {
"type": "string",
"format": "uri",
"description": "The owner's private page to change the link, see clicks per day and download the QR code."
},
"ownerKey": {
"type": "string",
"description": "Send it in x-owner-key to read or change the link. Treat it like a password."
}
}
}
]
},
"LinkWithDays": {
"allOf": [
{
"$ref": "#/components/schemas/Link"
},
{
"type": "object",
"required": [
"clicksByDay"
],
"properties": {
"clicksByDay": {
"type": "array",
"items": {
"type": "object",
"required": [
"date",
"clicks"
],
"properties": {
"date": {
"type": "string",
"format": "date",
"description": "A UTC day."
},
"clicks": {
"type": "integer",
"minimum": 1
}
}
}
}
}
}
]
}
}
}
}Change history
Quality pass: clicks per day, CSV export, links on other devices
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync