Sites

Create an empty site

Creates an empty site in the active workspace and seeds its brief. Nothing is published until you publish. By default a slug that another account holds is auto-suffixed ({slug}-{adjective}-{noun}); the response says so with slugAdjusted: true, so always use the returned slug afterwards.

Free-site capacity is base + perPaid × paidSites in the workspace (defaults 10 + 10 per paid site; fleet and per-workspace overrides exist). Only free-tier sites count toward usage; past the effective max the request answers 403 free_site_limit. A key limited to specific sites, and a guest token, can't create sites.

post/api/v1/sites

Request

  • Base URL: https://api.dotsy.ai
  • URL: https://api.dotsy.ai/api/v1/sites
  • Auth: HTTP bearer

Headers

X-Dotsy-Workspacestring

Org id or slug to act as for this request (session/MCP user actors only — ignored for pga_ keys). Validated against the caller's own memberships (id match first, then slug); 403 if not a member. Takes precedence over session.activeOrganizationId and the auto-provisioned home-workspace fallback.

Request body

slugstring required

The address you want: {slug}.dotsy.site. Lowercase letters, numbers and hyphens, 1 to 63 characters. A slug that looks like a site id (a UUID) or is reserved for the platform is refused.

titlestring

The site's display name, up to 200 characters.

keyConvention'flat' | 'directory'

How content keys map to URLs. flat (default): about.html serves at /about. directory: about/index.html serves at /about.

purposestring

One sentence on what the site is for, 5 to 280 characters. It seeds the site brief. Left out, it is inferred from the title or slug.

onSlugTaken'fail' | 'auto-suffix' | 'merge'

What to do when another account already has the slug. auto-suffix (default) picks {slug}-{adjective}-{noun} and answers slugAdjusted: true. fail answers 409 slug_taken instead. merge reuses a slug you already own, where the other policies answer 409 slug_taken_self.

editingMode'live' | 'staged'

How the editor's Save behaves. live (default) publishes each save right away. staged keeps saves as drafts until you publish. Writes made through the API always stage, whatever this says.

Example request

{
  "slug": "acme-studio",
  "title": "Acme Studio",
  "purpose": "Show Acme's work and bring in new client enquiries."
}

Response

The site exists. It is empty and unpublished.

slugstring required

The slug the site was created with. It differs from requestedSlug when slugAdjusted is true.

requestedSlugstring required

The slug you asked for.

slugAdjustedboolean required

True when the slug was taken and a variant was picked.

titlestring nullable required

The title you sent, or null.

keyConvention'flat' | 'directory' required
editingMode'live' | 'staged' required
createdAtnumber required

Creation time, Unix ms.

createdtrue required
publicUrlstring required
liveUrlstring required

Same as publicUrl.

liveReadyboolean required

False: nothing is published yet.

Example response

{
  "slug": "acme-studio",
  "requestedSlug": "acme-studio",
  "publicUrl": "https://acme-studio.dotsy.site/",
  "liveUrl": "https://acme-studio.dotsy.site/"
}

Changes

No recorded changes to this operation across all 1 revision of this API.