On this page

Home / Documentation / API reference

API reference

HTTP surface for sites, pages, blocks, media, CMS, and billing, aligned with the dashboard. Use the sidebar to jump within this page. New to SlateHut? Read the documentation hub first, then come back here for routes, schemas, and examples.

Introduction

Authenticated routes accept a Bearer API key (Launch+ workspaces) or, on this origin, a signed-in session. The sections below document authentication, limits, and the OpenAPI narrative; then the full route list, generated from the same spec we ship as JSON.

Conceptual overview, workspace behavior, and capability summaries live on the main documentation page.

Authentication

Create a secret key under API keys in the dashboard for Launch, Pro, or Agency workspaces (Free cannot create Bearer keys). Send Authorization: Bearer sh_live_… on each call. Signed-in visitors can also call these routes from the browser without a header. See Examples → Auth header.

Base URL and limits

Base URL

All versioned routes hang off your SlateHut host.

https://slatehut.com/api/v1

Rate limits

Up to 60 requests per minute for each API key or session. Expect 429 when you exceed that window.

OpenAPI specification

We ship OpenAPI 3.1 JSON so you can import into Postman, generate typed clients, or diff changes between releases. The prose below is mirrored from the spec itself.

SlateHut APIv1.0.0140 schemas

Server URL in the document
https://slatehut.com

Auth style: HTTP bearer, API key from Dashboard → API Keys (prefix `sh_live_`). **Free** workspaces cannot create keys; Launch, Pro, and Agency can.

Use this API from your own scripts and integrations to create and update SlateHut sites-pages, themes, forms, media, and more-so they stay aligned with what you see in the dashboard.

Workspaces: API keys and browser sessions are scoped to an active workspace. Bearer keys belong to one workspace; GET /api/v1/sites lists sites in that workspace only. The dashboard lets you switch workspaces (each has its own plan and AI credit pool). Free workspaces cannot create Bearer keys; Launch, Pro, and Agency can.

Authenticate with Authorization: Bearer <api_key> (keys start with sh_live_; create keys in the dashboard on a Launch+ workspace). If you are logged into SlateHut in the browser, your session also works for the same endpoints on this website. Rate limit: 60 requests per minute per API key or session.

Same behavior as the dashboard: Site document GET/PUT, CMS, domains, preview token, per-site form submissions, file upload, Unsplash search/import (requires UNSPLASH_ACCESS_KEY on our servers), subdomain availability, and sync-chrome (navbar/footer sync across pages) match what you can do in the product.

Granular pages & blocks: GET/POST /api/v1/sites/{subdomain}/pages, GET/PUT/DELETE …/pages/{pagePath}, and block CRUD under …/pages/{pagePath}/blocks (plus PATCH …/blocks/reorder) update the same JSON document as the editor. Path segment pagePath: use _ for the home page; nested slugs use one encoded segment (e.g. legal%2Fprivacy). Query scope=template targets dynamic.templateBlocks on CMS pages. Every PageBlock may include optional animation (BlockAnimation: preset, scroll|load trigger, timing) plus animatedHero, logoCloud, featureShowcase, metricsBand, comparisonTable, faqAccordion, and gallery3d block types alongside the existing library.

Images: POST /api/v1/media/upload (multipart file), or Unsplash GET …/media/unsplash/search (supports orientation and color filters) + POST …/media/unsplash/import with { photoId }{ url, alt, attribution }. You must display attribution.html (or an equivalent link credit) wherever the imported image appears, this is required by the Unsplash API license.

Built-in templates: GET /api/v1/templates lists curated ids (aiSaas, financialAdvisor, lawFirm, medicalAesthetic, realEstate, executiveCoach, agency, boutiqueHotel, weddingVenue, interiorDesign, dtcProduct, onlineCourse, fineDining, luxuryPortfolio, comingSoon) with premium home layouts; pass templateId on create or generation to start from one.

AI site generation: POST /api/v1/sites/generate runs plan + home page in one call (gated by workspace AI credits in USD, not a monthly run count). Optional brief object (industry, audience, inspiration URLs, logo URL, avoid list, tone sliders) steers the model toward a more bespoke result. For human review, use POST /api/v1/sites/generate/plan (returns JSON plan) then POST /api/v1/sites/generate/from-plan with that plan-same persistence as POST /api/v1/sites. Plan may include 1–6 static pages (home "" plus optional routes); the model emits one blocks pass per planned page. Optional Unsplash images. Free plan / no AI budget: AI generation endpoints return 402 when limits are hit; the dashboard and editor remain available for manual editing. Use POST /api/v1/sites with templateId, full pages[], or { blank: true } (no AI credits; dry-run with POST /api/v1/sites/validate), then page/block CRUD or MCP create_site_from_template / create_site_from_document + block tools. POST /api/v1/sites/generate/from-plan still runs SlateHut models even if you supply the plan.

Billing (Stripe): POST /api/v1/billing/checkout returns { url } for Stripe Hosted Checkout on a workspace subscription (owner/admin only). Checkout sessions enable allow_promotion_codes so promotion codes can be entered on Stripe’s hosted page (success returns to the dashboard billing return URL). POST /api/v1/billing/credits-checkout returns { url } for one-time AI credit pack purchases. POST /api/v1/billing/portal returns a Stripe Customer Portal URL. GET /api/v1/billing/status returns the active workspace billing summary. Plan changes sync from Stripe webhooks to the workspace billingPlan.

