Developers

The OneLink API

Add tiles, change your page and read your audience and insights from your own code, Zapier, or an assistant. On every plan.

Quickstart

  1. In your dashboard, open API & assistants, type a name under API keys and click Create a key. Copy it: we only show it once.
  2. Check it works:
curl https://onelinkin.bio/api/v1/me \
  -H "Authorization: Bearer onelink_live_…"
  1. List your pages. Use a page's id or its handle anywhere a page is asked for.
curl https://onelinkin.bio/api/v1/pages \
  -H "Authorization: Bearer onelink_live_…"
  1. Add a tile. Its picture and headline come from the link.
curl -X POST https://onelinkin.bio/api/v1/pages/yourname/tiles \
  -H "Authorization: Bearer onelink_live_…" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://yournewsletter.com/p/this-week", "section": "Issues"}'

Assistants (MCP)

Claude, ChatGPT, Cursor and other assistants connect to https://onelinkin.bio/api/mcp. They sign in with OAuth, so there's no key to paste. Setup for each one is on the connect page. The tools run through the same code as the API, so the two always agree.

Endpoints

Every request is JSON. Send your key as Authorization: Bearer <key>. The full schema is in openapi.json (OpenAPI 3.1).

EndpointWhat it doesScope
GET /api/v1Versions and where the MCP server, docs and OpenAPI document are.none
GET /api/openapi.jsonThis document, as OpenAPI 3.1.none
GET /api/v1/meWho the key belongs to, its scopes and its name.any key
GET /api/v1/pagesEvery page you're on, with your role and the page's plan.page:read
GET /api/v1/pages/{page}A page's settings, its sections, and its tiles as a tree (folders hold children).page:read
PATCH /api/v1/pages/{page}Change the name, intro, design, accent, layout, buttons, social links, announcement, send-everyone-to-one-link, language, footer logo size, the link preview's title and description (share_meta, Pro), or the page's own fonts, colours, background, blocks and header (style; each section merges, '' clears a choice, null a section).page:write
GET /api/v1/pages/{page}/tilesEvery tile on the page as a flat list, in page order.page:read
POST /api/v1/pages/{page}/tilesAdd a tile from a link (its picture and headline come with it), a folder, a section button, a form, or a block: text, heading, faq, testimonials, quote, resume, timeline, countdown, marquee, file, image or social_row, with its fields in content. Files and pictures come from a public url; upload from a computer in the dashboard.page:write
POST /api/v1/pages/{page}/tiles/reorderPut tiles that share a folder (or the top level) in a new order.page:write
PATCH /api/v1/pages/{page}/tiles/{id}Change a tile: title, link, section, folder, pin, price, badge, schedule, hide, gate; a link tile's animation, goal bar and thumbnail; a block's content.page:write
DELETE /api/v1/pages/{page}/tiles/{id}Delete a tile. A tile from a link is kept out of sight so feeds don't add it back; a folder's tiles move up a level.page:write
GET /api/v1/pages/{page}/qr-codesThe page's QR codes: what each printed code holds (scan_url), where it goes now, its scans and its look. Free pages have 3; Pro and up as many as they like.page:read
POST /api/v1/pages/{page}/qr-codesMake a QR code that goes to any address. It can be repointed later without a reprint.page:write
PATCH /api/v1/pages/{page}/qr-codes/{id}Rename, repoint (target_url) or restyle a QR code. The code itself never changes, so printed copies keep working.page:write
GET /api/v1/pages/{page}/short-linksThe page's short links, newest first, with their clicks and campaign tags. Free pages have 10; Pro and up as many as they like.page:read
POST /api/v1/pages/{page}/short-linksMake a short link to any address, with your own ending or a random one, and optional UTM tags.page:write
PATCH /api/v1/pages/{page}/short-links/{id}Repoint a short link, change its note or its UTM tags. The address stays the same.page:write
DELETE /api/v1/pages/{page}/short-links/{id}Delete a short link. Anyone who taps it afterwards sees a not found page.page:write
GET /api/v1/pages/{page}/subscribersThe page's email subscribers, newest first.audience:read
GET /api/v1/pages/{page}/formsThe page's forms and gates, with their fields and how many replies each has.audience:read
GET /api/v1/pages/{page}/forms/{id}/responsesOne form's replies, newest first.audience:read
GET /api/v1/pages/{page}/messagesMessages sent from the page's message box, newest first.audience:read
GET /api/v1/pages/{page}/productsWhat the page sells: downloads, tips, tickets, paid bookings and paid links, with prices (in the smallest unit, like cents), tickets sold and whether each is on the page.page:read
GET /api/v1/pages/{page}/ordersPaid, refunded and abandoned orders, newest first, with the buyer, the amount and OneLink's 5% fee. Refunds are made in the dashboard.audience:read
POST /api/v1/pages/{page}/broadcastsDraft an email to the page's subscribers (Pro): a subject, Markdown before and after, link tiles and a button. It's sent from the dashboard, after a look over.page:write
POST /api/v1/pages/{page}/broadcasts/{id}/testSend a draft to your own email address, marked as a test.page:write
GET /api/v1/pages/{page}/peopleEveryone who got in touch through the page (signed up, wrote, RSVPd, filled in a form, passed a gate, bought or booked), seen most recently first, with their tags and notes. Filter by tag or segment.audience:read
PATCH /api/v1/pages/{page}/peopleSet one person's tags (the whole list) and/or notes (Pro). Tags are copied to Mailchimp, and to the CRM on Enterprise, where connected.page:write
GET /api/v1/pages/{page}/segmentsSaved segments of the audience list, each with its filter in words and how many subscribers an email to it would reach.audience:read
POST /api/v1/pages/{page}/segmentsSave a segment (Pro): a filter by tag, how people got in touch, when they first did, whether they wrote and whether they bought. Send an email to it with create_broadcast_draft's segment_id.page:write
DELETE /api/v1/pages/{page}/segments/{id}Delete a segment. Nobody is removed from the list.page:write
GET /api/v1/pages/{page}/testsRunning A/B tests on tiles: each version's title and link, how many visitors saw it, taps and tap rate since the test started.insights:read
POST /api/v1/pages/{page}/tiles/{id}/variantTry a second version of a link tile (Pro): half the visitors see this title and/or link. Sending it again changes version B and starts the count again.page:write
DELETE /api/v1/pages/{page}/tiles/{id}/variantEnd a tile's test: keep=a leaves the tile as it is, keep=b makes version B the tile's own.page:write
GET /api/v1/pages/{page}/link-alertsWhat the daily link check found broken: link tiles whose page doesn't load (with the status the site answered) and feeds that stopped working.page:read
GET /api/v1/pages/{page}/assistAI helpers on this page: whether the server has them switched on, whether the plan includes them (Pro), calls used today out of 60, and whether the summary email starts with an AI paragraph.page:read
POST /api/v1/pages/{page}/assistAsk an AI helper (Pro, owners, admins and editors, 60 calls a page a day): kind bio (three intro options), tiles (tiles from a newsletter issue or article, by text or url), pin (the tile to pin this week, with a reason), caption (a caption made shorter, clearer or a question) or translate (strings into another language). Only the page's own content and added-up numbers are sent; nothing on the page changes.page:write
PATCH /api/v1/pages/{page}/assistTurn the AI paragraph at the top of the summary email on or off. On needs Pro, and it's written only when the server has AI switched on.page:write
GET /api/v1/pages/{page}/translationsThe page's translated copies (Pro): each language's name, intro, captions by tile id and section names, whether it's live at onelinkin.bio/handle/lang, and the page's own words to translate.page:read
PATCH /api/v1/pages/{page}/translations/{lang}Add a language or change one (Pro; owners, admins and editors). Send only what changes; captions and sections replace their whole list. Empty words show the page's own. live: true shows it with a language switcher and hreflang links.page:write
DELETE /api/v1/pages/{page}/translations/{lang}Remove a language. Its address then opens the page in its own language.page:write
POST /api/v1/pages/{page}/translations/{lang}/suggestTranslate for me (Pro, when AI is switched on): the page's name, intro, section names and captions in that language, from the AI helper. Nothing is saved; send what you want to keep to saveTranslation. Each 50 strings is one of the page's 60 AI calls a day.page:write
POST /api/v1/pages/{page}/copyMake a copy of the page (owners and admins): settings, design, tiles with their pictures and files, folders, sections, forms and gates, feeds, events and booking setup. Not subscribers, messages, orders, products, tile tests, alerts, short links or QR codes. The copy belongs to the page's owner and counts toward their plan's pages.page:write
GET /api/v1/pages/{page}/sign-in-linksThe page's sign-in links for collaborators (owners and admins): who made each, its note, whether it's open, used, turned off or expired, and who used it. Links are made in the dashboard only; the address is shown once there.page:read
DELETE /api/v1/pages/{page}/sign-in-links/{id}Turn off a sign-in link that hasn't been used (owners and admins).page:write
GET /api/v1/pages/{page}/domainThe page's own domain (Publisher and above): a root domain like yourpaper.com or a subdomain like links.yourpaper.com, whether it's live, and the DNS records to add. A root domain also gets www records; www visitors go on to the root domain. HTTPS is free and automatic. Set in the dashboard under Design.page:read
GET /api/v1/page-movesRequests you sent to bring in a page you own on another OneLink account: the page, the email it went to, and whether it's waiting, moved, cancelled, turned down or expired.page:read
POST /api/v1/page-movesAsk to bring in a page you own on another account (Publisher and above, with room for one more page). If that email owns the page, it gets a link that works once for 7 days; the move happens only when the owner presses Move the page there, signed in. The page keeps its address, tiles, subscribers and settings; the old account stays on its team. Pages that sell through Stripe, or the only page on a paid plan, can't move.page:write
DELETE /api/v1/page-moves/{id}Cancel a request to bring in a page that's still waiting.page:write
GET /api/v1/directoryPages listed in the OneLink directory, verified first, by kind of page (the fourteen on onelinkin.bio/for) or by name. Each has its address, name, intro, kind, verified check and a rough size, never exact numbers. Good for finding pages to recommend.page:read
GET /api/v1/pages/{page}/insightsViews, taps, tap rate, sign-ups, a daily series, top tiles and buttons, referrers and devices.insights:read
GET /api/v1/pages/{page}/healthThe page's health: a score out of 100 and what to fix (broken links, sample text, a missing photo or intro, untitled or repeated tiles and more), each with the dashboard address that fixes it. Checked at most once a day.page:read
GET /api/v1/pages/{page}/previewRedirects (302) to the page's preview image, the picture shown when it's shared.page:read
GET /api/v1/white-labelThe key owner's white-label settings (Enterprise): whether the OneLink name is off their pages, share cards, emails to visitors and the sign-in page on their own domain, and the sender name, support email and sign-in name. Changed in the dashboard under Pages & team.page:read
GET /api/v1/roadmapOneLink's public roadmap (shipped, building, planned; only shipped items carry a date) and changelog, newest first. No key needed.none
POST /api/mcpThe MCP server (streamable HTTP, JSON-RPC 2.0) for Claude, ChatGPT, Cursor and other assistants.any key

