API ReferenceGET /v1/sites/:id

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

FieldTypeWhen present
idstringalways — the site UUID.
slugstringalways — URL-safe slug used in the subdomain.
business_namestringalways — the value you passed at create time.
statusstringalways — 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.
warningsarraypresent only when status = complete_with_warnings. See Ship-with-warnings below.
generation_phasestringduring 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_messagestringduring generating — human-readable progress message.
deployment_urlstringonce status = complete. The canonical URL — subdomain or custom domain.
hosting_tierstringalways — free_subdomain or paid_custom_domain.
last_refreshed_atstringfree-tier sites only. ISO 8601. See Pricing → 7-day refresh.
pause_statestringfree-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_urlstring | nullthe configured webhook URL, or null if forms deliver to contact_email only.
last_errorstringonly when status = failed. Human-readable error message.
usageobjectalways — 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.
inputobject | nullalways — 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 a fix_via_revision.suggested_prompt you can drop into POST /v1/sites/:id/revisions to 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

StatusBodyCause
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.)