Pages: pages[] = SitePageDef; each blocks[] entry = PageBlock (discriminated type + *BlockProps), including optional custom blocks (sanitized HTML + Tailwind + scoped css with .ai-custom-root selectors). Set optional anchorId on any block to give it an HTML id for in-page anchors (e.g. navbar link #pricing scrolls to the block with anchorId: "pricing"). When creating CMS collections with attachDynamicPage, the home page navbar and footer are automatically copied to the new dynamic page. Use POST …/collections/{collectionId}/attach-dynamic-page to attach a minimal list/detail page to an existing collection. CMS detail metadata uses dynamic.seoMapping: field ids plus optional *Template strings with {{fieldId}} placeholders filled from entry data (see CmsSeoMapping).

MCP (Model Context Protocol): POST, GET, and DELETE on /api/mcp expose Streamable HTTP for AI clients (Cursor, ChatGPT, Claude, and others). Authenticate with Authorization: Bearer <api_key> (sh_live_…, same as REST v1; only on paid key-enabled workspaces) or complete OAuth 2.1 via /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server (token endpoints under /api/oauth). MCP tools are deterministic (no SlateHut AI credits): create_site_from_template, create_site_from_document, update_site, block/page/theme CRUD, media, CMS, domains, submissions, templates. Hosted AI: REST POST /api/v1/sites/generate* only. Deletion: delete_site with confirm: true. Server instructions on initialize describe the no-AI workflow. Section HTML AI remains dashboard/REST generate-section where documented. Prompts provide canned site-type briefs. Agents can discover block shapes through MCP resources, schema://blocks (index), schema://blocks/{type} (full JSON schema: shell + props + resolved component refs), schema://theme, example://blocks/{type}, example://sites/{templateId}, site://{subdomain}, site://{subdomain}/pages/{pageSlug}, and block/page/site mutations return field-path validation errors (e.g. props.variant: Invalid enum value) so they can self-correct. Requires MCPAUTH_SECRET (HMAC for signed authorize state) and MCPAUTH_PRIVATE_KEY (RSA PEM for JWKS) when using the OAuth flow.

Editor-only: Live preview hydration actions (no public HTTP surface).

Download the live file: https://slatehut.com/api/v1/openapi.json

Grab it with curl if you want a local copy in one command.

Model Context Protocol (MCP)

Connect Cursor, ChatGPT, Claude, and other MCP clients to /api/mcp (Streamable HTTP). Use the same sh_live_ API key as REST v1, or run the OAuth 2.1 flow discovered from /.well-known/oauth-protected-resource (authorization server metadata at /.well-known/oauth-authorization-server; token endpoints under /api/oauth). Sign in on the web when the authorize step redirects to login. OAuth issuance requires MCPAUTH_SECRET and MCPAUTH_PRIVATE_KEY (RSA PEM) in the server environment.

MCP installation snippets and product-oriented guide → Includes a Free plan / no AI credits recipe when AI tools return quota errors.

Tools

  • create_site_from_template — built-in template, no AI credits
  • create_site_from_document — full pages[] you supply (BYO-LLM), no AI credits
  • list_sites, get_site, update_site_theme
  • add_page, update_page, delete_page
  • list_templates, check_subdomain

Prompts

Canned briefs align with built-in templates (AI SaaS, wealth, law, med spa, real estate, coaching, agency, hospitality, events, interiors, DTC, courses, dining, portfolio, coming soon).

OpenAPI lists MCP-related paths under the mcp tag.

Free plan / no AI credits (REST)

Free workspaces include limited AI budget and one lifetime AI generation start. When AI endpoints return 402, the dashboard and editor remain open for manual editing. Use deterministic REST instead of generate/edit:

  1. List templates. GET /api/v1/templates
  2. Create without AI. POST /api/v1/sites with templateId or { blank: true }— no AI credits consumed.
  3. Validate (optional). POST /api/v1/sites/validate dry-runs the same body before create.
  4. Customize. Page and block CRUD under /api/v1/sites/{subdomain}, or MCP create_site_from_template/ create_site_from_document + update_site. See MCP: Free plan / no AI credits.

Build a site with this API (for agents)

Follow the steps in order. Each step names the HTTP method and path; the Examples section below has working payloads in curl, JavaScript, and Python.

  1. Create or pick a site. POST /api/v1/sites with a template, or POST /api/v1/sites/generate when you want AI to draft the first home page. Optional: GET /api/v1/sites/availability?q=… before you commit a subdomain.
  2. Inspect pages. GET /api/v1/sites/{subdomain}/pages lists routes; GET …/pages/_ returns the home document with blocks.
  3. Shape the layout. Add blocks with POST …/blocks, update with PUT …/blocks/{id}, or reorder via PATCH …/blocks/reorder. Use the Data models section for props per block type.
  4. Add assets. POST /api/v1/media/upload accepts multipart files; reference the returned URL inside hero, gallery, or rich blocks.
  5. Tune the theme. PUT /api/v1/sites/{subdomain} with a theme object merges into the existing palette.
  6. Verify in the browser. Open the public URL for that subdomain on your SlateHut host (or the custom domain after DNS verifies) and confirm the live page matches the JSON you saved.

Need raw HTTP samples? Jump to the Examples.

All endpoints

Every row matches the published OpenAPI document. Path-level parameters apply to every method on that URL. Bearer means an API key or session cookie; Public means no authentication.

templatesBuilt-in site templates (no auth)

get/api/v1/openapi.jsonPublic

OpenAPI document

Responses

  • 200, This OpenAPI JSON
get/api/v1/templatesPublic

List site templates

Responses

  • 200, Template metadata

cmsCMS presets (no auth)

get/api/v1/cms/presetsPublic

List CMS collection presets (blog, directory)

Responses

  • 200, Preset ids and descriptions

sitesSite CRUD (auth required, no AI credits)

get/api/v1/sitesBearer

List current workspace's sites

Responses

  • 200, Site list (SiteListResponse)
  • 401, Missing or invalid credentials
post/api/v1/sitesBearer

Create a site

Request body

application/json · CreateSiteRequest

Responses

  • 201, Created
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 409, Validation or conflict error
  • 503, Validation or conflict error
post/api/v1/sites/validateBearer

Validate a create-site payload (dry run)

Validates the same JSON body as POST /api/v1/sites (templateId, blank, or full pages[]) without persisting or consuming create-site quota. Use before large programmatic imports.

Request body

application/json · required · CreateSiteRequest

Responses

  • 200, Valid payload
  • 400, Validation failed
  • 401, Missing or invalid credentials
get/api/v1/sites/availabilityBearer

Check if a subdomain is valid and available

Same rules as the editor: normalization, reserved names, length 2–48, uniqueness. Empty q returns { normalized: "", available: true }.

Parameters

NameInReqDetails
qquerynostringProposed subdomain string

Responses

  • 200, normalized slug and whether it can be registered (SubdomainAvailabilityResponse)
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
get/api/v1/sites/{subdomain}Bearer

Get site document

Parameters

NameInReqDetails
subdomainpathyesstring
includequerynostringComma-separated projection: pages, theme, chrome, title, description, meta, or all (default full document).

Responses

  • 200, Site payload (SiteGetResponse)
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
put/api/v1/sites/{subdomain}Bearer

Update site

Parameters

NameInReqDetails
subdomainpathyesstring

Request body

application/json · required · UpdateSiteRequest

Responses

  • 200, Updated
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
  • 409, Validation or conflict error
delete/api/v1/sites/{subdomain}Bearer

Delete site

Permanently deletes the site and its data. Any custom domains attached to the site are removed from the hosting project on Vercel before the database row is deleted (same as removing each domain via DELETE …/domains/{hostname}).

Parameters

NameInReqDetails
subdomainpathyesstring

Responses

  • 200, Deleted
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
get/api/v1/sites/{subdomain}/pagesBearer

List pages (slug, path, block counts)

Returns a lightweight summary per page. Full SitePageDef is available via GET …/pages/{pagePath}.

Parameters

NameInReqDetails
subdomainpathyesstring

Responses

  • 200, Page summaries (SitePageListResponse)
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
post/api/v1/sites/{subdomain}/pagesBearer

Create a new page

Adds a route under the site. slug must not be empty (use _ in pagePath only when addressing the existing home page on other routes). Defaults to a single text block if blocks is omitted.

Parameters

NameInReqDetails
subdomainpathyesstring

Request body

application/json · required · CreateSitePageRequest

Responses

  • 201, Created page
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
  • 409, Validation or conflict error
get/api/v1/sites/{subdomain}/pages/{pagePath}Bearer

Get one page (full SitePageDef)

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstringSingle URL segment for the page slug. Use `_` for home (`slug === ""`). Nested slugs: encode slashes, e.g. `legal%2Fprivacy`.

Responses

  • 200, 200
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
put/api/v1/sites/{subdomain}/pages/{pagePath}Bearer

Update one page

Partial update: omit fields to keep current values. Set dynamic to null to remove CMS wiring. seo can be set to null to clear.

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstringSingle URL segment for the page slug. Use `_` for home (`slug === ""`). Nested slugs: encode slashes, e.g. `legal%2Fprivacy`.

Request body

application/json · required · UpdateSitePageRequest

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
delete/api/v1/sites/{subdomain}/pages/{pagePath}Bearer

Delete a page

Cannot delete the home page or the only remaining page.

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstringSingle URL segment for the page slug. Use `_` for home (`slug === ""`). Nested slugs: encode slashes, e.g. `legal%2Fprivacy`.

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
get/api/v1/sites/{subdomain}/pages/{pagePath}/blocksBearer

List blocks on a page

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstringSame as single-page GET: `_` = home; nested = encodeURIComponent.
scopequerynoindex | template`index` (default) = page `blocks`. `template` = `dynamic.templateBlocks` on CMS pages.

Responses

  • 200, 200 (PageBlockListResponse)
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
post/api/v1/sites/{subdomain}/pages/{pagePath}/blocksBearer

Add a block

Optional position (0-based insert index; default append).

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstringSame as single-page GET: `_` = home; nested = encodeURIComponent.
scopequerynoindex | template`index` (default) = page `blocks`. `template` = `dynamic.templateBlocks` on CMS pages.

Request body

application/json · required · AddSiteBlockRequest

Responses

  • 201, 201
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
patch/api/v1/sites/{subdomain}/pages/{pagePath}/blocks/reorderBearer

Reorder blocks

blockIds must list every block id exactly once.

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstring
scopequerynoindex | template

Request body

application/json · required · ReorderBlocksRequest

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
get/api/v1/sites/{subdomain}/pages/{pagePath}/blocks/{blockId}Bearer

Get one block

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstring
blockIdpathyesstring
scopequerynoindex | template

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
put/api/v1/sites/{subdomain}/pages/{pagePath}/blocks/{blockId}Bearer

Patch block shell / props

Shallow-merge props onto existing props. anchorId / colorOverrides null clears. type and id cannot be changed.

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstring
blockIdpathyesstring
scopequerynoindex | template

Request body

application/json · required · BlockPatchRequest

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
delete/api/v1/sites/{subdomain}/pages/{pagePath}/blocks/{blockId}Bearer

Remove a block

Cannot remove the last block on a page or template.

Parameters

NameInReqDetails
subdomainpathyesstring
pagePathpathyesstring
blockIdpathyesstring
scopequerynoindex | template

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
post/api/v1/sites/{subdomain}/sync-chromeBearer

Sync navbar & footer from one page to all pages

Copies the navbar and footer blocks from a source page (default: home) to every other page on the site, including dynamic.templateBlocks for CMS detail pages. Mirrors the editor's "Apply to all pages" action. Existing navbar/footer blocks on target pages are replaced in-place; pages without them get the block prepended (navbar) or appended (footer).

Parameters

NameInReqDetails
subdomainpathyesstring

Request body

application/json

Responses

  • 200, Sync complete
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
post/api/v1/sites/{subdomain}/preview-tokenBearer

Regenerate draft preview token

Parameters

NameInReqDetails
subdomainpathyesstring

Responses

  • 200, previewToken

sites-aiSlateHut-hosted AI generation (consumes workspace AI credits). For programmatic builds without credits, use `POST /api/v1/sites` with `pages[]` or MCP `create_site_from_document`.

post/api/v1/sites/generateBearer

Create a site from an AI prompt

Runs structured LLM calls (Vercel AI Gateway): a site plan (Sonnet) then one blocks call per planned static page (up to six: home plus optional about/pricing/contact/blog, etc.), then persists like POST /api/v1/sites. For a two-step flow with plan review, use POST /api/v1/sites/generate/plan then POST /api/v1/sites/generate/from-plan. Image URLs: Unsplash + Blob when configured; otherwise Picsum placeholders.

Request body

application/json · required · GenerateSiteRequest

Responses

  • 201, Created
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 402, AI Gateway budget cap reached. Update billing limits and try again. `reason = budget_exceeded`.
  • 409, Validation or conflict error
  • 422, Model could not produce valid output. Try a shorter or clearer prompt. `reason = invalid_output`.
  • 429, AI provider is rate-limited right now. `reason = rate_limited`.
  • 502, AI provider is temporarily unavailable, credentials are misconfigured, or the request failed. `reason = upstream_unavailable | unauthorized | upstream_error | unknown`.
  • 503, AI provider is temporarily unavailable, credentials are misconfigured, or the request failed. `reason = upstream_unavailable | unauthorized | upstream_error | unknown`.
  • 504, AI provider timed out. Try again in a moment. `reason = upstream_timeout`.
post/api/v1/sites/generate/planBearer

Create a site plan from a prompt (AI)

Returns JSON plan (theme, navbar, footer, pages[] with home plus optional extra routes)-same shape required by POST /api/v1/sites/generate/from-plan. Non-streaming; mirrors a plan-only step for programmatic flows; the dashboard New site page (/dashboard/new) uses one-step streaming generation instead.

Request body

application/json · required · GenerateSitePlanRequest

Responses

  • 200, Site plan JSON
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 402, AI Gateway budget cap reached. Update billing limits and try again. `reason = budget_exceeded`.
  • 422, Model could not produce valid output. Try a shorter or clearer prompt. `reason = invalid_output`.
  • 429, AI provider is rate-limited right now. `reason = rate_limited`.
  • 502, AI provider is temporarily unavailable, credentials are misconfigured, or the request failed. `reason = upstream_unavailable | unauthorized | upstream_error | unknown`.
  • 503, AI provider is temporarily unavailable, credentials are misconfigured, or the request failed. `reason = upstream_unavailable | unauthorized | upstream_error | unknown`.
  • 504, AI provider timed out. Try again in a moment. `reason = upstream_timeout`.
post/api/v1/sites/generate/from-planBearer

Create a site from an approved AI plan

Runs SlateHut block generation from a plan returned by POST /api/v1/sites/generate/plan (optionally edited), then persists like POST /api/v1/sites/generate. Still consumes AI credits — if your agent already has full block JSON, use POST /api/v1/sites with pages[] instead.

Request body

application/json · required · GenerateSiteFromPlanRequest

Responses

  • 201, Created
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 402, AI Gateway budget cap reached. Update billing limits and try again. `reason = budget_exceeded`.
  • 409, Validation or conflict error
  • 422, Model could not produce valid output. Try a shorter or clearer prompt. `reason = invalid_output`.
  • 429, AI provider is rate-limited right now. `reason = rate_limited`.
  • 502, AI provider is temporarily unavailable, credentials are misconfigured, or the request failed. `reason = upstream_unavailable | unauthorized | upstream_error | unknown`.
  • 503, AI provider is temporarily unavailable, credentials are misconfigured, or the request failed. `reason = upstream_unavailable | unauthorized | upstream_error | unknown`.
  • 504, AI provider timed out. Try again in a moment. `reason = upstream_timeout`.
post/api/v1/sites/{subdomain}/generate-sectionBearer

Generate section block HTML with AI

Returns sanitized html and optional scoped css for a section block. Consumes workspace AI credits. Does not persist; PATCH the block afterward.

Parameters

NameInReqDetails
subdomainpathyesstring

Request body

application/json · required

Responses

  • 200, Generated section
  • 401, Missing or invalid credentials
  • 402, AI Gateway budget cap reached. Update billing limits and try again. `reason = budget_exceeded`.
  • 403, Not allowed for this resource
  • 404, Resource not found

collectionsCMS collections per site (auth)

get/api/v1/sites/{subdomain}/collectionsBearer

List CMS collections

Parameters

NameInReqDetails
subdomainpathyesstring

Responses

  • 200, All collections for the site (CmsCollectionsListResponse)
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
post/api/v1/sites/{subdomain}/collectionsBearer

Create collection (preset: blog|directory, or manual fields). Manual `fields` must include the `slugField` id as a text field with `required: true`. Optional attachDynamicPage adds a dynamic list/detail route with the home page navbar/footer auto-copied.

Parameters

NameInReqDetails
subdomainpathyesstring

Request body

application/json · CreateCollectionRequest

Responses

  • 201, Collection created
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 409, Validation or conflict error
get/api/v1/sites/{subdomain}/collections/{collectionId}Bearer

Get collection schema

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring

Responses

  • 200, 200
  • 404, Resource not found
patch/api/v1/sites/{subdomain}/collections/{collectionId}Bearer

Update collection schema (fields and title/slug/content/image pointers)

Cannot change the type of an existing field id; remove and add a new field instead. The field whose id matches slugField must remain present, have type text, and required: true.

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring

Request body

application/json · required

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 404, Resource not found
delete/api/v1/sites/{subdomain}/collections/{collectionId}Bearer

Delete collection and its items

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring

Responses

  • 200, 200
  • 404, Resource not found
post/api/v1/sites/{subdomain}/collections/{collectionId}/attach-dynamic-pageBearer

Attach minimal CMS list + detail page to an existing collection (copies home navbar/footer)

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring

Request body

application/json · required · AttachDynamicPageRequest

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
get/api/v1/sites/{subdomain}/collections/{collectionId}/itemsBearer

List items (query: page, limit, status=draft|published|all, sortField, sortOrder)

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring

Responses

  • 200, 200 (CmsItemsListResponse)
post/api/v1/sites/{subdomain}/collections/{collectionId}/itemsBearer

Create CMS item

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring

Request body

application/json · required · CmsItemWriteRequest

Responses

  • 201, 201
  • 409, Validation or conflict error
get/api/v1/sites/{subdomain}/collections/{collectionId}/items/{itemId}Bearer

Get item

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring
itemIdpathyesstring

Responses

  • 200, 200
  • 404, Resource not found
put/api/v1/sites/{subdomain}/collections/{collectionId}/items/{itemId}Bearer

Update item

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring
itemIdpathyesstring

Request body

application/json · required · CmsItemWriteRequest

Responses

  • 200, 200
delete/api/v1/sites/{subdomain}/collections/{collectionId}/items/{itemId}Bearer

Delete item

Parameters

NameInReqDetails
subdomainpathyesstring
collectionIdpathyesstring
itemIdpathyesstring

Responses

  • 200, success

domainsCustom hostnames (auth, Vercel configured)

get/api/v1/sites/{subdomain}/domainsBearer

List custom domains; ?status=1 includes Vercel DNS status per host

Parameters

NameInReqDetails
subdomainpathyesstring

Responses

  • 200, domains[], optional statusByDomain
post/api/v1/sites/{subdomain}/domainsBearer

Add custom domain (Vercel project must be configured)

Registers exactly the given hostname on the Vercel project (e.g. example.com or www.example.com). Add each variant separately if you need both.

Parameters

NameInReqDetails
subdomainpathyesstring

Request body

application/json · required

Responses

  • 201, domain
  • 409, Validation or conflict error
delete/api/v1/sites/{subdomain}/domains/{hostname}Bearer

Remove custom domain

Parameters

NameInReqDetails
subdomainpathyesstring
hostnamepathyesstringURL-encoded hostname (e.g. encodeURIComponent)

Responses

  • 200, success
post/api/v1/sites/{subdomain}/domains/{hostname}/verifyBearer

Trigger Vercel domain verification

Parameters

NameInReqDetails
subdomainpathyesstring
hostnamepathyesstring

Responses

  • 200, success

mediaUpload images/files for use in block props (auth)

post/api/v1/media/uploadBearer

Upload file (multipart), returns public URL for block props

Multipart form field file. Max size matches dashboard uploads (4 MB). Use the url in hero, gallery, navbar, imageText, etc.

Request body

multipart/form-data · required

Responses

  • 200, Public blob URL
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 503, Validation or conflict error

submissionsForm and newsletter signup responses from published sites (auth). The product shows each site’s inbox under that site; `GET /api/v1/submissions` lists across the active workspace’s sites for integrations. Visitor `POST /api/forms/submit` and `POST /api/newsletter/submit` count toward the workspace plan’s monthly submission cap and return **403** when the cap is reached (Free plan).

get/api/v1/submissionsBearer

List form submissions across all sites you own

Cross-site list for scripts and integrations (the dashboard uses per-site GET /api/v1/sites/{subdomain}/submissions). Use query subdomain to limit to one site. Pass cursor = previous response nextCursor (a submittedAt timestamp) for the next page.

Parameters

NameInReqDetails
subdomainquerynostringOptional; restrict to this site subdomain
cursorquerynostringPagination: prior `nextCursor` (numeric submittedAt)

Responses

  • 200, Submissions include `siteTitle` for cross-site display (AccountSubmissionsResponse)
  • 401, Missing or invalid credentials
get/api/v1/sites/{subdomain}/submissionsBearer

List form and newsletter submissions for one site

Parameters

NameInReqDetails
subdomainpathyesstring
formBlockIdquerynostringOptional; filter to one block id from site JSON (`form` or `newsletter` block)
cursorquerynostringPagination: prior `nextCursor`

Responses

  • 200, 200 (SiteSubmissionsResponse)
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
get/api/v1/sites/{subdomain}/submissions/countsBearer

Submission counts per form or newsletter block (editor sidebar)

Parameters

NameInReqDetails
subdomainpathyesstring

Responses

  • 200, 200 (SubmissionCountsResponse)
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found
delete/api/v1/sites/{subdomain}/submissions/{submissionId}Bearer

Delete one submission

Parameters

NameInReqDetails
subdomainpathyesstring
submissionIdpathyesstring

Responses

  • 200, 200
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 404, Resource not found

unsplashStock photo search and import via Unsplash API (requires UNSPLASH_ACCESS_KEY on server)

post/api/v1/media/unsplash/importBearer

Import Unsplash photo to Blob storage

Triggers the Unsplash download-tracking endpoint, stores an optimized copy on your Blob, and returns { url, alt, attribution }. Per the Unsplash API license you MUST display attribution.html (or an equivalent link credit) wherever the imported image is shown. Body: { "photoId": "<id from search>" }.

Request body

application/json · required

Responses

  • 200, 200
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 413, Validation or conflict error
  • 502, Validation or conflict error
  • 503, Validation or conflict error

billingStripe subscription checkout (embedded), Customer Portal, and billing status for the active workspace (owner/admin only for checkout and portal)

post/api/v1/billing/checkoutBearer

Create hosted subscription checkout session

Returns { url } to open Stripe Hosted Checkout for a recurring subscription. Sessions set allow_promotion_codes: true so customers can apply promotion codes on Stripe’s page. Recurring prices are resolved in Stripe by stable lookup_key values (see catalog setup scripts). Owner or admin only.

Request body

application/json · required · BillingCheckoutRequest

Responses

  • 200, Stripe Checkout session URL (BillingCheckoutResponse)
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 409, Validation or conflict error
  • 503, Validation or conflict error
post/api/v1/billing/credits-checkoutBearer

Create hosted AI credit pack checkout session

Returns { url } for a one-time Stripe Hosted Checkout payment (mode: payment) that adds purchased USD to the workspace bonusCreditUsd pool after checkout.session.completed. Sessions set allow_promotion_codes: true. Owner or admin only.

Request body

application/json · required · BillingCreditsCheckoutRequest

Responses

  • 200, Stripe Checkout session URL (BillingCreditsCheckoutResponse)
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 500, Validation or conflict error
post/api/v1/billing/portalBearer

Create Stripe Customer Portal session

Responses

  • 200, Redirect URL for the portal (BillingPortalResponse)
  • 400, Validation or conflict error
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 500, Validation or conflict error
get/api/v1/billing/statusBearer

Billing status for the active workspace

Responses

  • 200, Effective plan and Stripe subscription fields (BillingStatusResponse)
  • 401, Missing or invalid credentials
  • 403, Not allowed for this resource
  • 500, Validation or conflict error

mcpModel Context Protocol (Streamable HTTP) for AI assistants; OAuth discovery at /.well-known/oauth-protected-resource/api/mcp and /.well-known/oauth-authorization-server, with Client ID Metadata Documents (preferred) and dynamic client registration under /api/oauth. MCP tools are deterministic (no SlateHut AI credits): create_site_from_template, create_site_from_document, list_sites, get_site, update_site, update_site_theme, sync_site_chrome, regenerate_preview_token, list_cms_presets, add_page, update_page, delete_page, list_page_blocks, get_block, add_block, update_block, delete_block, reorder_blocks, upload_image, unsplash_search, unsplash_import, CMS, domains, submissions, list_templates, check_subdomain. Hosted AI generation: REST `POST /api/v1/sites/generate*` only. Initialize returns server instructions for the no-AI workflow. Resources: site://{subdomain}, site://{subdomain}/pages/{pageSlug}, schema://blocks, schema://blocks/{type}, schema://theme. Structured JSON is returned as structuredContent where supported.

get/api/mcpBearer

MCP Streamable HTTP (GET SSE)

Responses

  • 200, MCP SSE stream
  • 401, Missing or invalid credentials
  • 429, Rate limit exceeded
post/api/mcpBearer

MCP Streamable HTTP (POST JSON-RPC)

Request body

application/json

Responses

  • 200, MCP response (JSON or SSE per client Accept header)
  • 401, Missing or invalid credentials
  • 429, Rate limit exceeded
delete/api/mcpBearer

MCP Streamable HTTP (session teardown)

Responses

  • 200, OK
  • 401, Missing or invalid credentials
get/.well-known/oauth-protected-resourcePublic

OAuth protected resource metadata (RFC 9728)

Responses

  • 200, Metadata JSON
get/.well-known/oauth-protected-resource/api/mcpPublic

OAuth protected resource metadata for /api/mcp (RFC 9728 path suffix)

Responses

  • 200, Metadata JSON
get/.well-known/oauth-authorization-serverPublic

OAuth authorization server metadata (RFC 8414)

Responses

  • 200, Metadata JSON

Site & page JSON

These fields line up with UpdateSiteRequest in the spec. Optional keys can be omitted; sending pages replaces the entire page array, while theme merges shallowly.

  • title, public site name
  • description, socialImageUrl , default SEO
  • faviconUrl, headScripts
  • pages, SitePageDef[]
  • theme, SiteTheme

One page in pages[]

Name in API spec: SitePageDef

FieldRequiredType / constraints
blocksyesarray[→ PageBlock]
dynamicno→ SitePageDynamic
seono→ SitePageSeo
slugyesstring
titlenostring

Global theme object

Name in API spec: SiteTheme

FieldRequiredType / constraints
backgroundnostring, CSS hex color, e.g. #27272a
bordernostring, CSS hex color, e.g. #27272a
borderRadiusnonone, sm, md
fontPresetnointer, poppins, roboto, open-sans, lato, montserrat, raleway, dm-sans, space-grotesk, outfit, plus-jakarta-sans, playfair-display, …
footerBackgroundnostring, CSS hex color, e.g. #27272a
footerForegroundnostring, CSS hex color, e.g. #27272a
footerMutednostring, CSS hex color, e.g. #27272a
foregroundnostring, CSS hex color, e.g. #27272a
headingFontPresetnointer, poppins, roboto, open-sans, lato, montserrat, raleway, dm-sans, space-grotesk, outfit, plus-jakarta-sans, playfair-display, …
heroForegroundnostring, CSS hex color, e.g. #27272a
heroFromnostring, CSS hex color, e.g. #27272a
heroTonostring, CSS hex color, e.g. #27272a
mutednostring, CSS hex color, e.g. #27272a
mutedForegroundnostring, CSS hex color, e.g. #27272a
primarynostring, CSS hex color, e.g. #27272a
primaryForegroundnostring, CSS hex color, e.g. #27272a
sectionSpacingnocompact, default, spacious

Section types (blocks)

Each block has a type discriminator plus props. Optional anchorId becomes the HTML id for in-page links like #pricing. Optional fullWidth, colorOverrides, and animation apply to every block type (see schema BlockAnimation in the OpenAPI components). Presets include fade, slide, zoom, blur, and stagger; stagger animates direct child elements in sequence. Respect for reduced motion is handled in published CSS.

Layout

  • navbar

    Navigation, Top bar with your brand, links, and optional CTA.

    NavbarBlockProps

    FieldRequiredType / constraints
    brandLabelyesstring
    ctaHrefnostring
    ctaIconnostring, Lucide icon id (optional).
    ctaLabelnostring
    linksyesarray[→ NavLinkItem]
    logoIconnostring, Lucide icon id when logoUrl is empty (e.g. sparkles). Prefer for API-generated sites without a logo asset.
    logoUrlnostring, Public image URL (e.g. from POST /api/v1/media/upload).
    variantnostandard, minimal, elevated, dense, splitCentered
  • hero

    Hero, Headline, CTAs, imagery, background fill (gradient, solid, photo), patterns, splits, stacked/full-bleed/centered with optional below-fold image, trust row, highlights.

    HeroBlockProps

    FieldRequiredType / constraints
    announcementHrefnostring, Optional link for the announcement pill.
    announcementTextnostring, Optional pill above eyebrow (e.g. funding news).
    backgroundFillnothemeGradientBand, solidPageBackground, photoWithThemeTint
    backgroundImagePositionnocenter, top, bottom, left, right, top left, top right, bottom left, bottom right
    backgroundImageUrlnostring
    backgroundPatternnonone, subtleLineGrid, subtleDotGrid, diagonalFineLines, radialCornerWash
    copyEntrancenonone, fadeRise
    eyebrownostring, Optional short label above the headline.
    featuredImageAltnostring
    featuredImageFitnocover, contain
    featuredImagePositionnocenter, top, bottom, left, right, top left, top right, bottom left, bottom right
    featuredImageUrlnostring
    featuredPresentationnobanner, mockup
    featuredTiltnoboolean, When featuredPresentation is mockup, apply a subtle 3D tilt (respects reduced motion).
    headlineyesstring
    headlineEmphasisnostring, Substring of headline to emphasize (gradient or outlined box); first match only.
    headlineEmphasisStylenoaccentGradientText, softBadgeOutline, thickUnderlineAccent, translucentMarker, solidAccentPill
    highlightsnoarray[→ HeroHighlightItem]
    primaryCtaHrefyesstring
    primaryCtaIconnostring
    primaryCtaLabelyesstring
    secondaryCtaHrefyesstring
    secondaryCtaIconnostring
    secondaryCtaLabelyesstring
    secondaryCtaVariantnooutline, text
    subheadlineyesstring
    trustCaptionnostring, Small caption above trust logos (e.g. “Trusted by”).
    trustItemsnoarray[→ HeroTrustItem]
    variantnomarketingCenteredGradient, marketingCenteredSolid, splitTextLeftImageRight, splitImageLeftTextRight, stackedCenteredWithWideImageBelow, editorialStart
  • animatedHero

    Animated hero, Hero with animated gradient, optional word marquee, and floating shapes, extends the standard hero.

  • spotlightHero

    Spotlight hero (animated), Dark, dramatic hero with an animated radial spotlight that follows the cursor, large editorial headline (optional emphasis word for a gradient slice), supporting subhead, primary + optional secondary CTA, up to 3 small badges, and an optional trust caption. Reach for this when the brief is premium, sophisticated, mysterious, or B2B-technical and the page should open with weight rather than warmth.

    SpotlightHeroBlockProps

    FieldRequiredType / constraints
    badgesnoarray[→ SpotlightHeroBadge]
    eyebrownostring
    glowColornostring
    headlineyesstring
    headlineEmphasisnostring
    primaryCtaHrefyesstring
    primaryCtaIconnostring
    primaryCtaLabelyesstring
    secondaryCtaHrefnostring
    secondaryCtaLabelnostring
    subheadlineyesstring
    trustCaptionnostring
  • auroraHero

    Aurora hero (animated gradient), Hero band with an animated aurora gradient backdrop (slow color drift) behind centered editorial copy, primary + optional secondary CTA, and an optional trust caption. `intensity:"subtle"` keeps the gradient pastel and refined; `intensity:"bold"` saturates it for a more vivid, cinematic feel. Good when the brief is modern, AI-forward, or wants atmosphere without a hero photo.

    AuroraHeroBlockProps

    FieldRequiredType / constraints
    badgesnoarray[→ SpotlightHeroBadge]
    eyebrownostring
    headlineyesstring
    headlineEmphasisnostring
    intensitynosubtle, bold
    primaryCtaHrefyesstring
    primaryCtaIconnostring
    primaryCtaLabelyesstring
    secondaryCtaHrefnostring
    secondaryCtaLabelnostring
    subheadlineyesstring
    trustCaptionnostring
  • banner

    Announcement banner, Thin announcement or notification strip with optional link and icon.

    BannerBlockProps

    FieldRequiredType / constraints
    dismissiblenoboolean
    hrefnostring
    iconnostring, Lucide icon id (optional).
    linkLabelnostring
    textyesstring
    variantnoinfo, success, warning, accent
  • split

    Split columns, Two columns for compare-and-contrast stories.

    SplitBlockProps

    FieldRequiredType / constraints
    asideBodyyesstring
    asideHeadingyesstring
    bodyyesstring
    headingyesstring
  • imageText

    Image & text, Photo or graphic beside a headline and body copy.

    ImageTextBlockProps

    FieldRequiredType / constraints
    bodyyesstring
    headingyesstring
    imageAltyesstring
    imageFitnocover, contain
    imagePositionnocenter, top, bottom, left, right, top left, top right, bottom left, bottom right
    imageSideyesleft, right
    imageUrlyesstring
  • bentoFeatures

    Bento grid, Asymmetric feature cells in a bento-style grid.

    BentoFeaturesBlockProps

    FieldRequiredType / constraints
    cellsyesarray[→ BentoCell]
    headingyesstring
  • bento3dFeatures

    3D-tilt bento grid, 4-6 capability cards in an asymmetric grid where each card has a soft 3D tilt on hover. Items support `span:"wide"|"tall"|"normal"`, an optional image or Lucide icon, and an `accent` tone (primary/muted/inverse). Use when the brief is a modern software product with several differentiated capabilities to showcase tactilely; avoid for service businesses where bento reads as gimmicky.

    Bento3dFeaturesBlockProps

    FieldRequiredType / constraints
    headingyesstring
    itemsyesarray[→ Bento3dItem]
  • featureShowcase

    Feature showcase, Sticky scroll feature sections with alternating media and bullet lists.

    FeatureShowcaseBlockProps

    FieldRequiredType / constraints
    headingnostring
    itemsyesarray[→ FeatureShowcaseItem]
    mediaSidenoleft, right, alternate
    stickyScrollnoboolean
  • featuresAccordion

    Interactive features accordion, Interactive side-by-side showcase of key features, where selecting an accordion tab on the left smoothly expands details in-place and cross-fades full visual mockups on the right.

    FeaturesAccordionBlockProps

    FieldRequiredType / constraints
    activeColornostring, Optional accent override.
    headingyesstring
    itemsyesarray[→ FeaturesAccordionItem]
    subheadingnostring

Content

  • text

    Text section, Simple heading plus paragraph-great for policy or bios.

    TextBlockProps

    FieldRequiredType / constraints
    bodyyesstring
    headingyesstring
  • rich

    Rich block, Long-form content with headings, lists, and formatting.

    RichBlockProps

    FieldRequiredType / constraints
    docyes→ TipTapDoc
  • features

    Features grid, Selling points: icon grid or alternating image rows (layout + per-item imageUrl/imageAlt), optional subheading.

    FeaturesBlockProps

    FieldRequiredType / constraints
    headingyesstring
    itemsyesarray[→ FeatureItem]
    layoutnogrid, alternating
    subheadingnostring
  • stats

    Stats row, Key metrics in a clean horizontal row.

    StatsBlockProps

    FieldRequiredType / constraints
    headingyesstring
    statsyesarray[→ StatItem]
  • metricsBand

    Metrics band, Animated or static KPI band with count-up numbers.

    MetricsBandBlockProps

    FieldRequiredType / constraints
    countUpnoboolean
    headingnostring
    itemsyesarray[→ MetricsBandItem]
    stylenominimal, card, split
  • team

    Team grid, Team member grid with avatars, roles, bios, and social links.

    TeamBlockProps

    FieldRequiredType / constraints
    columnsyes2, 3, 4
    headingyesstring
    membersyesarray[→ TeamMember]
    subheadingnostring
  • callout

    Callout box, Highlighted callout box for tips, warnings, or important notes.

    CalloutBlockProps

    FieldRequiredType / constraints
    bodyyesstring
    headingnostring
    iconnostring, Lucide icon id; defaults to variant icon.
    variantnoinfo, tip, warning, important
  • list

    List / grid (static), Manually edited cards or rows (team, services, resources).

    ListBlockProps

    FieldRequiredType / constraints
    columnsyes2, 3, 4
    headingyesstring
    itemsyesarray[→ ListItem]
    layoutyeslist, grid
    showImagesyesboolean
  • collectionList

    CMS index block, Repeating cards loaded from a content collection (blog posts, directory, etc.).

    CollectionListBlockProps

    FieldRequiredType / constraints
    collectionIdyesstring, CMS collection id (`GET /api/v1/sites/{subdomain}/collections`).
    columnsyes2, 3, 4
    fieldMapno→ CollectionListFieldMap
    headingyesstring
    layoutyeslist, grid
    limitnointeger, Max items when pagination is disabled.
    paginationno{ enabled: boolean; pageSize: integer }
    showImagesyesboolean
    sortFieldnostring, Field id or `updatedAt`.
    sortOrdernoasc, desc
    visibleFieldsnoarray[string]
  • collectionDetail

    CMS detail block, Renders one CMS entry on detail URLs from your collection fields.

    CollectionDetailBlockProps

    FieldRequiredType / constraints
    layoutnostandard, wide, sidebar
    showDateyesboolean
    showFieldsnoarray[string]
    showImageyesboolean
    variantnoarticle, listing, profile
    visibleFieldsnoarray[string]
  • steps

    How it works, Numbered or icon steps for your process.

    StepsBlockProps

    FieldRequiredType / constraints
    headingyesstring
    stepsyesarray[→ StepItem]
    subheadingnostring
  • processBeam

    Process steps with animated beam, How-it-works section with 3-6 numbered steps connected by an animated SVG beam that fills as the section scrolls into view. Each step has a title, description, and optional Lucide icon. Use when the brief is service-led or B2B with a multi-step engagement worth showing; replaces the basic `steps` block when the design direction is more cinematic.

    ProcessBeamBlockProps

    FieldRequiredType / constraints
    headingyesstring
    stepsyesarray[→ ProcessBeamStep]
  • timeline

    Timeline, Milestones, roadmap, or history.

    TimelineBlockProps

    FieldRequiredType / constraints
    headingyesstring
    itemsyesarray[→ TimelineItem]
  • comparison

    Comparison, Side-by-side comparison (not full pricing tables).

    ComparisonBlockProps

    FieldRequiredType / constraints
    headingyesstring
    leftTitleyesstring
    rightTitleyesstring
    rowsyesarray[→ ComparisonRow]
  • comparisonTable

    Comparison table, Full pricing-style comparison table with CTAs per column.

    ComparisonTableBlockProps

    FieldRequiredType / constraints
    columnsyesarray[→ ComparisonTableColumn]
    headingnostring
    rowsyesarray[→ ComparisonTableRow]
    stickyHeadernoboolean

Media

  • imageGallery

    Image gallery, Rows of images with optional captions.

    ImageGalleryBlockProps

    FieldRequiredType / constraints
    columnsyes2, 3, 4
    headingyesstring
    imagesyesarray[→ GalleryImage]
  • youtube

    YouTube video, Responsive embedded video player.

    YoutubeBlockProps

    FieldRequiredType / constraints
    aspectRationo16:9, 4:3, 1:1
    titlenostring
    videoUrlyesstring
  • map

    Google Map, Location map visitors can pan and zoom.

    MapBlockProps

    FieldRequiredType / constraints
    embedUrlnostring
    heightnointeger
    querynostring
    zoomnointeger
  • embed

    Custom embed, Drop in calendars, widgets, or other iframe tools.

    EmbedBlockProps

    FieldRequiredType / constraints
    captionnostring
    htmlyesstring, Iframe HTML; sanitized when rendered.
    maxWidthnointeger
  • marquee

    Scrolling ticker, Infinite horizontal scrolling ticker for logos, badges, or short text.

    MarqueeBlockProps

    FieldRequiredType / constraints
    directionnoleft, right
    itemsyesarray[→ MarqueeItem]
    pauseOnHovernoboolean
    speednoslow, normal, fast
  • logoCloud

    Logo cloud, Partner logos in a row, grid, or infinite marquee with optional grayscale.

    LogoCloudBlockProps

    FieldRequiredType / constraints
    grayscalenoboolean
    itemsyesarray[→ LogoCloudItem]
    speednoslow, normal, fast
    stylenorow, marquee, grid3Rows, infiniteScroll
  • gallery3d

    3D gallery, Image gallery with mosaic, parallax, tilt stack, or coverflow motion.

    Gallery3dBlockProps

    FieldRequiredType / constraints
    effectnoparallax, tiltStack, coverflow, mosaic
    headingnostring
    itemsyesarray[→ Gallery3dItem]

Engagement

  • cta

    Call to action, Single focused pitch with one primary button; solid, outline, or muted section variant.

    CtaBlockProps

    FieldRequiredType / constraints
    bodyyesstring
    buttonHrefyesstring
    buttonIconnostring
    buttonLabelyesstring
    headingyesstring
    variantnosolid, outline, muted
  • testimonial

    Testimonial, Customer quote with name and role.

    TestimonialBlockProps

    FieldRequiredType / constraints
    authoryesstring
    imageUrlnostring, Optional avatar image URL.
    quoteyesstring
    roleyesstring
  • testimonials

    Testimonials, Multiple quotes: grid, featured (first quote large), or marquee layout.

    TestimonialsBlockProps

    FieldRequiredType / constraints
    headingnostring
    itemsyesarray[→ TestimonialsItem]
    layoutnogrid, featured, marquee
  • marqueeTestimonials

    Marquee testimonials (infinite scroll), Infinite horizontal scroll of testimonial cards (two rows moving in opposite directions). Needs 6-24 short quotes with author, role, and optional company/avatar. Reach for this in place of the standard testimonials block when the brief has lots of short customer voices or when the design wants kinetic social proof rather than a static grid.

    MarqueeTestimonialsBlockProps

    FieldRequiredType / constraints
    headingnostring
    itemsyesarray[→ TestimonialsItem]
    speednoslow, normal, fast
  • faq

    FAQ, Accordion-style questions and answers.

    FaqBlockProps

    FieldRequiredType / constraints
    headingyesstring
    itemsyesarray[→ FaqItem]
  • faqAccordion

    FAQ accordion, Native accordion FAQ with grouped, flat, or two-column layout.

    FaqAccordionBlockProps

    FieldRequiredType / constraints
    allowMultiplenoboolean
    headingnostring
    itemsyesarray[→ FaqAccordionItem]
    startOpenIndexnointeger
    stylenogrouped, flat, twoColumn
  • logos

    Logo strip, Partner or press logos: text names and/or optional image URLs per logo.

    LogosBlockProps

    FieldRequiredType / constraints
    headingyesstring
    logosnoarray[→ LogoStripItem]
    namesnoarray[string]
  • pricing

    Pricing, Plans with prices, bullets, and sign-up buttons.

    PricingBlockProps

    FieldRequiredType / constraints
    headingyesstring
    subheadingnostring
    tiersyesarray[→ PricingTier]
  • glowingPricing

    Pricing with animated glow, 1-4 pricing tiers as cards, where the `highlighted` tier carries an animated gradient border glow (defaults to theme primary, override via `glowColor`). Same fields as the standard pricing block (name, price, period, features, button). Use for premium/SaaS pricing where the visual emphasis on the recommended tier should feel alive.

    GlowingPricingBlockProps

    FieldRequiredType / constraints
    glowColornostring
    headingyesstring
    subheadingnostring
    tiersyesarray[→ GlowingPricingTier]
  • newsletter

    Newsletter signup, Email capture section with heading, inline input, and submit button.

    NewsletterBlockProps

    FieldRequiredType / constraints
    buttonIconnostring, Lucide icon id (optional).
    buttonLabelyesstring
    descriptionnostring
    headingyesstring
    inputPlaceholderyesstring
    successMessageyesstring
    variantnoinline, stacked
  • form

    Form (collect responses), Collect leads and messages-submissions land in your dashboard.

    FormBlockProps

    FieldRequiredType / constraints
    descriptionnostring
    fieldsyesarray[→ FormField]
    formNameyesstring, Human-facing title on the page and in submissions (e.g. Contact us). Avoid snake_case internal ids.
    submitIconnostring
    submitLabelyesstring
    successMessageyesstring

Structure

  • divider

    Divider / spacer, Breathing room, line, or spacer between sections.

    DividerBlockProps

    FieldRequiredType / constraints
    heightPxnointeger, Used when variant is blank.
    variantyesline, dotted, blank
  • footer

    Footer, Bottom links, socials, and copyright.

    FooterBlockProps

    FieldRequiredType / constraints
    brandyesstring
    columnsnoarray[→ FooterColumn]
    copyrightYearnointeger
    socialLinksnoarray[→ SocialLink]
    taglineyesstring
  • section

    Custom HTML, Paste or write HTML and optional scoped CSS for layouts that are not covered by standard blocks. Optional AI assist to generate markup.

    SectionBlockProps

    FieldRequiredType / constraints
    cssnostring, Optional scoped CSS; selectors start with .ai-custom-root (or .in-view .ai-custom-root).
    generationModelnostring, Model id used for last generation (informational).
    htmlyesstring, Sanitized HTML fragment; Tailwind and theme CSS variables. No script/iframe/form/button.
    intentnostring, Semantic hint when using optional AI assist on this block.
    labelyesstring, Display name in the editor block list.
    promptnostring, Authoring prompt for generate/regenerate.

Template IDs

GET /api/v1/templates includes previewImageUrl for each id: a site-relative JPEG path to a curated showcase screenshot (for example /images/homepage-showcase-1.jpg).

  • aiSaasAnimated hero, logo marquee, bento grid, sticky feature story, metrics, pricing, and FAQ.
  • financialAdvisorTrust-first layout with process steps, team, testimonials, and a consultation form.
  • lawFirmPractice areas, firm timeline, partners, client outcomes, and consultation CTA.
  • medicalAestheticClinical hero, treatment bento, gallery, membership pricing, and booking form.
  • realEstatePhoto hero, KPI band, listing gallery, bio split, press logos, and inquiry form.
  • executiveCoachPremium hero, client logos, transformation pillars, offers, and application form.
  • agencyBold hero, case-study gallery, process, metrics, team, and project CTA.
  • boutiqueHotelImmersive hero, rooms gallery, amenities, story, map, and booking inquiry.
  • weddingVenueEditorial hero, event gallery, planning steps, packages, FAQ, and tour form.
  • interiorDesignPortfolio-forward hero, project grid, philosophy, process, press, and contact.
  • dtcProductLaunch hero, proof metrics, bento highlights, lifestyle gallery, comparison table.
  • onlineCourseAnimated hero, student metrics, module showcase, curriculum timeline, pricing.
  • fineDiningEditorial hero, menu rich text, photography, press quotes, map, and reservations.
  • luxuryPortfolioSplit hero, curated gallery, about split, testimonial, clients, inquiry form.
  • comingSoonMinimal launch page with stats and newsletter capture.

Errors

Bodies are JSON like { "error": "…" }. Expect 400 for validation, 401 for auth, 403 for ownership or plan limits, 404 when a resource is missing, 409 for conflicts, 429 when throttled, and 502/503 if an upstream integration is unavailable.

AI generation endpoints (/api/v1/sites/generate, /api/v1/sites/generate/plan, /api/v1/sites/generate/from-plan) additionally return a stable reason field next to error. Switch on reason instead of parsing the message. Values: budget_exceeded (402), rate_limited (429), invalid_output (422), upstream_unavailable / unauthorized / upstream_error / unknown (502 / 503), upstream_timeout (504).

Schema names in OpenAPI

Block props use these component schema names: NavbarBlockProps, HeroBlockProps, AnimatedHeroBlockProps, SpotlightHeroBlockProps, AuroraHeroBlockProps, BannerBlockProps, SplitBlockProps, ImageTextBlockProps, BentoFeaturesBlockProps, Bento3dFeaturesBlockProps, FeatureShowcaseBlockProps, FeaturesAccordionBlockProps, TextBlockProps, RichBlockProps, FeaturesBlockProps, StatsBlockProps, MetricsBandBlockProps, TeamBlockProps, CalloutBlockProps, ListBlockProps, CollectionListBlockProps, CollectionDetailBlockProps, StepsBlockProps, ProcessBeamBlockProps, TimelineBlockProps, ComparisonBlockProps, ComparisonTableBlockProps, ImageGalleryBlockProps, YoutubeBlockProps, MapBlockProps, EmbedBlockProps, MarqueeBlockProps, LogoCloudBlockProps, Gallery3dBlockProps, CtaBlockProps, TestimonialBlockProps, TestimonialsBlockProps, MarqueeTestimonialsBlockProps, FaqBlockProps, FaqAccordionBlockProps, LogosBlockProps, PricingBlockProps, GlowingPricingBlockProps, NewsletterBlockProps, FormBlockProps, DividerBlockProps, FooterBlockProps, SectionBlockProps. Shared helpers include NavLinkItem, FormField, SitePageDynamic, and TipTapDoc.

Copy-paste examples

Swap in your real subdomain where you see my-site, use a live API key from the dashboard, and pick the language tab you prefer. If you are already signed in on this site in a browser, your session cookie works too: no header required for the same routes.

Send the Authorization header

Every authenticated route expects Bearer auth unless you rely on a browser session.

Authorization: Bearer YOUR_API_KEY

List sites in the active workspace

Returns every site your current key or session can manage.

curl -sS "https://slatehut.com/api/v1/sites" \
  -H "Authorization: Bearer YOUR_KEY"

Create a site from a single prompt (AI)

Runs planning plus one home page, then persists like POST /api/v1/sites. Uses workspace AI credits.

curl -sS -X POST "https://slatehut.com/api/v1/sites/generate" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"A consulting firm with services, team, and contact form"}'