Scopes

  • page:read: See your pages.
  • page:write: Change your pages.
  • audience:read: See your subscribers, messages and form replies.
  • insights:read: See your insights.

A key acts as you, on every page you're on, within your role: viewers and contributors can read but not change a page, and only owners, admins and editors see subscribers, messages and form replies. A page's plan still applies, so scheduling a tile on a Free page answers plan_required.

Errors

Every error has the same shape:

{ "error": { "code": "not_found", "message": "That tile isn't on this page." } }
validation_error400Something in the request isn't right. details lists each problem.
unauthorized401No key, a key we don't know, or one that was revoked or expired.
plan_required402The page's plan doesn't include this, like scheduling on Free.
forbidden403The key lacks the scope, or your role on the page doesn't allow it.
not_found404No such page, tile or form among yours.
conflict409The change clashes with the page as it is now.
rate_limited429Too many requests. Wait for Retry-After seconds.
server_error500Our side failed. Try again in a moment.

Rate limits

120 requests a minute per key, 30 of them changes. Every answer carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset; a 429 also carries Retry-After.

Versions

v1 is current. Changes within v1 are additive: new fields and new endpoints, never a removed or renamed one. We give 180 days notice before retiring anything.

For machines

Questions or a bug? Email support@onelinkin.bio.

Create your pageSee a live pageFree to start. Nothing to install.