GET /v1/sites/:id
Fetch full status and metadata for a single site. Use this to poll for build completion or check the current hosting state.
Cost: Free.
Request
curl https://api.warpweb.ai/v1/sites/8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f \
-H "Authorization: Bearer wwk_<your-key>"Response
While generating:
{
"id": "8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f",
"slug": "brookside-plumbing-a1b2c3",
"business_name": "Brookside Plumbing",
"status": "generating",
"generation_phase": "researching",
"generation_message": "Looking up business...",
"hosting_tier": "free_subdomain",
"created_at": "2026-05-17T14:23:11Z",
"updated_at": "2026-05-17T14:23:42Z"
}After deploy:
{
"id": "8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f",
"slug": "brookside-plumbing-a1b2c3",
"business_name": "Brookside Plumbing",
"status": "complete",
"deployment_url": "https://brookside-plumbing-a1b2c3.warpweb.app",
"hosting_tier": "free_subdomain",
"last_refreshed_at": "2026-05-17T14:24:38Z",
"form_webhook_url": null,
"input": {
"mapsUrl": "https://www.google.com/maps/place/Brookside+Plumbing/@30.27,-97.74,17z",
"businessName": "Brookside Plumbing",
"received_at": "2026-05-17T14:23:11Z"
},
"created_at": "2026-05-17T14:23:11Z",
"updated_at": "2026-05-17T14:24:38Z"
}After deploy with visual-review warnings:
When the build completed and deployed but the visual-review rubric flagged advisory issues (see Build pipeline → ship-with-warnings below), the response carries status: "complete_with_warnings" and a warnings array describing what was flagged. The site is live and usable — these are advisory hints you can act on via a follow-up revision.
{
"id": "8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f",
"slug": "brookside-plumbing-a1b2c3",
"business_name": "Brookside Plumbing",
"status": "complete_with_warnings",
"deployment_url": "https://brookside-plumbing-a1b2c3.warpweb.app",
"hosting_tier": "free_subdomain",
"warnings": [
{
"rule": "hero-is-wedge-not-list",
"severity": "error",
"page": "index.html",
"viewport": "desktop",
"description": "Hero shows 6 service tiles instead of one focused wedge.",
"fix_via_revision": {
"endpoint": "POST /v1/sites/8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f/revisions",
"suggested_prompt": "Hero must show ONE focused problem statement above the fold. NO service grids, NO icon-and-label tiles, NO badge rows of certifications. The hero is a wedge, not a list — move the service grid below the hero."
}
}
],
"created_at": "2026-05-17T14:23:11Z",
"updated_at": "2026-05-17T14:24:38Z"
}After custom domain attach:
{
"id": "8f3c2a1b-5d47-4c9e-b820-1f8a3e7d9c4f",
"slug": "brookside-plumbing-a1b2c3",
"business_name": "Brookside Plumbing",
"status": "complete",
"deployment_url": "https://brooksideplumbing.com",
"hosting_tier": "paid_custom_domain",
"form_webhook_url": "https://api.yourapp.com/webhooks/warpweb-leads",
"created_at": "2026-05-17T14:23:11Z",
"updated_at": "2026-05-17T15:42:11Z"
}Key fields
| Field | Type | When present |
|---|---|---|
id | string | always — the site UUID. |
slug | string | always — URL-safe slug used in the subdomain. |
business_name | string | always — the value you passed at create time. |
status | string | always — one of generating, complete, complete_with_warnings, failed. Treat complete and complete_with_warnings as equivalent for “the site is deployed and live” — the warnings are advisory. |
warnings | array | present only when status = complete_with_warnings. See Ship-with-warnings below. |
generation_phase | string | during generating — one of researching, research_review, generating, reviewing, deploying, complete, failed. In auto mode (the default), research_review is brief or unobserved; in manual mode (review:"manual" on create) the site pauses there until you call POST /v1/sites/:id/approve-research. |
generation_message | string | during generating — human-readable progress message. |
deployment_url | string | once status = complete. The canonical URL — subdomain or custom domain. |
hosting_tier | string | always — free_subdomain or paid_custom_domain. |
last_refreshed_at | string | free-tier sites only. ISO 8601. See Pricing → 7-day refresh. |
pause_state | string | free-tier sites only. "active" when the site is live; "paused" when the 7-day refresh window has elapsed and visitors are seeing the paused-site placeholder. Paid-tier sites are always active and may omit the field. Call POST /v1/sites/:id/refresh to un-pause. |
form_webhook_url | string | null | the configured webhook URL, or null if forms deliver to contact_email only. |
last_error | string | only when status = failed. Human-readable error message. |
usage | object | always — aggregate AI spend for the initial generation phase (revisions are surfaced separately on each revision’s site.revision_complete webhook payload). Shape: { credits_charged: number | null, tokens_in: number, tokens_out: number, cost_usd: number }. credits_charged is null here because per-call deductions land on the credit ledger via deductUsageCredits at end-of-build; this field surfaces the raw token + USD aggregate so you can render “this site cost ~$0.42 in AI”. See Error shapes → defensive parsing for the recommended client-side handling. |
input | object | null | always — the build-input audit trail: a snapshot of what you originally passed to POST /v1/sites. Shape: { mapsUrl?, placeId?, businessName?, location?, facebookUrl?, existingSiteUrl?, received_at }. Only non-empty fields appear; received_at is always present when the object is non-null. Useful when a build came out wrong (e.g. Google Places returned the wrong duplicate profile for a business with two listings) — surface “Built from <url>” in your UI so the operator can retry with a different URL. null on legacy sites built before 2026-05-25 that haven’t been backfilled. Note: the underlying DB column is named input_signal; the API response renames to input for terseness. |
The full site row includes additional fields (pages_project_name, originated_via, etc.). Treat fields not documented here as internal and subject to change.
Ship-with-warnings
Warpweb’s contract is “POST → site.” Every build that completes research successfully MUST produce a deployed URL — we never leave you with a no-site outcome you can’t act on.
When the visual-review pipeline (a vision-model gate that screenshots the rendered site and grades it against a polish rubric) flags issues that 3 progressive-steering attempts can’t clear, the build ships anyway with:
status: "complete_with_warnings"instead of"complete".- A
warnings[]array on the GET response describing each finding, including the page + viewport it was observed on and afix_via_revision.suggested_promptyou can drop intoPOST /v1/sites/:id/revisionsto iterate.
The site is live in this state — deployment_url works, your customer can use it, your billing should treat it the same as complete. The warnings exist so you can choose to iterate (via a revision) or accept the result.
The same warnings[] array is included on the site.complete webhook payload so receivers can surface them in your UI without re-polling.
Catastrophic rendering failures (broken HTML, JS errors, 404s) are still terminal — those produce status: "failed" from the earlier typecheck loop and are not subject to ship-with-warnings.
Polling pattern
If you can’t run a webhook receiver, poll this endpoint every 2–5 seconds while status is generating. Stop when it flips to complete, complete_with_warnings, or failed. For production, prefer lifecycle webhooks — they fire within seconds of the underlying state change and avoid wasted polling.
Errors
| Status | Body | Cause |
|---|---|---|
| 404 | { "error": "Site not found" } | No site with that ID belongs to your account. (Also returned for non-existent IDs to avoid leaking which sites exist.) |