AI step 1: get a plan JSON you can edit

Non-streaming JSON with a top-level plan object. Review or change it, then call /generate/from-plan.

curl -sS -X POST "https://slatehut.com/api/v1/sites/generate/plan" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"A consulting firm with services, team, and contact form"}'

AI step 2: persist the site from a plan response

POST the same JSON body you received from /generate/plan (it includes the plan field).

curl -sS -X POST "https://slatehut.com/api/v1/sites/generate/from-plan" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d @plan-response.json

Fetch the full site document

Includes pages, blocks, theme, and metadata for one subdomain.

curl -sS "https://slatehut.com/api/v1/sites/my-site" \
  -H "Authorization: Bearer YOUR_KEY"

Update site title and merge theme

Theme keys merge shallowly. Sending pages replaces the entire list when present.

curl -sS -X PUT "https://slatehut.com/api/v1/sites/my-site" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Studio North","theme":{"radius":"md"}}'

List pages and read the home page

Home uses the path segment underscore, not the word home.

curl -sS "https://slatehut.com/api/v1/sites/my-site/pages" \
  -H "Authorization: Bearer YOUR_KEY"

curl -sS "https://slatehut.com/api/v1/sites/my-site/pages/_" \
  -H "Authorization: Bearer YOUR_KEY"

List blocks on the home page

Swap _ for another encoded page path when you target nested routes.

curl -sS "https://slatehut.com/api/v1/sites/my-site/pages/_/blocks" \
  -H "Authorization: Bearer YOUR_KEY"

Upload an image or file

Multipart field name must be file. Use the returned URL inside block props.

curl -sS -X POST "https://slatehut.com/api/v1/media/upload" \
  -H "Authorization: Bearer YOUR_KEY" \
  -F "file=@./photo.jpg"

Import a photo from Unsplash

Requires Unsplash to be configured on the server. Returns url and alt text.

curl -sS -X POST "https://slatehut.com/api/v1/media/unsplash/import" \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"photoId":"UNSPLASH_PHOTO_ID"}'

Check whether a subdomain is free

Helpful before you create a new site through the API.

curl -sS "https://slatehut.com/api/v1/sites/availability?q=my-brand" \
  -H "Authorization: Bearer YOUR_KEY"

Download the live OpenAPI document

Public route: no auth required. Save it for codegen or import into Postman.

curl -sS "https://slatehut.com/api/v1/openapi.json"