Domain preview
Turn a domain your visitor just searched into a live website preview in under five seconds — then, if they buy, into their first build.
https://api.swarmz.net/functions/v1/platform-domain-previewWhen a visitor searches a domain on your storefront — bakery-nord.com, mugs.shop — this endpoint returns a finished-looking website preview for that domain within five seconds (typically three to four, about one of which is the request itself). Show it next to the domain's price to sell the site together with the name. If the visitor buys the domain and a Swarmz plan, pass the preview's id to Create a tenant and the preview becomes the customer's first build: the editor opens on their first login with the complete site being generated in the same look.
How it stays fast
The domain name is parsed and classified instantly (business type, style world). One small, fast model call writes the copy brief under a hard 4.5 s cutoff; if the model is slow or unavailable, a deterministic brief answers instead, so the endpoint never exceeds its budget. The page is assembled from our section library — one of six layouts chosen by the kind of business (a store with product cards and a cart, a food menu with prices, a services price list with a booking card, property or trip listings behind a search bar, a portfolio, or a software page with pricing), with real stock photography — so the HTML is always valid, escaped and script-free, and two domains never look the same. The same domain for your account is served from cache for seven days.
Parameters
Prop
Type
Response
{
"ok": true,
"preview_id": "2b1c3d4e-5f60-4a7b-8c9d-0e1f2a3b4c5d",
"domain": "bakery-nord.com",
"preview_url": "https://api.swarmz.net/functions/v1/platform-domain-preview?id=2b1c3d4e-5f60-4a7b-8c9d-0e1f2a3b4c5d",
"category": "bakery",
"world": "butter-crumb",
"brief": {
"business_name": "Bakery Nord",
"tagline": "Baked fresh every morning",
"hero_headline": "Real bread, real butter, baked before sunrise",
"hero_sub": "Sourdough loaves, flaky croissants and celebration cakes …",
"cta": "Order for pickup",
"cta_secondary": "See the menu",
"nav": ["Menu", "Order", "Visit"],
"features": [{ "title": "Daily loaves", "body": "…" }, { "title": "Pastry counter", "body": "…" }, { "title": "Cakes to order", "body": "…" }],
"quote": "The croissants alone are worth the detour.",
"quote_by": "Marta K., regular since opening",
"palette": { "bg": "#fbf6ee", "fg": "#2b2118", "accent": "#c2572b", "muted": "#7a6a5c", "card": "#ffffff" },
"fonts": { "display": "Fraunces", "body": "Albert Sans" },
"mood": "warm",
"source": "model"
},
"html": "<!doctype html>…",
"source": "model",
"generated_ms": 2140,
"cached": false,
"created_at": "2026-10-08T12:00:00.000Z",
"expires_at": "2026-10-15T12:00:00.000Z"
}| Field | Type | Description |
|---|---|---|
preview_id | uuid | Keep this. It is what you pass to platform-create as preview_id when the visitor buys. |
preview_url | string | The preview page on api.swarmz.net, embeddable in an <iframe> on any site (no auth, unguessable id, no scripts, frame-ancestors *, cached one hour). On the staging project there is no custom API domain and Supabase serves HTML as plain text there — use html with srcdoc when testing against staging. |
html | string | The same page inline (~8 KB) for srcdoc or server-side rendering. Self-contained apart from a Google Fonts stylesheet. |
brief | object | The structured brief the page was rendered from — useful for a text teaser next to the frame ("Bakery Nord — Baked fresh every morning"). Includes items: the products, dishes, services, listings, projects or plans the page shows, with prices in the domain's currency. |
photos | array | The photos on the page (src, alt, page), from Pexels. |
category | string | The business type inferred from the name (bakery, shop, legal, tech, … or business when nothing matched). |
source | "model" | "fallback" | Whether the copy came from the model or the deterministic fallback (timeout, outage or your daily model cap). The page is complete either way. |
cached | boolean | Served from the seven-day cache for this domain. |
billing | object | { credits, metered } — the credits metered to your account for this call (0 for cached and fallback previews). |
generated_ms | number | Server time spent, for your own monitoring. |
Showing it
<iframe src="{preview_url}" title="Your website on bakery-nord.com"
loading="lazy" sandbox="" style="width:100%;aspect-ratio:16/10;border:0;border-radius:12px"></iframe>An empty sandbox attribute is fine: the page runs no scripts. Scale it down with CSS transform: scale(.6) on a fixed-width wrapper for a card-sized thumbnail.
From preview to first build
Existing customer buying another site? Pass the same preview_id to SSO instead: the brief is composed server-side and parked on the workspace you sign them into, exactly like initial_prompt, and the editor opens on the build.
New tenant
When the visitor checks out, call Create a tenant with the same preview_id:
{ "external_ref": "whmcs:1234", "whu": { "email": "owner@bakery-nord.com" }, "plan_code": "starter", "preview_id": "2b1c3d4e-…" }The brief is turned into the first-build prompt — the preview URL is given to the AI as the design reference, with the instruction to keep its palette, fonts and copy and expand it into the complete multi-page site a business of that kind needs (menu, ordering, contact, …). It is parked exactly like initial_prompt: nothing is generated and no credits are spent until the customer's first login, when the editor opens on the build already running. If you send both initial_prompt and preview_id, initial_prompt wins. The response carries preview_id and preview_consumed: true; a preview can be consumed once.
Limits
| Limit | Value |
|---|---|
| Rate | 120 requests / minute per key, 240 / minute per IP (domain search is bursty). |
| Daily model budget | 2,000 uncached previews per account per UTC day. Beyond it, previews are still instant but source is fallback. |
| Cache | Seven days per (account, domain). refresh: true bypasses it. |
| Retention | Every preview row is deleted 7 days after it was generated (nightly purge). The preview page and the preview_id stop working then; a purchase that comes later simply omits preview_id. |
| Billing | Each model-backed preview is metered to your platform account as swarmz_credits, computed from the model's actual cost (about 0.11 credits each) and invoiced with your tenants' usage. Cached hits and fallback previews cost nothing. Accounts without a card on file get fallback previews only. |
Errors
| Status | error | Meaning |
|---|---|---|
| 400 | invalid_domain | Not a registrable domain name. |
| 401 | unauthorized | Missing or invalid platform key. |
| 404 | — | GET ?id= for an unknown id. |
| 429 | rate_limited | See Rate limits. |
On platform-create, an unknown or foreign preview_id returns 404 preview_not_found before anything is provisioned, and a malformed one 400 invalid_preview_id.
Initial prompt
Capture the first build prompt on your own storefront and have the customer's workspace open mid-build on their first login. Works through the WHMCS module's Prompt Box or a single field on platform-create.
Change a tenant's plan
Move a tenant onto a different named plan, or patch its raw entitlements. Maps to WHMCS ChangePackage. Addressed by tenant_id.