Widgets
Widgets are embeddable components that you can add to your website to surface knowledge base content or collect contact form submissions. oHallo supports two widget types: KB widgets display searchable knowledge base entries, and contact form widgets capture visitor inquiries and route them into the conversation pipeline.
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": "#0166A3", "fontFamily": "Inter, sans-serif", "customCss": "", "allowedOrigins": ["https://nordic-parts.dk", "https://www.nordic-parts.dk"], "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": "#0166A3", "fontFamily": "Inter, sans-serif", "allowedOrigins": ["https://nordic-parts.dk", "https://www.nordic-parts.dk"], "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": "#0166A3", "fontFamily": "Inter, sans-serif", "customCss": "", "allowedOrigins": ["https://nordic-parts.dk", "https://www.nordic-parts.dk"], "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://nordic-parts.dk", "https://www.nordic-parts.dk", "https://shop.nordic-parts.dk"] }'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-0123-4567-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": "#0166A3", "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-0123-4567-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": "#0166A3", "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 |
formType | string | No | Freeform label for the type of form (e.g. general_inquiry, support_request) |
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, file, or captcha |
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-0123-4567-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": "#0166A3", "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.
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"}