Sites API
Manage the website identity and widget configuration used by your workspace.
Access
These dashboard endpoints require an authenticated agent session JWT in Authorization: Bearer. A Verify, messaging, or MCP connection key does not grant access to them. Requests stay within the authenticated workspace.
Listing and reading sites require authentication. Creating or changing a site requires admin access.
List and read sites
GET /api/v1/sites returns { sites: [...] } for the current workspace. It is not cursor-paginated and has no limit filter. GET /api/v1/sites/:id returns { site: {...} }; a site outside the workspace is not found.
curl 'https://app.message.com/api/v1/sites' \
-H 'Authorization: Bearer YOUR_AGENT_JWT'Create a site
POST /api/v1/sites takes name (1–120 characters) and optional domain. It returns HTTP 201 with { site: {...} }, including the generated embedId. If onboarding has bound the workspace to a website, a different domain is rejected with website_domain_locked. An unfinished required website may return website_domain_required.
Update site settings
PATCH /api/v1/sites/:id accepts name, domain, allowedDomains, primaryColor, position (left or right), welcomeMessage (up to 500 characters), businessHours and preChatForm. It returns { site: {...} }. A bound onboarding website also constrains domain and allowedDomains changes. There is no expectedVersion field or stale-version response on this endpoint.
Widget configuration
GET /api/v1/sites/:id/widget-config reads the widget settings. PATCH at the same path updates appearance and welcome fields, including companyName, welcomeHeading, welcomeSubtitle, primaryColor, position, theme (light, dark or match), companyLogo, launcherLogoUrl and bottomSpacing (0–200). Use Settings → Chat to preview supported form and hours structures before integrating them.
Keep credentials on your server
The public embedId is used by the widget installation snippet. It is not an agent credential. Never place an agent session JWT or private connection key in website code. The widget uses its separate visitor connection flow.
Errors
Invalid request bodies return 400 invalid_body. Missing sites return 404 not_found. Domain restrictions return 400 with website_domain_locked or website_domain_required. Treat those as configuration errors instead of retrying the same request.