Opening a site
While Cactal resolves your site and access, it shows a loading indicator. Inside the editor, Content Management, Assets, Context, Analytics, Activity, and Settings use loading layouts that match the selected tab. Settings shows an abstract skeleton until its initial data loads. These placeholders indicate that the page is still loading, not that the site or its content is empty.The website resource
GET /v1/websites/find?websiteId=... returns the full resource:
List responses (
GET /v1/websites) carry faviconUrl too and add three fields per item: primaryHostname, the primary custom domain hostname when one is set, otherwise the platform hostname; organizationSlug, the owning organization’s URL slug; and shared, true when your access comes from a direct editor grant outside your organization memberships. Trash listings (GET /v1/websites?status=deleted) instead add deletedAt (when the website entered the trash) and purgeEligibleAt (when it becomes permanently purgeable) to each item.
Lifecycle
1
Create
POST /v1/websites accepts either { "organizationId": "...", "name": "..." } or a creation prompt, plus an optional slug. Prompt-based creation returns immediately as Untitled site; after an agent run is accepted, the dashboard requests a name in the background and retries after later accepted runs while the temporary name remains. An explicit brand or project name in the brief is preserved; otherwise Cactal chooses a generic description from the stated purpose instead of inventing a brand. The first generated name atomically aligns the display name, an available organization slug, and an available platform hostname. The hostname uses the slug when globally available or adds a short suffix when needed. The website starts at headVersion: 1 and publishedVersion: null. Creating websites is free on every plan.2
Edit
Source edits go through an edit lease and advance
headVersion. Drafts are visible on the draft-- preview host, never on the live site.3
Publish
POST /v1/websiteSourceCode/head/publish runs the quality gate and build, then sets publishedVersion. Publishing to the platform domain is free on every plan. See Publishing.4
Serve
The published version always serves on the platform subdomain, free on every plan, and on every
active custom domain. A site counts toward your plan when an organization owner enables custom domains for it. See Domains.Listing and searching
GET /v1/websites paginates with cursor and limit (default 20, maximum 100) and returns { items, nextCursor }. Optional parameters:
Keys without organization-wide access only see the websites they are scoped to.
Addressing a website by slug
Every website has aslug, and its organization has a slug too, so you can resolve a website from the two slugs instead of its id:
GET /v1/websites/find accepts either websiteId or the organizationSlug + websiteSlug pair and returns the website along with canManageSchema and canManageDomains flags for the caller, or 404 when either slug does not match an active website you can access. Slugs are lowercase, may contain letters, digits, and hyphens, and stay unique among active websites in the organization.
Rename
PATCH /v1/websites/{websiteId} updates the display name and, when you include a slug, the URL slug. Names are trimmed and must be 1–200 characters. After the first automatic naming step, renaming changes nothing about hostnames, versions, or content: the platform subdomain remains stable unless it is changed separately in domain settings.
Soft delete and restore
DELETE /v1/websites/{websiteId} moves the website to the trash for 30 days; the deletion time and purge deadline appear as deletedAt and purgeEligibleAt in GET /v1/websites?status=deleted. The delete marks the website alone. Its CMS content, assets, source history, and deployments keep their existing lifecycle state but become inaccessible through the deleted parent. The site stops serving immediately: visitors get a 404, and the website disappears from GET /v1/websites.
Custom domains are the exception: trashing a website disables custom domains automatically, which disconnects each domain, stops its charge, and releases each hostname for another website to claim. The platform subdomain is untouched.
Deleted websites remain listable through GET /v1/websites?status=deleted (requires organizationId) during the restore window. They stop appearing once the deadline passes, even if permanent cleanup is waiting for a retry. Deleting an already-deleted website returns 404. POST /v1/websites/{websiteId}/restore returns the website to the active list before the deadline; restoration is rejected once the restore window expires. An hourly cleanup job permanently removes expired websites, CMS records, source history, domains, deployments, asset records, references, and blobs. This cleanup is irreversible.
Restoring the website makes all previously active child content available again without reviving collections, items, or assets that were deleted independently before the website entered trash. Custom domains do not come back either: the website is restored with custom domains disabled, so nothing silently re-bills. It serves on its platform subdomain until an owner re-enables custom domains, after which you add and verify domains again from scratch. See Domains.
Transfer between organizations
POST /v1/websites/{websiteId}/transfer with { "targetOrganizationId": "..." } moves the website — content, versions, domains, and history — to another organization. The target must be a different, active organization.
If the website has custom domains enabled, the target organization must have active billing and unused paid capacity; otherwise the transfer fails with 403 (Billing must be active to receive this website or This organization has reached its website capacity). Websites with custom domains disabled transfer without a billing check, even when published. See Plans and limits.
Constraints
Next steps
Source code
The file model and edit leases behind
headVersion.Publishing
How head becomes the published version, and how to roll back.