Skip to content

Concepts

Page content

Page codes host a mobile page at their short link. The content object on create and update sets what the page shows. Two fields work on every type: title (string, max 120) and accent (hex color like #7c3aed, the page's highlight color).

How normalization works#

The API normalizes content instead of rejecting it: unknown fields are dropped, over-length strings are truncated, URL fields accept http(s) only and store empty otherwise, and dates outside YYYY-MM-DD store empty. The request still succeeds, so open the hosted page (or GET the code) after your first integration test and check the result.

A link-in-bio page.

taglinethe bio; string, max 240, line breaks kept
linksarray of { label (max 80), url }, max 50; rows missing either are dropped. url may be a web address, an email address (stored as mailto:) or tel:+number. Each web address must pass the safety check, else 422 unsafe_destination
links[].kind"heading" makes the entry a label between groups of links (no url)
links[].emoji / hidden / featuredone emoji shown on the button; boolean to keep it off the page; boolean to make it stand out
socialsobject of profile links shown as icons: instagram, tiktok, youtube, facebook, x, linkedin, whatsapp, email, website. Handles (@name) and a WhatsApp number with country code are accepted
themelight (default), dark or color. Dark and color show on Starter and above
buttonStyle / buttonShapefill | outline | soft, and rounded | pill | square. Non-default values show on Starter and above
photo and bannerupload-only (dashboard); an edit through the API keeps them

A restaurant menu with sections and priced items.

taglinestring, max 160
themelight (default), dark or photo. Dark and photo show on Starter and above
currencystring, max 8, default $
sectionsarray of { name (max 80), desc (max 200), icon (one emoji), hidden (boolean), items }, max 20; unnamed sections are dropped
sections[].itemsarray of { name (max 80), price (max 20), desc (max 160) }, max 50 per section and 200 per menu
items[].variantsarray of { label (max 40), price (max 20) }, max 6; shown instead of price
items[].tagsany of: vegetarian, vegan, spicy, gluten-free, halal, new, popular
items[].soldOutboolean; the item stays on the page, greyed
languagesarray of language codes, first is the default (en, si, ta, hi, zh, ja, ko, fr, de, es, it, pt, ru). One language shows below Pro, three on Pro, all on Business
i18ntranslations for the other languages: { si: { title, tagline, hours, note } }. Sections and items take the same shape with { name, desc }. Anything missing falls back to the default language
hours / notestring, max 400 / 300; line breaks are kept
phone / email / addressstring, max 40 / 120 / 200
website / googleReviewUrl / tripadvisorUrlURL; a bare domain is accepted and stored as https://…
instagram / facebook / tiktokURL or @handle
whatsappwa.me URL, or a number with + and country code
whatsappOrdersboolean; scanners can build an order on the page and send it to the whatsapp number. Needs whatsapp to be a number
photos, cover and logoupload-only (dashboard). Editing a menu keeps them: each section and item keeps the photos of the entry with the same name, or the same position if it was renamed. Everything else is replaced by what you send: omit tags or translations and they are cleared

vcard#

A digital business card (vCard Plus) with a Save contact button that downloads a .vcf.

firstName / lastNamestring, max 60 each
pronounsstring, max 30; shown next to the name, not saved with the contact
jobTitle / orgstring, max 80 each
biostring, max 500, line breaks kept
phonesarray of { type: mobile | work | home | other, number }, max 4. Every number must start with + and the country code (e.g. +15550001234), else 422 invalid_phone
emailsarray of { type: work | personal | other, address }, max 3; invalid addresses are dropped
websiteURL; a bare domain is accepted. Must pass the safety check, else 422 unsafe_destination
addressstring, max 300, line breaks kept; shown with a Directions link
socialsobject of profile links: linkedin, instagram, x, facebook, tiktok, youtube, whatsapp. Handles (@name) are accepted
themelight (default) or dark
phone / email / notethe older single-field shape; still accepted (note becomes bio)
photo and bannerupload-only (dashboard); an edit through the API keeps them. The photo is embedded in the downloaded .vcf

video#

A page of YouTube or Vimeo videos.

taglinethe line under the name; string, max 300, line breaks kept
videosarray of { url, title (max 120), desc (max 600), hidden (boolean) }, max 12. url must be a YouTube or Vimeo video link (Shorts and unlisted videos work), else 422 invalid_video. The first is shown large. title is optional: the video's own title and channel are looked up from YouTube or Vimeo when you save
buttonsarray of { label (max 60), url }, max 3; rows missing either are dropped. url may be a web address, an email address or tel:+number, and must pass the safety check, else 422 unsafe_destination
socialsobject of profile links shown as icons, as for links
themelight (default) or dark
videoUrl / descriptionthe older one-video shape; still accepted and stored as a page with that one video
logoupload-only (dashboard); an edit through the API keeps it

coupon#

A coupon: the offer, a code with Copy, an optional barcode or QR code for the till, and the dates it is valid.

discount / title / businessstring, max 120 / 120 / 100; discount is the headline (20% off)
description / termsstring, max 1000 / 2000, line breaks kept
codestring, max 40
barcodenone (default), code128 or qr. code128 holds printable ASCII only, else 422 invalid_coupon
validFrom / validUntilYYYY-MM-DD, inclusive whole days; anything else is 422 invalid_coupon
timezoneIANA zone the days start and end in, e.g. Europe/London
addressstring, max 300; shown with Directions
buttonsarray of { label (max 40), url }, max 2; hidden once the offer has ended. Must pass the safety check
socials / themeprofile links as for links; light (default) or dark
ctaUrl / ctaLabelthe older one-button shape; still accepted
logo and bannerupload-only (dashboard); an edit through the API keeps them

apps#

An app download page. Visitors see their own store first; phones can be sent straight to it.

title / developer / taglinestring, max 80 / 80 / 120
descriptionstring, max 1500, line breaks kept
storesobject of store links: ios (apps.apple.com), testflight (testflight.apple.com/join/…, a beta invite), android (play.google.com), huawei (appgallery.huawei.com), amazon (amazon.*), microsoft (apps.microsoft.com). A link to the wrong store is 422 invalid_store_link
websiteURL of a web version or the app's site
autoRedirectboolean; an iPhone scan opens the App Store and an Android scan Google Play, without the page
featuresarray of strings, max 6, max 100 each
socialsprofile links, as for links
themelight (default) or dark
iosUrl / androidUrl / fallbackUrlthe older shape; still accepted
icon and screenshotsupload-only (dashboard); an edit through the API keeps them

event#

An event page with a countdown, Add to calendar, venue and online link, buttons, schedule and speakers.

taglinestring, max 160
descriptionstring, max 2000, line breaks kept
startDate / endDateYYYY-MM-DD; endDate only for an event over several days. Anything else is 422 invalid_event
startTime / endTime24-hour HH:MM; omit startTime for an all-day event
timezoneIANA zone the times are in, e.g. Europe/London. Needed for the countdown and calendar entries to be right everywhere
modein_person (default), online or hybrid
venue / addressstring, max 120 / 300; the address keeps line breaks
onlineUrlURL for an online or hybrid event; must pass the safety check
buttonsarray of { label (max 40), url }, max 3; hidden once the event is over. Must pass the safety check, else 422 unsafe_destination
agendaarray of { date (multi-day events), time, title (max 100), desc (max 160) }, max 30
speakersarray of { name (max 80), role (max 100) }, max 12. Photos are upload-only; an edit keeps a speaker's photo by name
organizer / socialsstring, max 100; profile links as for links
themelight (default) or dark
date / time / ctaUrl / ctaLabelthe older shape; still accepted

business#

A business page: open-now status from weekly hours, quick actions, about, amenities, photos and buttons.

title / tagline / descriptionstring, max 120 / 160 / 2000
phone / email / website / addresscontact details; the address keeps line breaks and is shown with Directions
hoursModeweekly, always (open 24/7) or none (default)
week7 arrays of { from, to } as HH:MM, Sunday first, up to 2 per day; an empty day is closed; to earlier than from runs past midnight. Anything else is 422 invalid_hours
timezoneIANA zone the hours are in, e.g. Europe/London; required with weekly hours
hoursNotestring, max 400, e.g. Closed on public holidays
amenitiesany of: wifi, parking, wheelchair, cards, delivery, takeaway, outdoor, pets, kids, aircon
buttonsarray of { label (max 40), url }, max 3. Must pass the safety check
socials / themeprofile links as for links (whatsapp becomes a quick action); light (default) or dark
hours / ctaUrl / ctaLabelthe older shape; still accepted (hours becomes hoursNote)
logo, banner and photosupload-only (dashboard); an edit through the API keeps them

feedback#

A feedback page: a rating (stars or faces), optional topics, a comment and an optional contact for a reply. Every visitor is then offered your public review links.

titlethe business's name
questionstring, max 200, default How was your experience?
ratingStylestars (default) or faces
aspectsarray of { label (max 40) }, max 5: topics rated on their own
commentPrompt / thanksMessagestring, max 160 / 300
askContactboolean; offer a field for an email or phone, for a reply
reviewsobject of review page links: google, tripadvisor, facebook, yelp, trustpilot. Shown to every visitor after sending. Must pass the safety check
buttonsarray of { label (max 40), url }, max 2, on the thank-you screen
notifyLowboolean; email the account owner about 1 and 2 star responses (at most 10 a day)
themelight (default) or dark
logoupload-only (dashboard); an edit through the API keeps it

social#

One page of profiles, in order. Each link must be on its network's own site.

aboutstring, max 300; line breaks kept
profilesarray of { network, url, label }, max 20. network: instagram, tiktok, youtube, facebook, x, linkedin, threads, pinterest, snapchat, whatsapp, telegram, spotify, twitch, discord, email or website. url: a link on that network, or a handle ("@name") where the network has them; a phone number with its country code for whatsapp; an address for email. label: optional, max 60, shown instead of the network's name. A link that is not on its network is 422 invalid_profile
theme / iconStylelight or dark / brand (each network's colours) or accent (the page's colour)
instagram / facebook / x / tiktok / youtube / linkedin / whatsapp / websitethe older shape, one field per network; still accepted and turned into profiles
avatarupload-only (dashboard); an edit through the API keeps it

A photo album with a full-screen viewer. Photos upload in the dashboard; an edit through the API keeps them.

descriptionstring, max 1000; line breaks kept
layoutgrid (default), feed (full width, one under another) or slides. Anything else is 422 invalid_layout
themelight (default) or dark. Anything else is 422 invalid_theme
downloadsboolean; show a Save button on each photo in the viewer. Not a boolean is 422 invalid_downloads
buttonsarray of { label (max 40), url }, max 2, under the photos. Must pass the safety check
imagesupload-only (dashboard). On an edit, send [{ id, caption }] to change captions (max 200) of photos already on the page; other fields are ignored

audio#

An MP3 page: cover art, a player and a track list. Tracks and the cover upload in the dashboard; an edit through the API keeps them.

artiststring, max 120; the artist, band or host shown under the title
descriptionstring, max 1000; line breaks kept
listenobject of streaming links: spotify, appleMusic, youtubeMusic, soundcloud, bandcamp, amazonMusic. Each must be on that service's own site. An unknown service or a link elsewhere is 422 invalid_listen_link
buttonsarray of { label (max 40), url }, max 3, under the player. Must pass the safety check
downloadsboolean; show a download button on each track. Default false
themelight (default) or dark. Anything else is 422 invalid_theme
tracks / coverFileIdupload-only (dashboard): MP3, M4A or WAV, up to 20 MB each, 20 per page

tag#

A lost-and-found page for a pet tag or an item label. The photo uploads in the dashboard; an edit through the API keeps it.

kindpet (default) or item. Anything else is 422 invalid_kind
name / ownerstrings, max 80 each: the pet's name or what the item is, and the owner's name as finders see it
message / lostNotestrings, max 400 each; line breaks kept. lostNote shows while lost is true
lostboolean; lost mode turns the page red and leads with lostNote. Not a boolean is 422 invalid_lost
phoneinternational format with the country code, e.g. +1 555 000 1234. Otherwise 422 invalid_phone
whatsappboolean, default true; offer WhatsApp on the same number
emailan email address. Otherwise 422 invalid_email
detailsarray of { label (max 40), value (max 200) }, max 6
photoFileIdupload-only (dashboard)