Developer guide
Changelog
Everything that has changed in this API, newest first. Check here before you ship — new capabilities show up in this list before you would notice them anywhere else.
Versioning
The version field of this document (currently 1.14.0) moves with the API
and follows semantic versioning:
| Bump | Means |
|---|---|
| MAJOR | A breaking change — a field or endpoint removed, a response shape changed, a previously optional field made required. |
| MINOR | A new endpoint, a new optional field, a new accepted value. Existing integrations keep working untouched. |
| PATCH | Documentation corrections and bug fixes with no contract change. |
Nothing is removed without warning. A field on its way out is first marked
deprecated in this reference and listed under Deprecated below, and it keeps
working for at least one MINOR cycle. Deprecated fields are still accepted, so
an integration that has not migrated yet will not start failing.
Two habits keep you safe against MINOR releases: ignore response fields you
do not recognise rather than validating strictly against a fixed shape, and
never assume a list field is a merge — several (geo_rules, Shield's
rules) replace the whole array.
2026-10-04 - 1.14.0
Added - stored integration reads and MCP guidance Eight GET routes under /api/v2/integrations expose connections, metrics, tracking links, account summaries, statements and fan health. Explicit integrations.read and current project/account rights apply. The Integrations and MCP sections explain common revenue readings, freshness, paging, scheduling limits and the read-only review workflow. This documents the implemented contract; deployment and account eligibility must be verified.
2026-08-06 — 1.13.0
Added — folders are fully manageable from the API
POST /api/v1/folders creates one, and GET, PATCH and DELETE /api/v1/folders/{folder_id} read, rename and delete it. Only the folder
listing existed before, so an integration could see folders but never make
one. Permissions: folders.create, folders.read, folders.edit,
folders.delete — these already existed on your API keys and finally have
endpoints behind them.
Added — file a link into a folder when you create or update it
PUT /api/v1/links and PATCH /api/v1/links/{link_id} accept folder_id
(single folder, null to clear) and folders (the full array — a link can
sit in several folders at once; sending it replaces the whole list). Links
created through the API no longer land outside every folder waiting to be
dragged into place by hand. Sending both spellings at once, or a folder id
from another project, is a 400. See the new Folders section above.
Added — the folders of a link are returned
link.folders (an array of folder ids) is now on GET /api/v1/links,
GET /api/v1/links/{link_id}, and echoed by both write verbs. It is always
present — [] for a link outside every folder — and is exactly the shape you
send back on a PATCH. GET /api/v1/links/{link_id} additionally returns a
sibling folders array with the names resolved.
Added — ?folder_id= on the link list
GET /api/v1/links?folder_id=... returns only the links inside one folder.
2026-08-03 — 1.12.0
Added — Media previews on every asset
GET /api/v1/assets and GET /api/v1/assets/{file_id} now return
thumbnail_url (320px), preview_url (1024px), media_kind
(image/video/audio/document) and is_image. Render a gallery
straight from those URLs instead of hand-building CDN transformations. The
two preview URLs are null for anything that is not an image — video and
PDF have no server-rendered still frame, so branch on media_kind.
Added — sort on the asset list
?sort=newest|oldest|largest|smallest|name (default newest). Anything else
is a 400.
Fixed — the asset list is finally paginable
total used to repeat the size of the page you just received; it now counts
every asset matching your filters. limit, offset, the new count (this
page) and has_more come back with it. If you were treating total as
"assets on this page", switch to count.
Fixed — file_id is back in the list, and reaches every file
The list endpoint never returned file_id, so there was no way to go from a
listing to GET /api/v1/assets/{file_id}. It is returned again — and both
endpoints now resolve dashboard-uploaded files too (their UUID is stored
under provider_file_id), which previously 404'd on the detail route.
Fixed — ?file_type= no longer hides files with a generic MIME type
Files stored as application/octet-stream are now matched on their filename
extension as well, so ?file_type=video returns the whole set.
Changed — user_id removed from the asset detail response
An internal identifier that the list endpoint never exposed. No other field
changed.
2026-08-03 — 1.11.1
Documentation — what an API-created link inherits
A new section, Links created through the API, answers the question directly:
a link created with PUT /api/v1/links is the same object as one created in
the dashboard, with the same landing-page, Shield, template, Geo Filter and
Privacy capabilities, and it stays editable in the dashboard afterwards. The
one difference is ownership — an API key is a project credential, so the
link belongs to the project rather than to a team member. That matters only
for dashboard permissions on teams using per-member roles, and is spelled out
there. No API change.
2026-08-03 — 1.11.0
Fixed — GET /api/v1/trending-links now actually exists
This endpoint has been documented for a while but was never wired up: calling
it returned a 404 HTML page. It is live now, behind the
statistics.read_project permission, and returns exactly the payload
described below. The project is resolved from your API key — project_id is
optional, and sending another project's id is a 403 rather than a
cross-project read.
2026-08-03 — 1.10.0
Added — Link Privacy (privacy.links)
Make a link private from the API, the same switch as Privacy in the
dashboard: {"privacy": {"links": true}} on PUT /api/v1/links and
PATCH /api/v1/links/{id}. The destinations the link renders are then served
through a short redirect on your own domain (https://<your-domain>/go/<token>),
so the real URL never appears in the HTML a crawler reads. The call that flips
the switch provisions those redirects — there is nothing else to enable.
Send {"links": false} to go back to normal.
The flag is returned by every link read — GET /api/v1/links,
GET /api/v1/links/{id} and the PUT /api/v1/links response — always as
privacy: { links: <boolean> }, false on a link that was never made
private. See the Link Privacy section.
2026-08-02 — 1.9.0
Added — every template family is now selectable on a link
A link has four template slots, and until now only the landing one could be
set through the API. All four are now accepted on PUT /api/v1/links and
PATCH /api/v1/links/{id}, and returned together under templates by
GET /api/v1/links/{id}:
cs_template (landing), cs_1-step (first-step gate), cs_3dots_template
(direct 3-dots overlay) and cs_3dots_click_template (click 3-dots overlay).
Send null on any of them to detach. See Templates — the three families.
Added — ?kind= on the Templates endpoints
GET /api/v1/templates and GET /api/v1/templates/{template_id} take
kind=landing|first_step|three_dots, so the ids for the new slots are
discoverable. Defaults to landing, so existing calls are unchanged. Both
responses now echo the kind they served. GET /api/v1/templates also takes
?summary=true for a trimmed listing — recommended, since the default
response returns full template documents and a v2 template embeds a whole page.
Changed — template ids are checked against your project
A template id that does not belong to the authenticated project is now
rejected with 400 naming the field, on every slot. It was previously
accepted for cs_template, which let a link be pointed at another project's
template. If you send ids you did not get from GET /api/v1/templates, check
them before upgrading.
Fixed — PATCH /api/v1/links/{id} accepts cs_template
It previously silently ignored it; the only way to attach a landing template
to an existing link was PUT|PATCH /api/v1/links/{id}/dynamic-overrides,
which still works and remains the right call when you set the template and
its dynamic_informations / dynamic_links together.
Fixed — Templates response shapes documented correctly
GET /api/v1/templates returns { templates, kind, project } and
GET /api/v1/templates/{template_id} returns { template, kind, project }.
This reference previously described a { success, data } envelope neither of
them has ever returned. No API change — the documentation was wrong.
2026-08-01 — 1.8.0
Added — Geo Filters (geo_rules)
Per-visitor overrides on a link: block a country, redirect a region to a
localized destination, or serve a different landing page per browser language.
Settable on PUT /api/v1/links and PATCH /api/v1/links/{id}, returned in full
by GET /api/v1/links/{id}, and summarised as geo_rules_count on
GET /api/v1/links. See the Geo Filters section for the model and examples.
Added — Shield (/api/v1/links/{link_id}/shield)
Traffic filtering and cloaking as a first-class resource: read, replace (PUT),
patch, and disable (DELETE) a link's Shield configuration, plus
GET /api/v1/shield for the condition vocabulary, GET /api/v1/shield/presets
for the built-in presets, and GET /api/v1/shield/bots for the crawler
registry. See the Shield section.
Deprecated — geolocation_enabled, geolocation_redirects
These two fields on PATCH /api/v1/links/{id} were never read by the serve
layer: setting them did nothing, and links "configured" with them were not
geo-targeted at all. They are still accepted so existing callers do not break,
but they are now discarded rather than stored. Migrate to geo_rules — a
{ countries, url } entry becomes a rule with t: "d_l".
Fixed — link detail response documented correctly
GET /api/v1/links/{id} returns { link, project }. It was previously
documented as { success, data }, which never matched the actual response. The
endpoint itself is unchanged; only the reference was wrong.
2026-07-24
Added — Landing Pages (v2)
Read and write Page Builder v2 pages on links and templates
(/api/v1/links/{link_id}/landing, /api/v1/templates/{template_id}/landing),
with version history, per-link dynamic-overrides, and the
/api/v1/landing-engine contract and example endpoints.
2026-03-31
Added — Visit logs
GET /api/v1/logs, /api/v1/links/{link_id}/logs and
/api/v1/folders/{folder_id}/logs — cursor-paginated visit history with masked
IPs and each visit's clicks merged in. See the API Logs section.
2026-02-19
Added — Social networks & trending links
Connected-account analytics, post metrics and history under
/api/v1/social-networks, plus GET /api/v1/trending-links.
2025-10-25
Added — Folders
/api/v1/folders and folder-scoped statistics.
2025-10-17
Initial public API — links, templates, assets and statistics.
Browse API endpointsKeeping this list current (internal note). This changelog lives in the
info.descriptionofstatic/openapi.yamland nowhere else — there is no second copy to drift out of sync. When you change the API: add a dated entry at the top of the list under the right label (Added / Changed / Deprecated / Removed / Fixed), say what a consumer must do rather than what the code now does, and bumpinfo.versionplus the number quoted under Versioning above.