Widgets
Widgets are embeddable components that you can add to your website to surface knowledge base content or collect contact form submissions. The widgets API manages two widget types: KB widgets display searchable knowledge base entries, and contact form widgets capture visitor inquiries and route them into the conversation pipeline. The chat widget is configured as a chat channel, and its embed code and the page controls that open and close it are covered in Embedding Widgets. The booking widget is a contact form widget with formType: "booking" (see Booking widget).
Widget management uses domain-specific scopes:
| Widget type | Read scope | Write scope |
|---|---|---|
| KB widgets | kb:read | kb:write |
| Contact form widgets | contacts:read | contacts:write |
KB widgets
Section titled “KB widgets”KB widgets embed a searchable knowledge base interface on your website. Visitors can browse and search entries without leaving the page.
Required scope: kb:read for GET endpoints, kb:write for write endpoints.
List KB widgets
Section titled “List KB widgets”Retrieve all KB widgets for a workspace.
curl "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/widgets/kb" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "items": [ { "id": "11223344-5566-4788-89aa-bbccddeeff00", "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Help Center Widget", "primaryColor": "#000000", "fontFamily": "Inter, sans-serif", "customCss": "", "allowedOrigins": ["https://example.com", "https://www.example.com"], "enabled": true, "theme": "light", "inlineView": "grid", "publicKey": "pk_wgt_a1b2c3d4e5f6", "createdAt": "2026-02-10T09:00:00.000Z", "updatedAt": "2026-03-01T11:30:00.000Z" } ], "total": 1}Create KB widget
Section titled “Create KB widget”Create a new KB widget for a workspace.
Required scope: kb:write
curl -X POST "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/widgets/kb" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "name": "Help Center Widget", "primaryColor": "#000000", "fontFamily": "Inter, sans-serif", "allowedOrigins": ["https://example.com", "https://www.example.com"], "enabled": true, "theme": "light", "inlineView": "grid" }'Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the widget |
primaryColor | string | No | CSS colour value for the primary accent |
fontFamily | string | No | CSS font-family string |
customCss | string | No | Additional CSS injected into the widget iframe |
allowedOrigins | string[] | No | Origins permitted to embed the widget |
enabled | boolean | No | Whether the widget is active |
theme | string | No | Colour theme: light, dark, or auto |
inlineView | string | No | Entry layout: grid or list |
Response (201):
{ "id": "11223344-5566-4788-89aa-bbccddeeff00", "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Help Center Widget", "primaryColor": "#000000", "fontFamily": "Inter, sans-serif", "customCss": "", "allowedOrigins": ["https://example.com", "https://www.example.com"], "enabled": true, "theme": "light", "inlineView": "grid", "publicKey": "pk_wgt_a1b2c3d4e5f6", "createdAt": "2026-03-15T10:00:00.000Z", "updatedAt": "2026-03-15T10:00:00.000Z"}Get KB widget
Section titled “Get KB widget”Retrieve a single KB widget by its identifier.
curl "https://api.ohallo.eu/api/widgets/kb/11223344-5566-4788-89aa-bbccddeeff00" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response: Returns the full KB widget object as shown in the create response above.
Update KB widget
Section titled “Update KB widget”Update an existing KB widget. Only the fields you include in the request body are changed.
Required scope: kb:write
curl -X PATCH "https://api.ohallo.eu/api/widgets/kb/11223344-5566-4788-89aa-bbccddeeff00" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "theme": "dark", "inlineView": "list", "allowedOrigins": ["https://example.com", "https://www.example.com", "https://shop.example.com"] }'Response: Returns the full updated KB widget object.
Delete KB widget
Section titled “Delete KB widget”Permanently delete a KB widget. Any pages still embedding the widget will display an error state.
Required scope: kb:write
curl -X DELETE "https://api.ohallo.eu/api/widgets/kb/11223344-5566-4788-89aa-bbccddeeff00" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response: 204 No Content on success.
Rotate KB widget public key
Section titled “Rotate KB widget public key”Generate a new public key for the widget. The previous key is invalidated immediately, so any embedded instances must be updated with the new key.
Required scope: kb:write
curl -X POST "https://api.ohallo.eu/api/widgets/kb/11223344-5566-4788-89aa-bbccddeeff00/rotate-key" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "publicKey": "pk_wgt_x9y8z7w6v5u4"}Contact form widgets
Section titled “Contact form widgets”Contact form widgets embed a customisable form on your website. Submissions are routed into oHallo as new conversations on the linked channel.
Required scope: contacts:read for GET endpoints, contacts:write for write endpoints.
List contact form widgets
Section titled “List contact form widgets”Retrieve all contact form widgets for a workspace.
curl "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/widgets/contact" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "items": [ { "id": "aabbccdd-eeff-4011-9233-445566778899", "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Website Contact Form", "channelId": "d4e5f6a7-b8c9-4123-8567-890abcdef012", "formType": "general_inquiry", "fields": [ { "id": "field_name", "type": "text", "label": "Full name", "required": true, "width": "full", "crmMapping": "contact.firstName" }, { "id": "field_email", "type": "email", "label": "Email address", "required": true, "width": "full", "crmMapping": "contact.email" }, { "id": "field_message", "type": "textarea", "label": "How can we help?", "placeholder": "Describe your question or request", "required": true, "width": "full" } ], "variant": "outlined", "primaryColor": "#000000", "customCss": "", "theme": "light", "successMessage": "Thank you for reaching out. We will get back to you within one business day.", "redirectUrl": null, "enabled": true, "publicKey": "pk_wgt_f1e2d3c4b5a6", "createdAt": "2026-02-20T12:00:00.000Z", "updatedAt": "2026-03-05T09:15:00.000Z" } ], "total": 1}Create contact form widget
Section titled “Create contact form widget”Create a new contact form widget linked to a specific channel.
Required scope: contacts:write
curl -X POST "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/widgets/contact" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "name": "Website Contact Form", "channelId": "d4e5f6a7-b8c9-4123-8567-890abcdef012", "formType": "general_inquiry", "fields": [ { "id": "field_name", "type": "text", "label": "Full name", "required": true, "width": "full", "crmMapping": "contact.firstName" }, { "id": "field_email", "type": "email", "label": "Email address", "required": true, "width": "full", "crmMapping": "contact.email" }, { "id": "field_company", "type": "text", "label": "Company", "required": false, "width": "half", "crmMapping": "account.name" }, { "id": "field_phone", "type": "phone", "label": "Phone number", "required": false, "width": "half", "crmMapping": "contact.phone" }, { "id": "field_message", "type": "textarea", "label": "How can we help?", "placeholder": "Describe your question or request", "required": true, "width": "full" } ], "variant": "outlined", "primaryColor": "#000000", "theme": "light", "successMessage": "Thank you for reaching out. We will get back to you within one business day.", "enabled": true }'Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the widget |
channelId | UUID | Yes | Channel that form submissions are routed to. It must be a channel of the widget’s workspace; any other answers 404 { "error": "Channel not found" } and nothing is created |
formType | string | No | Type of form. booking has its own behaviour: the widget offers time slots from its calendar connection, and the submission carries the selected slot and timezone (see Booking widget). demo_request, gated_content, newsletter and event_registration are also recognised; any other value (e.g. general_inquiry) is handled as a contact form |
fields | array | No | Form field definitions (see field object below) |
variant | string | No | Visual style: outlined, filled, or minimal |
primaryColor | string | No | CSS colour value for the primary accent |
customCss | string | No | Additional CSS injected into the widget iframe |
theme | string | No | Colour theme: light, dark, or auto |
successMessage | string | No | Message displayed after successful submission |
redirectUrl | string | No | URL to redirect to after submission instead of showing the success message |
enabled | boolean | No | Whether the widget is active |
Field object:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the field within the form |
type | string | Yes | Field type: text, email, phone, textarea, number, select, checkbox, date, time, start-time, end-time, file, captcha, or hidden. A hidden field is never rendered; the embedding page supplies its value with data-field-<name> |
label | string | Yes | Label displayed above the field |
placeholder | string | No | Placeholder text inside the field |
required | boolean | Yes | Whether the field must be filled before submission |
width | string | Yes | Layout width: full or half |
options | string[] | No | Available choices for select fields |
crmMapping | string | No | Maps the field value to a CRM property: contact.email, contact.firstName, contact.lastName, contact.phone, account.name, or account.vatNumber |
Response (201):
{ "id": "aabbccdd-eeff-4011-9233-445566778899", "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Website Contact Form", "channelId": "d4e5f6a7-b8c9-4123-8567-890abcdef012", "formType": "general_inquiry", "fields": [ { "id": "field_name", "type": "text", "label": "Full name", "required": true, "width": "full", "crmMapping": "contact.firstName" }, { "id": "field_email", "type": "email", "label": "Email address", "required": true, "width": "full", "crmMapping": "contact.email" }, { "id": "field_company", "type": "text", "label": "Company", "required": false, "width": "half", "crmMapping": "account.name" }, { "id": "field_phone", "type": "phone", "label": "Phone number", "required": false, "width": "half", "crmMapping": "contact.phone" }, { "id": "field_message", "type": "textarea", "label": "How can we help?", "placeholder": "Describe your question or request", "required": true, "width": "full" } ], "variant": "outlined", "primaryColor": "#000000", "customCss": "", "theme": "light", "successMessage": "Thank you for reaching out. We will get back to you within one business day.", "redirectUrl": null, "enabled": true, "publicKey": "pk_wgt_f1e2d3c4b5a6", "createdAt": "2026-03-15T10:00:00.000Z", "updatedAt": "2026-03-15T10:00:00.000Z"}Get contact form widget
Section titled “Get contact form widget”Retrieve a single contact form widget by its identifier.
curl "https://api.ohallo.eu/api/widgets/contact/aabbccdd-eeff-4788-8233-445566778899" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response: Returns the full contact form widget object as shown in the create response above.
Update contact form widget
Section titled “Update contact form widget”Update an existing contact form widget. Only the fields you include in the request body are changed.
Required scope: contacts:write
curl -X PATCH "https://api.ohallo.eu/api/widgets/contact/aabbccdd-eeff-4788-8233-445566778899" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "successMessage": "Thank you. A member of our team will respond within two hours during business hours.", "variant": "filled" }'Response: Returns the full updated contact form widget object. A new channelId must be a channel of the widget’s workspace; any other answers 404 { "error": "Channel not found" } and the widget is left unchanged.
Delete contact form widget
Section titled “Delete contact form widget”Permanently delete a contact form widget. Any pages still embedding the widget will display an error state.
Required scope: contacts:write
curl -X DELETE "https://api.ohallo.eu/api/widgets/contact/aabbccdd-eeff-4788-8233-445566778899" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response: 204 No Content on success.
Rotate contact form widget public key
Section titled “Rotate contact form widget public key”Generate a new public key for the widget. The previous key is invalidated immediately, so any embedded instances must be updated with the new key.
Required scope: contacts:write
curl -X POST "https://api.ohallo.eu/api/widgets/contact/aabbccdd-eeff-4788-8233-445566778899/rotate-key" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "publicKey": "pk_wgt_m3n4o5p6q7r8"}