Prospia Sites hosts landing pages, blog articles, news and simple pages for a Prospia organization, with the SEO work done by the platform: HTML rendered on the server, sitemap, robots.txt, llms.txt, RSS, JSON-LD structured data, share images and 301 redirects when an address changes.
org (id or exact name) to act on another organization the user belongs to.site (id or short name, see site_list); with a single site it can be left out.sites_terms_required with the link (acceptUrl). Only the person can accept.getting_started, then sites_guide for the topics you need (design, blocks, recipes).site_list, or site_create (slug 3 to 40 chars, name, locale pt-BR, en or es, kind organization or person).media_upload (https URL or base64), or media_upload_url (a one-time PUT link for curl) when the file is on a disk you reach with a shell. Start with the logo (SVG) when the brand has one.site_update (colors, design, menu, profiles, job title, per-language chrome). This saves a SETTINGS DRAFT; the live site does not change.landing_create_draft with the blocks (or content_generate_landing, which spends credits), page_create_draft, blog_create_draft, news_create_draft. All create DRAFTS.preview_link (one page draft; links to other pages open their drafts) and site_preview_link (the whole site with the draft settings). Show the links to the person.content_publish (or landing_publish...) for pages, site_settings_publish for the settings. The site is rebuilt at once.homeContentId in site_update.revision_list shows the history, revision_diff compares (default: live against latest draft), content_rollback puts an older revision back live.baseRevision (the revision you read) with every *_update. If someone saved after it, the update is refused with sites-revision_conflict instead of overwriting: read the page again, merge, save.*_update takes only the fields you change, except blocks, which is always the complete list in order.site_settings_diff (draft against live, field by field), site_settings_revisions, site_settings_discard, site_settings_rollback.site_look_status says a newer look is available, show site_look_preview and call site_look_apply only after the person agrees (the next publication also moves the site to the newer look).site_delete removes a site for good: pages, images, published versions and custom domains; its .sites.prospia.ai address becomes free. Leads already received stay in Prospia. Owner or admin only.site_export_link first (a .zip with settings, pages and original images). Then call site_delete without confirmName to get the summary, show it, and call it again with confirmName set to the exact site name the person typed. Never fill the name in yourself.hostnames).body). The page title is the only H1, so sections start at ##.faq list, becomes FAQ structured data. News take sourceName and sourceUrl.description (meta description) is required to publish. Covers: coverMediaId + coverAlt.The tools validate with strict schemas: an unknown argument, an unknown block field, a value over its limit, a missing required field or an invalid link is refused with the field path, and nothing is saved. Read the message, fix that field, send again. A tool that answers "missing scope" was added after the connection was made: the person accepts the new permission in Prospia (Settings > Connected apps).
The design of a site is a set of closed options (no free CSS): every site stays fast, accessible and consistent. All of them go through site_update (or site_create), land in the settings draft and go live with site_settings_publish. Check them with site_preview_link, not with the page preview_link.
primaryColor, accentColor, backgroundColor, textColor: hex (#rgb or #rrggbb). Background defaults to white, text to near black.surfaceColor, mutedTextColor, borderColor (cards and panels, secondary text such as dates, captions and the footer, card and section lines). Empty derives them from the main colors, so a site renders as before. Use surfaceColor for white cards on a tinted page (backgroundColor: "#f5f6f8", surfaceColor: "#ffffff"); keep mutedTextColor at 4.5:1 against both backgrounds.font (system, serif, humanist, rounded) picks a font stack already on the device. fontPairing below replaces it when set to anything but system.Heading and text fonts, served by the site itself (no third-party font service):
system: the visitor device font, nothing to download (fastest). Neutral; good for tools, local businesses and any site where speed matters most.classic-serif: a classic serif for headings over the system font for text. Personal sites, consultancies, law and finance: serious without being heavy.editorial: Fraunces headings with Inter text. Magazines, studios, portfolios, blogs with personality.modern: Inter for everything. SaaS, tech products, startups.book: Literata, made for long reading. Blogs, essays, documentation-like sites.light: light pages (default).dark: dark pages for everyone.auto: follows the light or dark setting of the visitor device, without JavaScript. The best default for personal sites and blogs.darkPrimaryColor, darkAccentColor, darkBackgroundColor, darkTextColor, darkSurfaceColor, darkMutedTextColor, darkBorderColor. Leave them empty and the platform derives them from the light colors with accessible contrast. Set them when the brand needs exact dark colors; values you set are used as given, so check the contrast yourself (light text on a dark background, accent still readable).themeToggle: true adds a light/dark button to the header; the visitor browser remembers the choice. Use it with auto or dark.logoMediaId. Use the horizontal version (mark plus wordmark), not a square icon. logoDarkMediaId is the same logo in light colors for dark pages (colorScheme dark, auto on a dark device, or the theme toggle set to dark); it only shows when logoMediaId is set. An empty id removes either one.headerMark picks how the header shows the brand:"monogram": the logo, or without a logo the initials in a circle of the accent color. monogram sets the letters (1 to 3 letters or digits; default: initials of the site name)."logo": ONLY the logo image (its alt text is the site name), plus logoLabel when set: a short word next to the logo such as "Learn" or "Blog" (up to 24 characters; empty removes it). Use it when the logo already carries the name, so the name is not shown twice. Without a logo it falls back to the site name.languageSwitcher (only shows on sites with translations):list: every language by name in the header (default; fine with two languages and a short menu).compact: the current language code (PT, EN) in a small button that opens the list; use it when the menu is long or there are three or more languages.navLinks: the header menu (up to 8 links of {label, url}), listed before the automatic Blog and News entries. Point items at sections with #anchorId (see the links topic).footerText: one or two plain sentences. The copyright line with the year and site name is added by the platform: never write it yourself.footerLinks: up to 20 links (privacy, terms, contact).poweredBy (site_create and site_update, boolean): true keeps the "Made with Prospia" line, false removes it. Only plans that allow it accept false (see planFlags in site_get); other plans get branding_locked. It is a settings draft field: publish it with site_settings_publish.footerBadges (up to 4): small linked logos, each {label?, mark} with a built-in mark, or {label?, mediaId, alt, url, darkMediaId?} with an image of the site. label (up to 40 chars) is the text before the logo ("Hosted on"); empty uses a default in the page language. Built-in marks:quave-one: the Quave ONE logo, links to quave.one ("Hosted on").prospia-sites: the Prospia Sites logo, links to prospia.ai ("Made with").locales.<lang>.footerBadges with translated labels. Check site_get planFlags before adding a Prospia badge: plans that keep the "Made with Prospia" line would show the brand twice.locales: {"en": {navLinks, footerText, footerLinks, jobTitle, footerBadges}}: pages in that language show this version; empty fields fall back to the default ones. Each language you send replaces that language; null removes it.kind: organization or person (structured data Organization or Person). jobTitle for a person. socialLinks (profiles, https or mailto:) show in the footer and in heroes with showSocialLinks; the https ones become sameAs.faviconMediaId (an SVG mark, served as /favicon.svg, or a square PNG 512x512; plans with a custom favicon), defaultOgMediaId (1200x630 share image for pages without their own; PNG, JPEG or WebP, never SVG).classic-serif or editorial, colorScheme: "auto", themeToggle: true, headerMark: "monogram".modern, light, a strong primary for the sign-up button, the SVG logo with headerMark: "logo".system (fast on any phone), light, brand colors from the logo.book or editorial, auto.Every design field: primaryColor, accentColor, backgroundColor, textColor, font, fontPairing, colorScheme, surfaceColor, mutedTextColor, borderColor, darkPrimaryColor, darkAccentColor, darkBackgroundColor, darkTextColor, darkSurfaceColor, darkMutedTextColor, darkBorderColor, themeToggle, headerMark, monogram, logoLabel, languageSwitcher, footerBadges.
A landing page is an ordered list of blocks. The set of block types is fixed on purpose: no free layout, no custom CSS, so every site stays fast, accessible and readable on phones.
The field lists below are generated from the same JSON Schema the tools validate with; limits are in characters.
anchorId (optional; text, up to 60 chars): Section id, so menus and buttons can link to it (#anchorId, or content:<id>#anchorId from another page). Lowercase words with hyphens, unique in the page.eyebrow (optional; text, up to 40 chars): Small uppercase label above the section title ("Products", "Series"). Keep it to one or two words.ctaLabel and ctaUrl go together. Use imageMediaId or avatarMediaId, never both. Every image needs its alt text (imageAlt, avatarAlt, alt).imageMediaId) is only allowed with style: "card".linkLabel needs linkUrl; an item has at most 3 links counting linkUrl and links.anchorId is unique in the page; main, faq-h, rel-h and anything starting with form- or ps- are reserved. A form section is already reachable at #form-<formId>.formId.body and in features/benefits intro; full markdown only in the text block. Other fields are plain text.blocks[3].items[0].linkUrl: invalid_url) and nothing is saved.The opening of the page: the one H1 of the page, a short promise and the main action. When to use: Always first, exactly once per landing. On a personal site it carries the name, the role line, a short bio, a round portrait and the profile buttons.
heading (required; text, up to 200 chars): The page H1: the main promise, or the person name on a personal site.subheading (optional; text, up to 300 chars): One sentence under the title. With body set, it reads as the role line (e.g. "Cofounder and DevOps engineer").ctaLabel (optional; text, up to 60 chars): Button text, a verb plus an object ("Get a quote"). Goes with ctaUrl.ctaUrl (optional; a link, see the links topic): Button target. Goes with ctaLabel.imageMediaId (optional; a mediaId from media_upload): A picture beside the text (product, screenshot, photo). Not together with avatarMediaId.imageAlt (optional; text, up to 200 chars): What the picture shows; required with imageMediaId.body (optional; text, up to 2000 chars): A short paragraph under the subheading; inline markdown: [text](link), bold.avatarMediaId (optional; a mediaId from media_upload): A round portrait beside the text (personal sites), instead of imageMediaId.avatarAlt (optional; text, up to 200 chars): Who is in the portrait ("Portrait of Ada Lovelace"); required with avatarMediaId.avatarSize (optional; one of medium, small): Portrait size.socialLinks (optional; list (up to 8)): Profile buttons with the brand icon of each URL (X, LinkedIn, GitHub, Instagram, YouTube, Mastodon, mailto: for e-mail, a globe otherwise).socialLinks[].label (required; text, 1 to 80 chars): Button text ("GitHub").socialLinks[].url (required; a link, see the links topic): Absolute https URL of the profile, or mailto:.showSocialLinks (optional; true or false): true shows the site profiles (socialLinks of the site settings) when the block has none of its own.What you offer, as a grid of items that can each link to a page (products, services, projects). When to use: For a catalog of products, services or projects; give each item its own link when it has a page.
heading (optional; text, up to 200 chars): Section title (an H2).intro (optional; text, up to 2000 chars): Introduction under the title; inline markdown: [text](link), bold, *italic*.items (required; list (1 to 30)): The cards of the grid.items[].title (required; text, up to 200 chars): Card title (product, service or project name).items[].text (optional; text, up to 2000 chars): One to three sentences about it.items[].linkUrl (optional; a link, see the links topic): Where the card links (its page, a demo, a repository).items[].linkLabel (optional; text, up to 60 chars): Link text; needs linkUrl; defaults to "Learn more" in the site language.items[].links (optional; list (up to 3)): More links after linkUrl ([{label, url}]), for example the source code.items[].links[].label (required; text, up to 60 chars): Link text.items[].links[].url (required; a link, see the links topic): Link target.What the visitor gains, as a grid of short items (outcomes, not features). When to use: Right after the hero on product and service pages: 3 or 4 items, each a concrete result.
heading (optional; text, up to 200 chars): Section title (an H2).intro (optional; text, up to 2000 chars): Introduction under the title; inline markdown: [text](link), bold, *italic*.items (required; list (1 to 30)): The cards of the grid.items[].title (required; text, up to 200 chars): The benefit, as an outcome ("Quote in one hour").items[].text (optional; text, up to 2000 chars): One or two sentences that prove or explain it.items[].linkUrl (optional; a link, see the links topic): Optional link for the card.items[].linkLabel (optional; text, up to 60 chars): Link text; needs linkUrl; defaults to "Learn more" in the site language.items[].links (optional; list (up to 3)): More links after linkUrl ([{label, url}]).items[].links[].label (required; text, up to 60 chars): Link text.items[].links[].url (required; a link, see the links topic): Link target.Questions and answers; published as FAQPage structured data. When to use: Near the end, with the 3 to 6 questions buyers really ask (price policy, area served, deadlines, how it works).
heading (optional; text, up to 200 chars): Section title (default "Frequently asked questions" in the site language).items (required; list (1 to 30)): The questions.items[].question (required; text, up to 300 chars): The question, as the buyer would ask it.items[].answer (required; text, up to 2000 chars): A direct answer, first sentence first.A call to action with one button: a full-width banner, or a card with an optional image. When to use: To close the page (banner) or to highlight one thing in the middle of it (card, for example a series, a launch or a guide).
heading (required; text, up to 200 chars): The call, short ("Ready to start?").text (optional; text, up to 2000 chars): One or two sentences of support.buttonLabel (required; text, up to 60 chars): Button text, a verb plus an object.buttonUrl (required; a link, see the links topic): Button target.style (optional; one of banner, card): banner: a band in the primary color (default); card: a soft card with an accent border.imageMediaId (optional; a mediaId from media_upload): Image beside the text; only with style card.imageAlt (optional; text, up to 200 chars): What the image shows; required with imageMediaId.imagePosition (optional; one of right, left): Side of the image in the card.buttonStyle (optional; one of primary, outline): primary: filled button (default); outline: bordered.Quotes from real customers, with name and role. When to use: Only with real quotes the person gave you, with permission. Never write or paraphrase testimonials.
heading (optional; text, up to 200 chars): Section title (an H2).items (required; list (1 to 30)): The quotes.items[].quote (required; text, up to 2000 chars): The words of the customer, verbatim.items[].author (required; text, up to 100 chars): Who said it.items[].role (optional; text, up to 100 chars): Role and company.Free text in markdown: an about section, a story, terms, a list. When to use: When the content is prose rather than a grid: "About", "How it works", a short manifesto.
heading (optional; text, up to 200 chars): Section title (an H2).markdown (required; text, up to 20000 chars): Markdown body: paragraphs, lists, ### subheadings, links (/path and content:<id> work).One image across the width of the page, with a caption. When to use: For a diagram, a product photo or a screenshot that explains more than text would.
mediaId (required; a mediaId from media_upload): The image (from media_upload).alt (required; text, up to 200 chars): What the image shows, for screen readers and search.caption (optional; text, up to 300 chars): Optional caption under the image.The newest LIVE posts of the site (blog articles, news or both) as the same cards as the /blog index: cover, title, summary and date, in the language of the landing. When to use: On a home or hub landing so it shows fresh content by itself: every publication rebuilds the site and updates the list. Without matching posts the section is left out, so it is safe before the first article.
heading (optional; text, up to 200 chars): Section title (an H2).kind (optional; one of article, news, all): article (blog, default), news, or all (both, newest first).count (optional; number): How many posts to show (default 3).tag (optional; text, up to 100 chars): Only posts with this tag (matched by slug, ignoring case and accents). Use a tag the site posts already have; never invent one.category (optional; text, up to 100 chars): Only posts of this category (matched by slug). Use an existing category.showAllLink (optional; true or false): Adds a "See all" link to /blog or /news.A lead form (name, e-mail and consent always; optional and custom fields); the leads arrive in Prospia. When to use: On lead capture and service pages, when the plan includes forms. Point buttons at it with #form-<formId>.
formId (required; text): Form id on the site (a-z, 0-9, hyphen; unique). The section gets the anchor form-<formId>.purpose (required; text, up to 300 chars): What the data is for, one sentence shown above the consent box.heading (optional; text, up to 200 chars): Section title (an H2).intro (optional; text, up to 2000 chars): Introduction under the title.fields (optional; list of phone, company, cnpj, role, message, city): Optional built-in fields to show (name, e-mail and consent are always there).required (optional; list of phone, company, cnpj, role, message, city): Which of the optional fields are required.customFields (optional; list (up to 8)): Extra fields (sensitive data is refused).customFields[].key (required; text, up to 40 chars): Field key (a-z, 0-9, underscore).customFields[].label (required; text, up to 120 chars): Field label.customFields[].kind (required; one of text, textarea, select, checkbox): Field kind.customFields[].required (optional; true or false): Whether it must be filled.customFields[].options (optional; list (up to 20) of texts): Choices of a select field.submitLabel (optional; text, up to 60 chars): Button text ("Send", "Request a quote").successMessage (optional; text, up to 2000 chars): Message shown after sending.privacyUrl (optional; a link, see the links topic): Privacy policy of the data controller; without it give controllerName and controllerEmail.termsUrl (optional; a link, see the links topic): Terms of use, if any.controllerName (optional; text, up to 120 chars): Who controls the data (without privacyUrl).controllerDocument (optional; text, up to 20 chars): Company registration number of the controller (CNPJ in Brazil).controllerEmail (optional; text, up to 254 chars): Contact e-mail of the controller (without privacyUrl).Starting points for the sites people ask for most. Adapt the copy to the real business: every name, number and URL below is an example. Values in <angle brackets> are placeholders for ids you get from media_upload, and content:<uuid> links stand for the id of one of your pages (from the *_list tools).
Always: hero first, one main action, the anchors the menu needs, alt text on every image, the person sees the preview before anything is published.
personal)Use when: A person presenting their work: consultant, engineer, designer, writer. Site kind "person" so the structured data is a Person with jobTitle and sameAs.
Order and why:
Site settings (site_update):
{"kind":"person","jobTitle":"Cofounder and DevOps engineer","fontPairing":"classic-serif","colorScheme":"auto","themeToggle":true,"headerMark":"monogram","monogram":"AL","languageSwitcher":"compact","navLinks":[{"label":"Products","url":"#products"},{"label":"About","url":"#about"}],"socialLinks":[{"label":"GitHub","url":"https://github.com/example"},{"label":"LinkedIn","url":"https://www.linkedin.com/in/example"}]}
Example blocks (landing_create_draft or landing_update blocks):
[
{"type":"hero","heading":"Ada Lovelace","subheading":"Cofounder and DevOps engineer","body":"I build infrastructure that small teams can run alone. Today I work on [Example Cloud](https://example.com).","avatarMediaId":"<portrait mediaId>","avatarAlt":"Portrait of Ada Lovelace","showSocialLinks":true},
{"type":"cta","eyebrow":"Series","heading":"Infrastructure with AI, step by step","text":"How I run deploys, alerts and reviews with an AI agent, and what went wrong.","buttonLabel":"Read the series","buttonUrl":"content:3f2b8c1e-0a4d-4e6b-9c7a-5d1e2f3a4b5c","style":"card","imageMediaId":"<diagram mediaId>","imageAlt":"Diagram of the five-step cycle","imagePosition":"right"},
{"type":"features","anchorId":"products","eyebrow":"Products","heading":"What I work on","items":[{"title":"Example Cloud","text":"Hosting for Node and Go apps, with backups and alerts included.","linkUrl":"https://example.com","linkLabel":"Visit Example Cloud"},{"title":"tui-tools","text":"Small terminal tools for daily server work.","linkUrl":"https://example.org/tui-tools","links":[{"label":"Source code","url":"https://github.com/example/tui-tools"}]}]},
{"type":"text","anchorId":"about","eyebrow":"About","heading":"Since 2005","markdown":"I started as a Linux admin and moved to platform work in 2014.\n\nI write about what I build in the [series](/infra-with-ai)."}
]
saas)Use when: A software product with a sign-up or trial. One clear action repeated at the top and at the end.
Order and why:
Site settings (site_update):
{"kind":"organization","fontPairing":"modern","colorScheme":"light","navLinks":[{"label":"Features","url":"#features"},{"label":"FAQ","url":"#faq"}]}
Example blocks (landing_create_draft or landing_update blocks):
[
{"type":"hero","heading":"Close the month in one afternoon","subheading":"Bookkeeping software for small agencies, with bank sync and invoices in one place.","ctaLabel":"Start free trial","ctaUrl":"https://app.example.com/signup","imageMediaId":"<screenshot mediaId>","imageAlt":"Monthly closing screen with the bank reconciliation done"},
{"type":"benefits","heading":"Why teams switch","items":[{"title":"Bank sync every hour","text":"Transactions arrive matched to invoices."},{"title":"Invoices in two clicks","text":"From a project, with your taxes already set."},{"title":"One report for the accountant","text":"Export the month as a single file."}]},
{"type":"features","anchorId":"features","heading":"Features","items":[{"title":"Reconciliation","text":"Suggested matches you confirm or fix.","linkUrl":"/reconciliation"},{"title":"Invoices","text":"Recurring and one-off, sent by e-mail."},{"title":"Reports","text":"Cash flow and profit by project."}]},
{"type":"faq","anchorId":"faq","items":[{"question":"How long is the trial?","answer":"Fourteen days, no card needed."},{"question":"Which banks are supported?","answer":"The list is on the integrations page and grows every month."}]},
{"type":"cta","heading":"Try it with your own numbers","buttonLabel":"Start free trial","buttonUrl":"https://app.example.com/signup"}
]
local-service)Use when: A clinic, workshop, office or contractor that serves one area. Visitors want to know what you do, where, and how to reach you now.
Order and why:
Site settings (site_update):
{"kind":"organization","fontPairing":"system","colorScheme":"light","navLinks":[{"label":"Services","url":"#services"},{"label":"Contact","url":"#form-quote"}]}
Example blocks (landing_create_draft or landing_update blocks):
[
{"type":"hero","heading":"Air conditioning repair in Campinas","subheading":"Same-week visits for homes and offices.","ctaLabel":"Call (19) 3000-0000","ctaUrl":"tel:+551930000000","imageMediaId":"<team photo mediaId>","imageAlt":"Technician cleaning a split air conditioner"},
{"type":"features","anchorId":"services","heading":"Services","items":[{"title":"Installation","text":"Split and window units, with the electrical check."},{"title":"Cleaning and maintenance","text":"Filters, coils and drain, with a checklist report."},{"title":"Repair","text":"Diagnosis on the first visit."}]},
{"type":"faq","items":[{"question":"Which neighborhoods do you serve?","answer":"All of Campinas and Valinhos."},{"question":"How does a quote work?","answer":"Send the model and the problem; we answer the same day."}]},
{"type":"form","formId":"quote","purpose":"We use your contact only to answer this quote request.","heading":"Request a quote","fields":["phone","message"],"required":["phone"],"submitLabel":"Send request","controllerName":"Example Air Ltda","controllerEmail":"privacy@example.com"}
]
lead-capture)Use when: A campaign page (ads, e-mail, a QR code) with one goal: get the visitor to fill a form. No menu detours, one offer.
Order and why:
Site settings (site_update):
{"colorScheme":"light","fontPairing":"modern"}
Example blocks (landing_create_draft or landing_update blocks):
[
{"type":"hero","heading":"Free energy audit for small factories","subheading":"A two-hour visit and a written report with the three changes that save the most.","ctaLabel":"Book the audit","ctaUrl":"#form-audit"},
{"type":"benefits","items":[{"title":"Written report","text":"Yours to keep, with the expected savings of each change."},{"title":"No commitment","text":"You decide later if you want help with the changes."},{"title":"Two hours on site","text":"We measure while the line runs."}]},
{"type":"form","formId":"audit","purpose":"We use these details to schedule the audit and send the report.","heading":"Book the audit","fields":["company","phone","city"],"required":["company"],"submitLabel":"Book the audit","successMessage":"Thanks. We will call you within one business day to set the date.","privacyUrl":"https://example.com/privacy"},
{"type":"faq","items":[{"question":"Is it really free?","answer":"Yes. The audit and the report have no cost."},{"question":"What happens after I send the form?","answer":"We call you to pick a date."}]}
]
blog-hub)Use when: A site that lives on articles. The blog index (/blog) and news index (/news) are automatic; the landing is the home that explains the site and points to the best articles.
Order and why:
Site settings (site_update):
{"fontPairing":"book","colorScheme":"auto","themeToggle":true,"navLinks":[{"label":"Start here","url":"content:3f2b8c1e-0a4d-4e6b-9c7a-5d1e2f3a4b5c"}]}
Example blocks (landing_create_draft or landing_update blocks):
[
{"type":"hero","heading":"Practical notes on running small servers","subheading":"One article a week on backups, deploys and monitoring, from real incidents.","ctaLabel":"Start here","ctaUrl":"content:3f2b8c1e-0a4d-4e6b-9c7a-5d1e2f3a4b5c"},
{"type":"features","eyebrow":"Most read","heading":"Start with these","items":[{"title":"Backups you actually tested","text":"A restore drill in 30 minutes.","linkUrl":"content:3f2b8c1e-0a4d-4e6b-9c7a-5d1e2f3a4b5c","linkLabel":"Read"},{"title":"Alerts that wake the right person","text":"Three rules that cut our pages by half.","linkUrl":"/blog"}]},
{"type":"posts","eyebrow":"Latest","heading":"New on the blog","kind":"article","count":3,"showAllLink":true},
{"type":"cta","heading":"Get the next article","text":"One e-mail a week, no tracking.","buttonLabel":"Subscribe","buttonUrl":"https://example.com/newsletter","buttonStyle":"outline"}
]
multi-language)Use when: The same site in two or more languages, with the language switcher and hreflang done for you. Build and review the main language first, then translate.
Order and why:
Site settings (site_update):
{"languageSwitcher":"compact","locales":{"en":{"navLinks":[{"label":"Products","url":"#products"},{"label":"About","url":"#about"}],"footerText":"Product names belong to their owners.","jobTitle":"Cofounder and DevOps engineer"}}}
Example blocks (landing_create_draft or landing_update blocks):
[
{"type":"hero","heading":"Ada Lovelace","subheading":"Cofounder and DevOps engineer","showSocialLinks":true},
{"type":"features","anchorId":"products","eyebrow":"Products","items":[{"title":"Example Cloud","linkUrl":"https://example.com"}]},
{"type":"text","anchorId":"about","eyebrow":"About","heading":"Since 2005","markdown":"English version of the about text."}
]
Copy decides whether a visitor stays. These rules are the same ones the Prospia AI writer follows:
locale. Translations are rewritten in their language, not mixed.seoTitle: 50 to 60 characters (limit 70). Meta description: 70 to 160 characters (the tools warn outside that range), a real sentence with the main term.media_upload stores an image (https URL or base64) and returns the mediaId plus the sizes. JPEG, PNG, GIF, WebP and ICO go up to 15 MB: the platform makes widths of 1600, 800 and 400 px for responsive loading and a 1200x630 share card, and removes EXIF and GPS data.
logoMediaId, logoDarkMediaId), favicons and diagrams in image blocks. The server sanitizes it: scripts, foreignObject, event handlers, external links and references and unsafe styles are removed. It needs a width and height or a viewBox.urls.original.defaultOgMediaId, a page ogMediaId) must be PNG, JPEG or WebP: social networks do not show SVG, so an SVG there is refused with raster_required.media_upload_url (site, optional filename and alt): it returns uploadUrl, maxBytes per type and a ready example, e.g. curl -sS -X PUT --data-binary @logo.svg -H 'Content-Type: image/svg+xml' '<uploadUrl>'.id, urls, width, height, contentType): the id is the mediaId. The link lasts 10 minutes and works for one upload; a refused file (wrong type, too large) can be sent again with the same link.media_upload with a public https URL, or base64 (a data:...;base64, prefix and line breaks are fine).invalid_base64: a character that is not base64 (the message names it and its position) or a length no complete base64 has (truncated). Send the whole file again or use media_upload_url.not_an_image: the bytes are not JPEG, PNG, GIF, WebP, ICO or SVG (the message says how many bytes arrived and the first ones).too_large (over 15 MB or too many pixels), svg_too_large (SVG over 200 KB): the message says the size and the limit.invalid_svg: malformed XML, the root is not <svg>, no size, or nothing left after sanitizing. decode_failed: a known format whose data is corrupt or truncated.raster_required: an SVG set as a share image.imageMediaId): 1200 to 1600 px wide, landscape or square; a real screenshot or photo.avatarMediaId): square, at least 512x512, face centered (it is cropped to a circle).coverMediaId): 1200x630; index cards crop to that ratio.ogMediaId per page, defaultOgMediaId for the site): exactly 1200x630, text large and centered (it is shown small in feeds).logoMediaId): horizontal SVG (mark plus name), transparent background; logoDarkMediaId in light colors for dark pages.faviconMediaId): an SVG mark or a square PNG, 512x512, simple shape that reads at 16 px.darkMediaId for dark pages.imageAlt, avatarAlt, alt, coverAlt): what the image shows and why it is there, in the page language, under 125 characters. Not "image of"; not the file name.The page ogMediaId, else the cover, else the site defaultOgMediaId, else (landings) the hero or first image, else a generated card with the title in the site colors.
content_generate_image, content_generate_share_image and content_generate_favicon draw images and spend credits; no text, logos or real people in them. Prefer the person's own photos and screenshots when they exist.
The platform does the technical SEO (server HTML, canonical, Open Graph, JSON-LD, sitemap, hreflang, llms.txt, redirects). Your part is the words and the structure.
air-conditioning-repair), up to 120 characters, no dates unless the content is dated./infra-com-ia and /en/infra-com-ia).seoTitle (up to 70) when the search title should differ from the page title.description: 70 to 160 characters, required to publish. The tools return SEO notes in issues on every save: read them.locale (e.g. en) and translationOf (the original id). On the same site it lives at /en/<slug> and the home translation at /en.content_create_translation {id, locale}: a linked draft copy (add translate: true for an AI translation, which spends credits). One translation per language per page: a second one answers translation_exists with the existing page.targetSite).<html lang> and og:locale, and the header shows the language switcher. Previews show the switcher and hreflang too.site_update locales (menu, footer, job title, badges per language). A menu link content:<id> opens the translation of that page in the page language.site_update takes the analytics ids (a settings draft). GA4 (ga4MeasurementId) and Umami (umamiScriptUrl + umamiWebsiteId) work on every plan; Tag Manager, Google Ads, Meta, LinkedIn and Clarity need a paid plan.generate_lead in GA4, Umami and the others.https://cloud.umami.is/script.js) or self-hosted on Quave ONE (https://quave.one/?utm_source=prospia-sites&utm_medium=docs&utm_campaign=umami): an app with the official image ghcr.io/umami-software/umami:postgresql-latest, a Postgres database, DATABASE_URL and APP_SECRET, then add the site in Umami and copy its script URL and website id.content:<id>.Every link field (and every link inside markdown) accepts:
https://... absolute URL (external sites)./path: a path of the same site (/contact).#anchor: a section of the same page.content:<id>: another page of the same site by id; content:<id>#anchor for a section of it.mailto: and tel:.Anything else (javascript:, data:, spaces, quotes) is refused.
content:<id> (or /path). They are resolved at render time, so they survive slug changes and custom domains, and inside previews they open the drafts.https://<site>.sites.prospia.ai/... links to your own pages: they break when a custom domain is added and they skip the drafts in previews.anchorId (lowercase, digits, hyphens, up to 60 chars, unique in the page) and link to it with #anchorId.#anchorId goes to that section of the home page in the language of the page being viewed; content:<id>#anchorId goes to a section of another page.#form-<formId>; form- and ps- prefixes, main, faq-h and rel-h are reserved.#produtos in Portuguese, #products in English); the menu of each language (locales.<lang>.navLinks) points to its own.domain_add {hostname} returns the records, each with a purpose. Ownership: one TXT _prospia-sites.<domain> proves the registrable domain (example.com.br) belongs to the organization once; it covers www, blog and any other address under it, on every site of the organization. Routing: a CNAME to sites.prospia.ai for a subdomain; for the domain itself (no CNAME possible there) the A and AAAA records shown, or an ALIAS/ANAME record when the DNS provider has one.withWww: true (or add www.<domain> after): www then redirects to the primary address.domain_check answers ownership.verified and routing.ok apart, and check.issues says what is missing (ownership_txt_missing, routing_missing). DNS changes can take hours; tell the person to wait and check again rather than changing records.domain_check {primary: true}) only when it is active; the .sites.prospia.ai address keeps working and redirects to it.navLinks (up to 8). Footer: footerLinks (up to 20). Profiles: socialLinks.ctaUrl, cta buttonUrl, card linkUrl and links (up to 3 per card), and inline markdown in hero body, intro and the text block.Collected from real sites built through this connector. Each one cost a round of rework.
content:<id> or /path.anchorId: the link only scrolls to the top. Set anchorId on the blocks first, then use #anchorId in navLinks.eyebrow and keep the title clean.[text](link) shows literally in headings, card titles and card text. Inline markdown works only in hero body and in intro; full markdown in the text block. For a link inside a card use linkUrl or links.landing_update: the blocks left out are removed. Read the page, change what you need, send the complete list.baseRevision, or ignoring sites-revision_conflict: someone else's edit gets lost. Re-read and merge.footerText: the platform already adds the copyright line, so it shows twice.content_create_translation (or locale + translationOf): the pages get hreflang, the switcher and may keep the same slug.site_update locales.preview_link. Settings drafts show in site_preview_link (the whole site).site_get planFlags; they are not settings.poweredBy: false on a plan that keeps "Made with Prospia" (branding_locked): tell the person it is a paid-plan option, do not retry.imageMediaId and avatarMediaId in one hero, an image on a CTA banner (needs style: "card"), linkLabel without linkUrl: refused. See the rules in the blocks topic.planFlags.site_preview_link.preview_link / site_preview_link first, publish after a yes.Reading, writing drafts, uploading images, previews, publishing and this guide are free. Only AI generation spends the organization's AI credits:
content_generate_landingcontent_generate_blockcontent_generate_articlecontent_generate_imagecontent_generate_faviconcontent_generate_share_imageimage_suggest_descriptioncontent_create_translation with translate: true (the AI translation; without it the copy is free). It also needs the AI writing permission.model; the default is the cheapest, larger models cost more. The answer of every AI tool reports creditsUsed and the balance.site_plan_status shows the balance and the credits Sites AI spent per action. The Free plan starts with a small credit grant.