Brands
A brand is how customers know the business: its name, logo, sender name, languages, and the assistant’s personality and instructions. Workspaces sit under a brand, and channels sit under a workspace. To set up an account from the API, create the brand first, then its workspaces with POST /api/workspaces, then channels, knowledge, and policies.
Required scope: brands:read for GET endpoints, brands:write for write endpoints. Listing a brand’s workspaces also needs workspaces:read.
List brands
Section titled “List brands”curl "https://api.ohallo.eu/api/brands" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Returns the brands within the key’s reach. A key restricted to a brand or workspace sees that brand.
Create a brand
Section titled “Create a brand”curl -X POST "https://api.ohallo.eu/api/brands" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "name": "Example Company", "slug": "example-company", "emailFromName": "Example Company", "supportedLanguages": ["en", "de"], "primaryLanguage": "en" }'Response (201 Created):
{ "id": "b1a2c3d4-5678-4abc-8ef0-1234567890ab", "tenantId": "a1b2c3d4-e5f6-4890-abcd-ef1234567890", "name": "Example Company", "slug": "example-company", "status": "active", "emailFromName": "Example Company", "logoUrl": null, "primaryColor": null, "secondaryColor": null, "personaInstructions": null, "brandInstructions": null, "aiSenderName": null, "aiSenderTitle": null, "aiSenderImageUrl": null, "supportedLanguages": ["en", "de"], "primaryLanguage": "en", "personaVoice": { "voices": [] }, "createdAt": "2026-01-10T08:00:00.000Z", "updatedAt": "2026-01-10T08:00:00.000Z"}name, slug, and emailFromName are required. The slug is lowercase letters, digits, and hyphens, unique within the account, and fixed once the brand is created. The one exception is the first brand of a new account, which is born with the placeholder slug new-account and takes a slug derived from its name on its first rename. A logoUrl set by URL must use https.
The call is safe to retry. When a brand with the same slug and name exists, it is returned with 200 OK. When a different brand holds the slug, the response is 409 Conflict and names it:
{ "error": "A brand with this slug already exists", "brandId": "b1a2c3d4-5678-4abc-8ef0-1234567890ab"}Creating a brand needs a key without a brand or workspace restriction.
Get a brand
Section titled “Get a brand”curl "https://api.ohallo.eu/api/brands/b1a2c3d4-5678-4abc-8ef0-1234567890ab" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"A brand outside the key’s reach, or an ID that is not a UUID, answers 404.
Update a brand
Section titled “Update a brand”curl -X PATCH "https://api.ohallo.eu/api/brands/b1a2c3d4-5678-4abc-8ef0-1234567890ab" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "personaInstructions": "Warm and brief.", "brandInstructions": null }'Only the fields given change. null clears an optional field. Sending the current slug is accepted; a different slug answers 422. A key restricted to this brand may update it.
A brand keeps a supported language while one of its workspaces operates in it or one of its voice lines uses it as its language. An update whose supportedLanguages leaves out such a language changes nothing and answers 422:
{ "error": "A brand keeps a supported language while a workspace operates in it or a voice line uses it. In use: Swedish (sv) by workspace \"Example Company Sweden\".", "code": "language_in_use", "languagesInUse": [ { "language": "sv", "workspaces": [{ "id": "c1d2e3f4-5678-4abc-8ef0-1234567890ab", "name": "Example Company Sweden" }], "lines": [] } ]}Each entry of languagesInUse names a language with the workspaces that operate in it and the voice lines (id, displayName, workspaceId) that use it. Move them to another language first, then update the brand.
personaVoice holds one voice per language. On create and on update, these requests change nothing:
| Request | Response |
|---|---|
Two voices with the same language and vendor | 422 with "code": "duplicate_voice_language" |
| A voice that is not available | 422 with "code": "voice_not_available" |
| A new voice while the voice list cannot be read | 503 with "code": "voice_list_unavailable"; retry the request |
A voice the brand already uses is kept as it is.
Delete a brand
Section titled “Delete a brand”curl -X DELETE "https://api.ohallo.eu/api/brands/b1a2c3d4-5678-4abc-8ef0-1234567890ab" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"A brand is deleted once it has no workspaces; delete them first with DELETE /api/workspaces/{workspaceId}. While workspaces remain, the response is 409 Conflict. Deleting a brand needs a key without a brand or workspace restriction.
List a brand’s workspaces
Section titled “List a brand’s workspaces”curl "https://api.ohallo.eu/api/brands/b1a2c3d4-5678-4abc-8ef0-1234567890ab/workspaces" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Returns the workspaces of the brand within the key’s reach.
Upload the logo and the assistant’s sender image
Section titled “Upload the logo and the assistant’s sender image”curl -X POST "https://api.ohallo.eu/api/brands/b1a2c3d4-5678-4abc-8ef0-1234567890ab/logo" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -F "file=@logo.png;type=image/png"The file is JPEG, PNG, or WebP, up to 5 MB. The response carries the stored URL, { "logoUrl": "..." }. POST /api/brands/{brandId}/ai-sender-image stores the image shown with the assistant’s name in email signatures and answers { "aiSenderImageUrl": "..." }.
Keys restricted to a brand or workspace
Section titled “Keys restricted to a brand or workspace”A restricted key works within its brand or workspace. Brands and workspaces with a restricted key lists what each restriction allows. A brand or workspace outside the restriction answers 404; an action the restriction does not allow, on a brand or workspace the key can see, answers 403 with "code": "key_lock".
Listing, reading, creating, and updating brands are also available as tools on the oHallo MCP server.