# onelink.ninja
> Shareable link lists. Anyone can publish a list of links at a short URL, with
> no account. Creating one returns a secret edit token; a list can later be
> claimed by an account, after which the token stops working.
Three ways to make a list — use the first one your environment allows:
1. The JSON API below. No key. OpenAPI 3.1 spec: https://onelink.ninja/openapi.json
2. The MCP server: https://onelink.ninja/mcp (Streamable HTTP, no auth).
3. A prefill link you hand to the person (see "Prefill links").
If your environment blocks onelink.ninja, use the prefill link or the MCP server
instead of retrying.
## Reading a list
- https://onelink.ninja/l/{id} HTML page for a list.
- https://onelink.ninja/l/{id}.md The same list as plain Markdown. Prefer this one — it is
cheaper to read than the HTML and has no markup to strip.
Every HTML page advertises it via
.
- https://onelink.ninja/random 302-redirects to a random list that has at least one link.
## Writing a list
A JSON REST API creates and edits lists without a browser. Writes require
Content-Type: application/json.
- POST https://onelink.ninja/api/lists Create. Body: {title, description?, links:[{url,label,description?}]}
Returns {id, publicUrl, editUrl, editToken, markdownUrl}.
- GET https://onelink.ninja/api/lists/{id} Read.
- PATCH https://onelink.ninja/api/lists/{id} Update title/description/links.
- DELETE https://onelink.ninja/api/lists/{id} Delete.
- POST https://onelink.ninja/api/lists/{id}/links Append one link: {url, label, description?}.
- GET https://onelink.ninja/api/lists/random Random list as JSON, no redirect to follow.
Write endpoints take `Authorization: Bearer {editToken}`, or a session cookie
that owns the list once it has been claimed.
Create a list in one call:
curl -X POST https://onelink.ninja/api/lists \
-H 'content-type: application/json' \
-d '{"title":"My list","links":[{"url":"https://example.com","label":"Example"}]}'
Limits: title and labels ≤ 200 characters, descriptions ≤ 1000,
at most 20 links per list. URL schemes: http, https, mailto, tel.
The editToken returned at creation is the only credential for an unclaimed list.
Hand it back to the person you made the list for, and warn them it is the sole
way back into editing.
## MCP server
https://onelink.ninja/mcp Streamable HTTP, stateless, no auth.
Tools: create_list, get_list, add_link, update_list, delete_list, prefill_link.
They wrap the API above with the same validation and limits. Edit tools take the
editToken as `edit_token`; lists claimed by an account can't be edited over MCP.
## Prefill links
If you cannot make HTTP requests (e.g. you are a chat assistant), build a
prefill link and give it to the user. Nothing is saved until they click Publish.
https://onelink.ninja/new#data=
The JSON is the POST /api/lists body plus a version: {"v":1,"title","description"?,"links":[{url,label,description?}]}.
URL-encode it (encodeURIComponent) and put it in the fragment (#), never the
query string. Keep data= last in the link and the link under 8 KB. Invalid
links are dropped when the form opens, and the form says so.
Example, a list with one link:
https://onelink.ninja/new#data=%7B%22v%22%3A1%2C%22title%22%3A%22Climbing%20shoes%22%2C%22links%22%3A%5B%7B%22url%22%3A%22https%3A%2F%2Fexample.com%22%2C%22label%22%3A%22Example%22%7D%5D%7D
// JavaScript
const link = 'https://onelink.ninja/new#data=' + encodeURIComponent(JSON.stringify({ v: 1, ...list }));
# Python
link = "https://onelink.ninja/new#data=" + urllib.parse.quote(json.dumps({"v": 1, **lst}), safe="")
## Errors
Failures are {"error":{"code","message","details"?}}. Branch on code, not message:
invalid_body (400) · missing_credentials (401) · invalid_credentials (403)
not_found (404) · method_not_allowed (405) · rate_limited (429)
On invalid_body, details lists each failing field with its path. A 429 carries
Retry-After.
## Notes
- No API key is needed to create a list. Creation is rate limited to 10 per
minute per IP; a 429 means wait, not that you did something wrong.
- https://onelink.ninja/new.md describes these options for an agent that has landed on the
form. API catalog (RFC 9727): https://onelink.ninja/.well-known/api-catalog
- Markdown renderings are excluded from search indexes via robots.txt. They stay
fetchable — that only affects crawler indexing, not access.