links-free.openapps.xyz

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.
Owned app · rev 9e2af813edac
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.
← All files
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
9e2af813ed · 5 hours ago
Bounded source sync
29eee7dafa · 1 day ago
Bounded source sync
c5e634046a · 1 day ago
Bounded source sync
12abf93e7e · 1 day ago
Bounded source sync
d0d6a654b1 · 1 day ago
Bounded source sync
e03049f905 · 1 day ago
Bounded source sync
eb5c793bfa · 1 day ago
Bounded source sync
5dd8ec26e1 · 1 day ago