onelink.ninja logo onelink.ninja

API reference

Base URL is the site itself. See the overview for auth, errors and limits.

POST /api/lists

Create a list. No authentication. Rate limited.

{
	"title": "Best Tech Widgets 2026",
	"description": "Optional.",
	"links": [
		{ "url": "https://example.com/a", "label": "Widget A" },
		{ "url": "https://example.com/b", "label": "Widget B", "description": "Optional." }
	]
}

title is required and non-empty. links may be empty, but every link needs a valid absolute url and a non-empty label.

Returns 201 with { id, publicUrl, editUrl, editToken, markdownUrl }. This is the only response that ever contains the token — store it now.

GET /api/lists/{id}

Public list data. No authentication.

{
	"id": "Q20d9AsqNh",
	"title": "Best Tech Widgets 2026",
	"description": "Curated by a robot.",
	"url": "https://onelink.ninja/l/Q20d9AsqNh",
	"markdownUrl": "https://onelink.ninja/l/Q20d9AsqNh.md",
	"claimed": false,
	"createdAt": "2026-08-12T12:37:20.340Z",
	"updatedAt": "2026-08-12T12:37:20.340Z",
	"links": [{ "url": "https://example.com/a", "label": "Widget A", "description": null }]
}

404 if there is no such list. The secret token is never included.

PATCH /api/lists/{id}

Update a list. Requires a credential.

Every field is optional; send only what changes.

curl -X PATCH https://onelink.ninja/api/lists/{id} 
  -H 'content-type: application/json' 
  -H 'authorization: Bearer {editToken}' 
  -d '{"title":"Renamed"}'

Sending links replaces the whole list of links, in the order given — that is how reordering and removal work. Omit links to leave them untouched. To add one without restating the rest, use the append endpoint below.

Returns the updated list in the same shape as GET.

POST /api/lists/{id}/links

Append a single link. Requires a credential. A convenience wrapper around PATCH for the common “add one more” case.

curl -X POST https://onelink.ninja/api/lists/{id}/links 
  -H 'content-type: application/json' 
  -H 'authorization: Bearer {editToken}' 
  -d '{"url":"https://example.com/c","label":"Widget C"}'

Appends to the end. Returns 201 with the updated list.

DELETE /api/lists/{id}

Delete the list and all its links. Requires a credential. Returns { "deleted": true, "id": "…" }.

This is immediate and permanent. The public URL stops resolving for everyone.

GET /api/lists/random

A random list with at least one link. No authentication.

{
	"id": "seed-reading",
	"publicUrl": "https://onelink.ninja/l/seed-reading",
	"markdownUrl": "https://onelink.ninja/l/seed-reading.md"
}

The JSON counterpart to /random, for callers that would rather not follow a redirect. 404 if no list has any links yet.

Reading a list as text

Not part of the JSON API, but usually the cheapest option: GET /l/{id}.md returns the list as plain Markdown. If all you need is the content, prefer it over parsing this JSON.