SEO for SaaS
Start
API reference

Blocks

The block types, rich text, and the JSON Schema.

An article's body is an ordered array of blocks, each with a type. Render the types you know and skip the rest. A type added later is then missing from the page instead of breaking it.

TypeFields
headinglevel: 2 | 3 | 4, text, idid is an anchor derived from the text, unique within the article; a rewrite that changes the heading changes it. The article title isn't a block.
paragraphcontent: RichText
listordered, items: RichText[]
quotecontent: RichText, attribution?
codelanguage?, codePlain text; don't interpret.
imageurl, alt, caption?On the SEO for SaaS CDN; alt is always set.
calloutvariant: "info" | "tip" | "warning", content: RichText
ctaheading, body?, buttonLabel, buttonHrefA call to action into your product.
faqitems: { question, answer: RichText }[]Also in seo.jsonLd as FAQPage.
tableheaders: string[], rows: string[][]Plain-text cells.
videoprovider: "youtube", videoId, url, titleA YouTube video taken from the search results for the topic.

Every block also carries an id, unique within the article. Each type has a page with a live render under Components.

Rich text

Paragraphs, list items, quotes, callouts and FAQ answers are RichText: an array of runs.

FieldType
textstringPlain text. Render it as text, never as HTML.
bold, italic, codeboolean?Inline styling.
hrefstring?Makes the run a link: https: or http:, a site path (/pricing), or a # anchor. Nothing else.
relstring?Set on every link to a research source, currently nofollow ugc noopener. Pass it to the anchor unchanged.
A paragraph citing a source
{  "type": "paragraph",  "content": [    { "text": "Google describes the process in its " },    {      "text": "guide to how Search works",      "href": "https://developers.google.com/search/docs/fundamentals/how-search-works",      "rel": "nofollow ugc noopener"    },    { "text": "." }  ]}

JSON Schema

https://api.seoforsaas.dev/public/v1/schema/blocks.json describes the block array. It's generated from the schema the API validates with, so it always matches what the API returns. The API enforces the link-scheme and rel rules.