API ReferencePOST /v1/sites/:id/logo

POST /v1/sites/:id/logo

Replace the site’s nav + footer logo on a site that’s already deployed.

This is a pure file swap — the existing favicon stays as-is (call POST /v1/sites/:id/favicon separately if you also want a new favicon), and the brand color palette / overall style stay unchanged. If you want the palette to chase the new logo, follow up with a revision like "match my colors to my new logo".

Cost: free — deterministic operation, no LLM call.

Why this exists

Revisions are HTML-content edits driven by the AI; they cannot swap an asset file. This endpoint is the only way to point a deployed site at a different logo image without rebuilding from scratch.

Request

curl -X POST https://api.warpweb.ai/v1/sites/<site-id>/logo \
  -H "Authorization: Bearer wwk_..." \
  -H "Content-Type: application/json" \
  -d '{ "source": { "url": "https://example.com/my-logo.png" } }'

Body

FieldTypeRequiredDescription
source.urlstringone of (url, sitePhotoId)Public http(s):// URL of the new logo image. Fetched server-side via the SSRF-safe downloader; private IPs and non-image content types are rejected.
source.sitePhotoIdstring (uuid)one of (url, sitePhotoId)UUID of a row from this site’s site_photos catalog. Useful to promote a logo the classifier already found (subject="logo_or_brand") without re-uploading. Cross-site reuse is blocked with 403 — the row must belong to this site.

Response (success)

{
  "ok": true,
  "logoPath": "images/logo.png",
  "deployedUrl": "https://acme-plumbing-abc123.pages.dev",
  "hint": "Logo swapped. The existing favicon was NOT regenerated; call POST /v1/sites/:id/favicon if you want a new favicon. Brand colors / style also unchanged — follow up with POST /v1/sites/:id/revisions (\"match my colors to my new logo\") if you want the palette to chase the logo."
}
FieldDescription
logoPathRelative path to the new logo on the deployed site (images/logo.<ext>). Extension reflects the source content-type — png / svg / jpg / webp.
deployedUrlCloudflare Pages preview URL of the freshly redeployed site. Custom domains aliased to this project pick up the change automatically.
hintReminder of what was NOT changed by this call (favicon, brand colors).

Errors

StatusBodyCause
400{ "error": "source.url or source.sitePhotoId required" }Body missing both source variants.
400{ "error": "source.url must be http(s)://" }URL scheme isn’t http or https.
400{ "error": "logo_download_failed", "detail": "..." }SSRF guard rejected the URL, network error, or response wasn’t an image.
403{ "error": "sitePhotoId does not belong to this site" }The given sitePhotoId exists but belongs to a different site.
404{ "error": "sitePhotoId not found" }No row matches the given UUID.
404{ "error": "site_not_found" }Site id doesn’t exist, OR the API key’s user doesn’t own this site (the two cases are masked to avoid leaking ownership).
500{ "error": "logo_swap_failed", "detail": "..." }Unexpected server-side failure (image write, deploy, etc.). Safe to retry — operation is idempotent.