Skip to content

Site Builder

Base URL: /v1

All endpoints under /sitebuilder/* require authentication via Bearer token unless marked Public.


GET /v1/sitebuilder/projects

Returns all projects owned by the authenticated user, ordered by updated_at descending.

Response 200

{
"projects": [
{
"id": "uuid",
"user_id": "uuid",
"name": "My Website",
"description": "Portfolio site",
"settings": {},
"is_published": false,
"published_slug": null,
"updated_at": "2026-03-30T12:00:00Z",
"created_at": "2026-03-28T08:00:00Z"
}
]
}
FieldTypeDescription
idstringUnique project identifier (UUID)
user_idstringOwner user ID
namestringProject name
descriptionstringProject description
settingsobjectProject-level settings
is_publishedbooleanWhether the project is currently live
published_slugstringURL slug of the published site, or null
updated_atstringISO 8601 timestamp of last update
created_atstringISO 8601 timestamp of creation

POST /v1/sitebuilder/projects

Creates a new project. Automatically creates a “Home” page with slug index. If template_id is provided, all pages from the template project are copied into the new project.

Request Body

FieldTypeRequiredDescription
namestringYesProject name
descriptionstringNoProject description
template_idstringNoUUID of an existing project to clone pages from
{
"name": "My Portfolio",
"description": "Personal portfolio site",
"template_id": "d4f8a1b2-..."
}

Response 201

{
"project": {
"id": "a1b2c3d4-...",
"user_id": "uuid",
"name": "My Portfolio",
"description": "Personal portfolio site",
"settings": {},
"is_published": false,
"published_slug": null,
"updated_at": "2026-03-30T12:00:00Z",
"created_at": "2026-03-30T12:00:00Z"
}
}

GET /v1/sitebuilder/projects/{id}

Returns the project and all its pages. Returns 404 if the project does not exist or is not owned by the authenticated user.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Response 200

{
"project": {
"id": "a1b2c3d4-...",
"user_id": "uuid",
"name": "My Portfolio",
"description": "Personal portfolio site",
"settings": {},
"is_published": true,
"published_slug": "my-portfolio",
"updated_at": "2026-03-30T12:00:00Z",
"created_at": "2026-03-28T08:00:00Z",
"pages": [
{
"id": "page-uuid",
"name": "Home",
"slug": "index",
"html": "<h1>Hello</h1>",
"css": "h1 { color: blue; }",
"js": "",
"metadata": {},
"created_at": "2026-03-28T08:00:00Z"
}
]
}
}

Error Responses

StatusDescription
404Project not found or not owned by user

PATCH /v1/sitebuilder/projects/{id}

Updates allowed fields on the project. Automatically sets updated_at to the current timestamp.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Request Body

FieldTypeRequiredDescription
namestringNoNew project name
descriptionstringNoNew description
settingsobjectNoUpdated settings
{
"name": "Updated Name",
"settings": { "theme": "dark" }
}

Response 200

Returns the updated project object.


DELETE /v1/sitebuilder/projects/{id}

Permanently deletes the project. Cascading delete — all associated pages and form submissions are also removed.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Response 200

{
"message": "Project deleted"
}

POST /v1/sitebuilder/projects/{id}/clone

Creates a new project by copying all pages, metadata, description, and settings from the source project.

Path Parameters

ParameterTypeDescription
idstringSource project UUID

Request Body

FieldTypeRequiredDescription
namestringYesName for the cloned project
{
"name": "Portfolio v2"
}

Response 201

Returns the newly created project object with all cloned pages.

Error Responses

StatusDescription
404Source project not found

POST /v1/sitebuilder/projects/{id}/pages

Creates a new page within a project. If slug is not provided, it is auto-generated from the page name: lowercased, non-alphanumeric characters replaced with hyphens. Updates the parent project’s updated_at timestamp.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Request Body

FieldTypeRequiredDefaultDescription
namestringYesPage name
slugstringNoautoURL slug (auto-generated from name if omitted)
htmlstringNo""Page HTML content
cssstringNo""Page CSS styles
jsstringNo""Page JavaScript
{
"name": "About Us",
"html": "<h1>About</h1><p>We build things.</p>",
"css": "h1 { font-size: 2rem; }"
}

Auto-generated slug for the above: about-us

Response 201

{
"page": {
"id": "page-uuid",
"name": "About Us",
"slug": "about-us",
"html": "<h1>About</h1><p>We build things.</p>",
"css": "h1 { font-size: 2rem; }",
"js": "",
"metadata": {},
"created_at": "2026-03-30T12:00:00Z"
}
}

PATCH /v1/sitebuilder/pages/{id}

Updates fields on an existing page. Also updates the parent project’s updated_at timestamp.

Path Parameters

ParameterTypeDescription
idstringPage UUID

Request Body

FieldTypeRequiredDescription
namestringNoPage name
slugstringNoURL slug
htmlstringNoPage HTML content
cssstringNoPage CSS styles
jsstringNoPage JavaScript
metadataobjectNoPage metadata
{
"html": "<h1>Updated About</h1>",
"css": "h1 { color: red; }",
"metadata": { "seo_title": "About Us" }
}

Response 200

Returns the updated page object.


DELETE /v1/sitebuilder/pages/{id}

Deletes a page. Updates the parent project’s updated_at timestamp.

Path Parameters

ParameterTypeDescription
idstringPage UUID

Response 200

{
"message": "Page deleted"
}

POST /v1/sitebuilder/projects/{id}/publish

Publishes the project as a live site. If the project has already been published, the existing publication is updated (upsert on project_id). Sets is_published to true and assigns the published_slug.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Request Body

FieldTypeRequiredDescription
slugstringNoCustom slug for the published URL (auto-generated from project name if omitted)
{
"slug": "my-portfolio"
}

Response 200

{
"published": {
"id": "pub-uuid",
"project_id": "a1b2c3d4-...",
"user_id": "uuid",
"slug": "my-portfolio",
"published_at": "2026-03-30T12:00:00Z"
},
"site_url": "/v1/sites/my-portfolio"
}

GET /v1/sites/{slug}

Serves the index page of the published site as a full HTML document.

Path Parameters

ParameterTypeDescription
slugstringPublished site slug

Response 200

Returns text/html — the rendered index page with embedded CSS and JS.

Error Responses

StatusDescription
404Published site not found

GET /v1/sites/{slug}/{pageName}

Serves a specific page of the published site as a full HTML document.

Path Parameters

ParameterTypeDescription
slugstringPublished site slug
pageNamestringPage slug

Response 200

Returns text/html — the rendered page with embedded CSS and JS.

Error Responses

StatusDescription
404Site or page not found

POST /v1/sitebuilder/ai/generate-text

Generates text content using GPT-4o-mini. Subject to a monthly limit of 100,000 tokens per user.

Request Body

FieldTypeRequiredDefaultDescription
promptstringYesThe text generation prompt
max_tokensintegerNo500Maximum tokens to generate
{
"prompt": "Write a short hero section tagline for a freelance designer portfolio.",
"max_tokens": 100
}

Response 200

{
"text": "Crafting digital experiences that leave a lasting impression.",
"tokens_used": 12
}

Error Responses

StatusDescription
429Monthly token limit exceeded (100,000 tokens/month)

POST /v1/sitebuilder/ai/modify-text

Modifies existing text using AI. Maximum 1,000 tokens per request. Subject to a monthly limit of 100,000 tokens per user.

Request Body

FieldTypeRequiredDescription
textstringYesThe text to modify
operationstringYesOne of the allowed operations (see below)
target_languagestringIf translateTarget language (e.g. "Spanish", "French")
tonestringIf change_toneDesired tone (e.g. "professional", "casual")

Allowed Operations

OperationDescription
simplifySimplify the text for easier reading
shortenMake the text more concise
lengthenExpand the text with more detail
fix_spellingCorrect spelling and grammar errors
change_toneRewrite in a different tone (requires tone)
translateTranslate to another language (requires target_language)
{
"text": "Our synergistic approach leverages cross-functional paradigms.",
"operation": "simplify"
}

Response 200

{
"text": "Bienvenido a nuestro sitio web.",
"tokens_used": 8
}

Error Responses

StatusDescription
400Invalid operation or missing required field (target_language or tone)
429Monthly token limit exceeded

POST /v1/sitebuilder/ai/generate-image

Generates an image using DALL-E-3. Subject to a monthly limit of 50 images per user.

Request Body

FieldTypeRequiredDefaultDescription
promptstringYesImage generation prompt
sizestringNo1024x1024Output image dimensions

Allowed Sizes

ValueDimensions
1024x1024Square (default)
1024x1792Portrait
1792x1024Landscape
{
"prompt": "A minimalist hero image of a mountain landscape at sunset",
"size": "1792x1024"
}

Response 200

{
"image_url": "https://oaidalleapiprodscus.blob.core.windows.net/..."
}

Error Responses

StatusDescription
429Monthly image limit exceeded (50 images/month)

POST /v1/sitebuilder/projects/{id}/export/download

Creates a ZIP archive containing all project pages as standalone HTML files. The ZIP is uploaded to Supabase storage and a signed download URL is returned. The URL expires after 1 hour.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Response 200

{
"download_url": "https://your-supabase-url.supabase.co/storage/v1/object/sign/exports/..."
}

Error Responses

StatusDescription
404Project not found

POST /v1/sitebuilder/projects/{id}/export/ftp

Exports all project pages as HTML files to a remote FTP server.

Path Parameters

ParameterTypeDescription
idstringProject UUID

Request Body

FieldTypeRequiredDefaultDescription
hoststringYesFTP server hostname
portintegerNo21FTP server port
usernamestringYesFTP username
passwordstringYesFTP password
remote_pathstringNo"/"Remote directory to upload into
{
"host": "ftp.example.com",
"port": 21,
"username": "deploy",
"password": "s3cur3p@ss",
"remote_path": "/public_html"
}

Response 200

{
"message": "FTP export complete",
"files_uploaded": 5
}

Error Responses

StatusDescription
400Missing required fields (host, username, or password)
404Project not found

POST /v1/sitebuilder/forms

Handles form submissions from published sites. Any visitor can submit data to a project’s form.

Request Body

FieldTypeRequiredDescription
project_idstringYesUUID of the project the form belongs to
form_idstringYesIdentifier for the specific form
dataobjectYesKey-value pairs of form field submissions
{
"project_id": "a1b2c3d4-...",
"form_id": "contact-form",
"data": {
"name": "Jane Doe",
"email": "jane@example.com",
"message": "I'd like to discuss a project."
}
}

Response 201

{
"submission": {
"id": "sub-uuid",
"project_id": "a1b2c3d4-...",
"form_id": "contact-form",
"data": {
"name": "Jane Doe",
"email": "jane@example.com",
"message": "I'd like to discuss a project."
},
"created_at": "2026-03-30T12:30:00Z"
}
}