Skip to content

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 typeRead scopeWrite scope
KB widgetskb:readkb:write
Contact form widgetscontacts:readcontacts:write

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.

Retrieve all KB widgets for a workspace.

Terminal window
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 a new KB widget for a workspace.

Required scope: kb:write

Terminal window
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:

FieldTypeRequiredDescription
namestringYesDisplay name for the widget
primaryColorstringNoCSS colour value for the primary accent
fontFamilystringNoCSS font-family string
customCssstringNoAdditional CSS injected into the widget iframe
allowedOriginsstring[]NoOrigins permitted to embed the widget
enabledbooleanNoWhether the widget is active
themestringNoColour theme: light, dark, or auto
inlineViewstringNoEntry 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"
}

Retrieve a single KB widget by its identifier.

Terminal window
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 an existing KB widget. Only the fields you include in the request body are changed.

Required scope: kb:write

Terminal window
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.

Permanently delete a KB widget. Any pages still embedding the widget will display an error state.

Required scope: kb:write

Terminal window
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.

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

Terminal window
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 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.

Retrieve all contact form widgets for a workspace.

Terminal window
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 a new contact form widget linked to a specific channel.

Required scope: contacts:write

Terminal window
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:

FieldTypeRequiredDescription
namestringYesDisplay name for the widget
channelIdUUIDYesChannel that form submissions are routed to
formTypestringNoFreeform label for the type of form (e.g. general_inquiry, support_request)
fieldsarrayNoForm field definitions (see field object below)
variantstringNoVisual style: outlined, filled, or minimal
primaryColorstringNoCSS colour value for the primary accent
customCssstringNoAdditional CSS injected into the widget iframe
themestringNoColour theme: light, dark, or auto
successMessagestringNoMessage displayed after successful submission
redirectUrlstringNoURL to redirect to after submission instead of showing the success message
enabledbooleanNoWhether the widget is active

Field object:

FieldTypeRequiredDescription
idstringYesUnique identifier for the field within the form
typestringYesField type: text, email, phone, textarea, number, select, checkbox, date, time, file, or captcha
labelstringYesLabel displayed above the field
placeholderstringNoPlaceholder text inside the field
requiredbooleanYesWhether the field must be filled before submission
widthstringYesLayout width: full or half
optionsstring[]NoAvailable choices for select fields
crmMappingstringNoMaps 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"
}

Retrieve a single contact form widget by its identifier.

Terminal window
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 an existing contact form widget. Only the fields you include in the request body are changed.

Required scope: contacts:write

Terminal window
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.

Permanently delete a contact form widget. Any pages still embedding the widget will display an error state.

Required scope: contacts:write

Terminal window
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.

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

Terminal window
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"
}