{"openapi":"3.1.0","info":{"title":"OnLynk Public API","version":"1.2.0","description":"Public API for OnLynk link-in-bio pages and smart links: manage pages, their content (links, cards, sections, socials), and smart links (including their conditional-redirect flow), and fetch analytics. Authenticate with the API key from your dashboard (API access section) via `Authorization: Bearer <key>`."},"externalDocs":{"description":"OnLynk API documentation","url":"https://docs.onlynk.me/api/"},"servers":[{"url":"https://onlynk.me"}],"security":[{"bearerAuth":[]}],"paths":{"/api/public/pages":{"get":{"operationId":"listPages","summary":"List pages accessible to the API key","description":"Returns personal pages and pages from organizations where the key's account has API access. The `personalPages`, `organizationPages` and `summary` keys are deprecated legacy aliases of `personal` / `organizations`.","responses":{"200":{"description":"Pages grouped by ownership","content":{"application/json":{"schema":{"type":"object","required":["personal","organizations"],"properties":{"personal":{"type":"array","items":{"$ref":"#/components/schemas/PageSummary"}},"organizations":{"type":"array","items":{"type":"object","required":["organization","pages"],"properties":{"organization":{"$ref":"#/components/schemas/Organization"},"pages":{"type":"array","items":{"$ref":"#/components/schemas/PageSummary"}}}}}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createPage","summary":"Create a page","description":"Creates a published page on the given slug, optionally with initial links and social links. The slug shares a single namespace with smart links; check `/api/public/slug-availability` first to avoid 409s. Pass `organizationId` to create the page inside an organization you have API access to. Cards and sections don't exist yet at creation; add them afterward via the sub-resource endpoints.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slug"],"properties":{"slug":{"type":"string","minLength":3,"maxLength":32,"pattern":"^[a-zA-Z0-9_.]+$","description":"Public handle. Letters, numbers, underscores and periods; cannot start or end with a period. Stored lowercased."},"title":{"type":"string","maxLength":128},"organizationId":{"type":["string","null"]},"links":{"type":"array","maxItems":50,"items":{"type":"object","required":["title","url"],"properties":{"title":{"type":"string","maxLength":128},"url":{"type":"string","format":"uri"},"order":{"type":"integer"},"icon":{"type":"string"},"iconUrl":{"type":"string","format":"uri"},"effect":{"type":"string"},"adult":{"type":"boolean"},"cloak":{"type":"boolean"}}}},"socials":{"type":"array","maxItems":50,"items":{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","description":"e.g. `INSTAGRAM`"},"url":{"type":"string","format":"uri"},"order":{"type":"integer"}}}}}}}}},"responses":{"201":{"description":"Page created","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PageSummary"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"organization":{"oneOf":[{"$ref":"#/components/schemas/Organization"},{"type":"null"}]},"links":{"type":"array","items":{"$ref":"#/components/schemas/Link"}}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Plan link limit reached (`plan_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slug unavailable (`slug_reserved` or `slug_taken`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed (`invalid_request`, includes `issues`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}":{"get":{"operationId":"getPage","summary":"Fetch a page's full detail","description":"Metadata, appearance settings, and content relations (links, cards, sections, socials) with their ids, which you need to call the sub-resource update/delete endpoints.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Full page detail","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PageDetail"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"links":{"type":"array","items":{"$ref":"#/components/schemas/Link"}},"cards":{"type":"array","items":{"$ref":"#/components/schemas/Card"}},"sections":{"type":"array","items":{"$ref":"#/components/schemas/Section"}},"socials":{"type":"array","items":{"$ref":"#/components/schemas/Social"}}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updatePage","summary":"Update a page's metadata and appearance","description":"Partial update of a page identified by its slug: metadata (title, note, published, description), appearance (colors, button style, font), and direct-link/chatbot/city/Meta Pixel settings. Some fields require specific plan features (direct links, advanced customization, Meta Pixel), the same gating as the dashboard. Content (links/cards/sections/socials) and slug renames have their own endpoints. Set a nullable field to `null` to clear it.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"title":{"type":["string","null"],"maxLength":128},"note":{"type":["string","null"],"maxLength":32,"description":"Private note shown only in the dashboard"},"published":{"type":"boolean"},"description":{"type":["string","null"],"maxLength":256},"picture":{"type":["string","null"],"format":"uri","description":"Profile picture URL. Upload bytes first via POST /pages/{slug}/images"},"banner":{"type":["string","null"],"format":"uri","description":"Banner image URL. Upload bytes first via POST /pages/{slug}/images"},"backgroundColor":{"type":["string","null"],"description":"Hex color"},"backgroundGradient":{"type":["string","null"]},"textColor":{"type":["string","null"],"description":"Hex color"},"buttonsColor":{"type":["string","null"],"description":"Hex color"},"buttonsTextColor":{"type":["string","null"],"description":"Hex color"},"cardBackgroundColor":{"type":["string","null"],"description":"Hex color"},"buttonShape":{"type":"string","enum":["PILL","ROUNDED","SQUARE"]},"buttonFill":{"type":"string","enum":["SOLID","OUTLINE","SOFT_SHADOW"]},"fontFamily":{"type":["string","null"]},"style":{"type":"string"},"directLink":{"type":["string","null"],"format":"uri","description":"Requires a plan with direct links"},"online":{"type":"boolean","description":"Requires advanced customization"},"city":{"type":"boolean","description":"Requires advanced customization"},"cityText":{"type":["string","null"],"description":"Requires advanced customization"},"responseDelay":{"type":["integer","null"],"description":"Requires advanced customization"},"promotion":{"type":["string","null"],"description":"Requires advanced customization"},"chatbotMessages":{"type":"array","items":{"type":"string"}},"chatbotLink":{"type":["string","null"],"format":"uri"},"metaPixelId":{"type":["string","null"],"description":"Requires a plan with Meta Pixel"},"metaPixelEnabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated page","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PageDetail"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed (`invalid_request`, includes `issues`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/images":{"post":{"operationId":"uploadPageImage","summary":"Upload an image, get back a hosted, optimized URL","description":"Generic image upload (multipart/form-data, a `file` field): auto-orients, resizes/crops and re-encodes the image (the server-side equivalent of the dashboard's client-side FilePond processing, since there's no browser in this flow), stores it on OnLynk's CDN, and returns its URL. Not attached to anything by itself; use the returned URL with `PATCH /pages/{slug}` (`picture`/`banner`) or the links/cards endpoints (`iconUrl`/`image`). Max 5MB, jpeg/png/webp/heic/heif.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"},"purpose":{"type":"string","enum":["picture","banner","card","icon","generic"],"description":"Target usage, picks the resize/crop profile. Defaults to `generic` (fit within 1600px, no crop)."}}}}}},"responses":{"201":{"description":"Uploaded","content":{"application/json":{"schema":{"type":"object","required":["url","width","height"],"properties":{"url":{"type":"string","format":"uri"},"width":{"type":"integer"},"height":{"type":"integer"}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Missing/oversized/unsupported file, or invalid purpose (`invalid_request`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/links":{"get":{"operationId":"listLinks","summary":"List a page's links","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Links in display order","content":{"application/json":{"schema":{"type":"object","required":["links"],"properties":{"links":{"type":"array","items":{"$ref":"#/components/schemas/Link"}}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addLink","summary":"Add a link to a page","description":"Appended at the end of the list unless `order` is given. Pass `sectionId` to group it under an existing section.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","url"],"properties":{"title":{"type":"string","maxLength":128},"url":{"type":"string","format":"uri"},"order":{"type":"integer"},"icon":{"type":"string"},"iconUrl":{"type":"string","format":"uri"},"effect":{"type":"string"},"adult":{"type":"boolean"},"cloak":{"type":"boolean","description":"Requires a plan with cloaking"},"sectionId":{"type":["string","null"]}}}}}},"responses":{"201":{"description":"Link created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed, invalid sectionId, or 50-link cap reached (`invalid_request` / `content_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/links/{linkId}":{"patch":{"operationId":"updateLink","summary":"Update a link","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"linkId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"title":{"type":"string","maxLength":128},"url":{"type":"string","format":"uri"},"order":{"type":"integer"},"icon":{"type":["string","null"]},"iconUrl":{"type":["string","null"],"format":"uri"},"effect":{"type":["string","null"]},"adult":{"type":"boolean"},"cloak":{"type":"boolean"},"sectionId":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Updated link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Link"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed or invalid sectionId (`invalid_request`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteLink","summary":"Delete a link","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"linkId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Link deleted"},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/cards":{"get":{"operationId":"listCards","summary":"List a page's image cards","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Cards in display order","content":{"application/json":{"schema":{"type":"object","required":["cards"],"properties":{"cards":{"type":"array","items":{"$ref":"#/components/schemas/Card"}}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addCard","summary":"Add an image card to a page","description":"Appended at the end of the list unless `order` is given. Pass `sectionId` to group it under an existing section.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","url"],"properties":{"title":{"type":"string","maxLength":128},"url":{"type":"string","format":"uri"},"image":{"type":"string","format":"uri"},"order":{"type":"integer"},"icon":{"type":"string"},"iconUrl":{"type":"string","format":"uri"},"adult":{"type":"boolean"},"cloak":{"type":"boolean","description":"Requires a plan with cloaking"},"sectionId":{"type":["string","null"]}}}}}},"responses":{"201":{"description":"Card created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Card"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed, invalid sectionId, or 50-card cap reached (`invalid_request` / `content_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/cards/{cardId}":{"patch":{"operationId":"updateCard","summary":"Update an image card","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"cardId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"title":{"type":"string","maxLength":128},"url":{"type":"string","format":"uri"},"image":{"type":["string","null"],"format":"uri"},"order":{"type":"integer"},"icon":{"type":["string","null"]},"iconUrl":{"type":["string","null"],"format":"uri"},"adult":{"type":"boolean"},"cloak":{"type":"boolean"},"sectionId":{"type":["string","null"]}}}}}},"responses":{"200":{"description":"Updated card","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Card"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or card not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed or invalid sectionId (`invalid_request`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteCard","summary":"Delete an image card","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"cardId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Card deleted"},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or card not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/sections":{"get":{"operationId":"listSections","summary":"List a page's content sections","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Sections in display order","content":{"application/json":{"schema":{"type":"object","required":["sections"],"properties":{"sections":{"type":"array","items":{"$ref":"#/components/schemas/Section"}}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addSection","summary":"Add a content section to a page","description":"A named category (e.g. \"My partners\") that links/cards can be grouped under via their `sectionId`.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string","minLength":1,"maxLength":64},"order":{"type":"integer"}}}}}},"responses":{"201":{"description":"Section created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Section"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed or 20-section cap reached (`invalid_request` / `content_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/sections/{sectionId}":{"patch":{"operationId":"updateSection","summary":"Rename or reorder a section","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"sectionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"title":{"type":"string","minLength":1,"maxLength":64},"order":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated section","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Section"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or section not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed (`invalid_request`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteSection","summary":"Delete a section","description":"Its links/cards are kept, ungrouped (sectionId set to null), not deleted.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"sectionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Section deleted"},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or section not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/socials":{"get":{"operationId":"listSocials","summary":"List a page's social links","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Social links in display order","content":{"application/json":{"schema":{"type":"object","required":["socials"],"properties":{"socials":{"type":"array","items":{"$ref":"#/components/schemas/Social"}}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"addSocial","summary":"Add a social link to a page","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","description":"e.g. `INSTAGRAM`"},"url":{"type":"string","format":"uri"},"order":{"type":"integer"}}}}}},"responses":{"201":{"description":"Social link created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Social"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed or 50-social cap reached (`invalid_request` / `content_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/pages/{slug}/socials/{socialId}":{"patch":{"operationId":"updateSocial","summary":"Update a social link","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"socialId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"type":{"type":"string"},"url":{"type":"string","format":"uri"},"order":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated social link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Social"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or social link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed (`invalid_request`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteSocial","summary":"Delete a social link","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"socialId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Social link deleted"},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page or social link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/stats/{slug}":{"get":{"operationId":"getPageStats","summary":"Fetch analytics for a page","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"startDate","in":"query","required":false,"description":"Start of the date range (inclusive, UTC). Defaults to 30 days ago.","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","required":false,"description":"End of the date range (inclusive, UTC). Defaults to today.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Aggregated analytics over the date range","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"totalViews":{"type":"integer"},"totalClicks":{"type":"integer"},"totalDirect":{"type":"integer"},"totalChatbotClicks":{"type":"integer"},"totalSafed":{"type":"integer"},"totalBlocked":{"type":"integer"},"topCountries":{"type":"array","items":{"type":"object","properties":{"country":{"type":"string"},"views":{"type":"integer"}}}},"topLinks":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"clicks":{"type":"integer"}}}},"topReferrers":{"type":"array","items":{"type":"object","properties":{"referrer":{"type":"string"},"views":{"type":"integer"}}}},"topDeviceTypes":{"type":"array","items":{"type":"object","properties":{"deviceType":{"type":"string"},"views":{"type":"integer"}}}},"dailyStats":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"views":{"type":"integer"},"clicks":{"type":"integer"}}}}}}}}},"400":{"description":"Invalid date range (`invalid_date_range`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Page not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/smart-links":{"get":{"operationId":"listSmartLinks","summary":"List smart links accessible to the API key","responses":{"200":{"description":"Smart links grouped by ownership","content":{"application/json":{"schema":{"type":"object","required":["personal","organizations"],"properties":{"personal":{"type":"array","items":{"$ref":"#/components/schemas/SmartLinkSummary"}},"organizations":{"type":"array","items":{"type":"object","required":["organization","smartLinks"],"properties":{"organization":{"$ref":"#/components/schemas/Organization"},"smartLinks":{"type":"array","items":{"$ref":"#/components/schemas/SmartLinkSummary"}}}}}}}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createSmartLink","summary":"Create a smart link","description":"Creates an enabled smart link on the given slug. The slug shares a single namespace with pages; check `/api/public/slug-availability` first to avoid 409s. Without a `flow`, every visit redirects to `fallbackUrl`; conditional flows are built in the dashboard's visual editor. Pass `organizationId` to create the link inside an organization you have API access to.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","slug","fallbackUrl"],"properties":{"title":{"type":"string","minLength":1,"maxLength":120},"slug":{"type":"string","minLength":3,"maxLength":32,"pattern":"^[a-zA-Z0-9_.]+$","description":"Public handle. Letters, numbers, underscores and periods; cannot start or end with a period. Stored lowercased."},"fallbackUrl":{"type":"string","format":"uri","description":"http(s) URL served when no flow matches (or none exists)"},"organizationId":{"type":["string","null"]},"flow":{"type":"object","description":"Optional serialized Smart Flow graph (advanced). Usually omitted; flows are built in the dashboard's visual editor."}}}}}},"responses":{"201":{"description":"Smart link created","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SmartLinkSummary"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"organization":{"oneOf":[{"$ref":"#/components/schemas/Organization"},{"type":"null"}]}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Plan link limit reached (`plan_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Slug unavailable (`slug_reserved` or `slug_taken`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed (`invalid_request`, includes `issues`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/smart-links/{slug}":{"get":{"operationId":"getSmartLink","summary":"Fetch a smart link's full detail","description":"Metadata, the full flow graph, and workspace placement (folder, custom domain).","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Full smart link detail","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SmartLinkDetail"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Smart link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateSmartLink","summary":"Update a smart link","description":"Partial update of a smart link identified by its slug. Use `enabled` to pause/resume the link. `flow` replaces the conditional-redirect graph entirely; pass `null` to clear it (the link then always resolves to `fallbackUrl`).","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"title":{"type":"string","minLength":1,"maxLength":120},"fallbackUrl":{"type":"string","format":"uri"},"note":{"type":["string","null"],"maxLength":32,"description":"Private note shown only in the dashboard"},"enabled":{"type":"boolean"},"flow":{"type":["object","null"],"description":"Serialized Smart Flow graph (advanced). Fetch the current one via GET first if you're modifying rather than replacing wholesale."}}}}}},"responses":{"200":{"description":"Updated smart link","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SmartLinkDetail"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Smart link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed (`invalid_request`, includes `issues`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/smart-links/{slug}/duplicate":{"post":{"operationId":"duplicateSmartLink","summary":"Duplicate a smart link","description":"Copies title, fallbackUrl and flow onto a new auto-generated slug (`{slug}_copie`, `{slug}_copie_2`, …). The duplicate starts disabled so it never serves before review, the same behavior as the dashboard's duplicate action.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Duplicate created","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SmartLinkDetail"},{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}]}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Plan link limit reached (`plan_limit_reached`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Smart link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Could not generate a unique slug for the duplicate (`internal_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/smart-links/{slug}/stats":{"get":{"operationId":"getSmartLinkStats","summary":"Fetch analytics for a smart link","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"startDate","in":"query","required":false,"description":"Start of the date range (inclusive, UTC). Defaults to 30 days ago.","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","required":false,"description":"End of the date range (inclusive, UTC). Defaults to today.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Cookieless visit analytics over the date range","content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"enabled":{"type":"boolean"},"total":{"type":"integer"},"uniqueVisitors":{"type":"integer"},"daysActive":{"type":"integer"},"growthVisits":{"type":["number","null"],"description":"Percent change vs the previous period of the same length"},"growthUnique":{"type":["number","null"]},"byDay":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"count":{"type":"integer"}}}},"byAction":{"$ref":"#/components/schemas/Breakdown"},"topDestinations":{"$ref":"#/components/schemas/Breakdown"},"byCountry":{"$ref":"#/components/schemas/Breakdown"},"byDevice":{"$ref":"#/components/schemas/Breakdown"},"byReferrer":{"$ref":"#/components/schemas/Breakdown"}}}}}},"400":{"description":"Invalid date range (`invalid_date_range`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"API key missing (`api_key_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Invalid API key (`invalid_api_key`) or insufficient access (`forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Smart link not found (`not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/slug-availability":{"get":{"operationId":"checkSlugAvailability","summary":"Check whether a handle can be claimed","description":"Unauthenticated. Availability spans the shared namespace (pages and smart links). Availability is a soft signal until the page or smart link is actually created.","security":[],"parameters":[{"name":"slug","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Availability result","content":{"application/json":{"schema":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"},"reason":{"type":"string","enum":["invalid","reserved","taken"],"description":"Present only when `available` is false"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key generated in the dashboard (API access section)."}},"schemas":{"Error":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable message"},"code":{"type":"string","description":"Stable machine-readable error code","enum":["api_key_required","invalid_api_key","forbidden","not_found","invalid_request","invalid_date_range","slug_reserved","slug_taken","plan_limit_reached","content_limit_reached","internal_error"]}}},"PageSummary":{"type":"object","required":["id","slug","published","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":["string","null"]},"published":{"type":"boolean"},"note":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PageDetail":{"type":"object","required":["id","slug","published","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":["string","null"]},"description":{"type":["string","null"],"maxLength":256},"published":{"type":"boolean"},"note":{"type":["string","null"]},"picture":{"type":["string","null"],"format":"uri"},"banner":{"type":["string","null"],"format":"uri"},"backgroundColor":{"type":["string","null"],"description":"Hex color"},"backgroundGradient":{"type":["string","null"]},"textColor":{"type":["string","null"],"description":"Hex color"},"buttonsColor":{"type":["string","null"],"description":"Hex color"},"buttonsTextColor":{"type":["string","null"],"description":"Hex color"},"cardBackgroundColor":{"type":["string","null"],"description":"Hex color"},"buttonShape":{"type":"string","enum":["PILL","ROUNDED","SQUARE"]},"buttonFill":{"type":"string","enum":["SOLID","OUTLINE","SOFT_SHADOW"]},"fontFamily":{"type":["string","null"]},"style":{"type":"string"},"directLink":{"type":["string","null"],"format":"uri","description":"Skip the landing page and redirect straight to this URL (requires a plan with direct links)"},"online":{"type":"boolean"},"city":{"type":"boolean"},"cityText":{"type":["string","null"]},"responseDelay":{"type":["integer","null"]},"promotion":{"type":["string","null"]},"chatbotMessages":{"type":"array","items":{"type":"string"}},"chatbotLink":{"type":["string","null"],"format":"uri"},"metaPixelId":{"type":["string","null"]},"metaPixelEnabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Link":{"type":"object","required":["id","title","url","order","adult","sectionId"],"properties":{"id":{"type":"string"},"title":{"type":"string","maxLength":128},"url":{"type":"string","format":"uri"},"order":{"type":"integer"},"icon":{"type":["string","null"],"description":"Built-in brand icon, e.g. `INSTAGRAM`"},"iconUrl":{"type":["string","null"],"format":"uri"},"effect":{"type":["string","null"],"description":"Attention-grabbing animation, e.g. `PULSE`"},"adult":{"type":"boolean"},"sectionId":{"type":["string","null"],"description":"Section this link is grouped under, or null if ungrouped"},"cloak":{"type":["string","null"],"description":"Opaque redirect id when cloaking is enabled"},"cloakUrl":{"type":["string","null"],"format":"uri","description":"Ready-to-use `/go/{cloak}` URL, or null"}}},"Card":{"type":"object","required":["id","title","url","order","adult","sectionId"],"properties":{"id":{"type":"string"},"title":{"type":"string","maxLength":128},"image":{"type":["string","null"],"format":"uri"},"url":{"type":"string","format":"uri"},"order":{"type":"integer"},"icon":{"type":["string","null"]},"iconUrl":{"type":["string","null"],"format":"uri"},"adult":{"type":"boolean"},"sectionId":{"type":["string","null"]},"cloak":{"type":["string","null"]},"cloakUrl":{"type":["string","null"],"format":"uri"}}},"Section":{"type":"object","required":["id","title","order","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"title":{"type":"string","minLength":1,"maxLength":64},"order":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Social":{"type":"object","required":["id","type","url","order"],"properties":{"id":{"type":"string"},"type":{"type":"string","description":"e.g. `INSTAGRAM`, `TIKTOK`, `YOUTUBE`…"},"url":{"type":"string","format":"uri"},"order":{"type":"integer"}}},"SmartLinkSummary":{"type":"object","required":["id","slug","title","enabled","fallbackUrl","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"enabled":{"type":"boolean"},"fallbackUrl":{"type":"string","format":"uri"},"note":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SmartLinkDetail":{"type":"object","required":["id","slug","title","flowVersion","fallbackUrl","enabled","createdAt","updatedAt"],"properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"flow":{"type":["object","null"],"description":"Serialized Smart Flow graph (nodes + edges), or null if the link has none and always resolves to fallbackUrl."},"flowVersion":{"type":"integer"},"fallbackUrl":{"type":"string","format":"uri"},"note":{"type":["string","null"]},"enabled":{"type":"boolean"},"groupId":{"type":["string","null"],"description":"Dashboard folder this link belongs to, if any"},"domainId":{"type":["string","null"],"description":"Custom domain this link is attached to, if any"},"isCustomDomainHome":{"type":"boolean","description":"Whether this link is served at its custom domain's root"},"pageId":{"type":["string","null"],"description":"Page this link is attached to, if any"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Organization":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":"string"}}},"Breakdown":{"type":"array","items":{"type":"object","required":["key","count"],"properties":{"key":{"type":"string"},"count":{"type":"integer"}}}}}}}