Contacts and Accounts
oHallo automatically creates contacts and accounts from inbound messages. Contacts represent individual people; accounts represent the companies they belong to. Use the API to search, read, and manage these records.
Contacts
Section titled “Contacts”List contacts
Section titled “List contacts”Search contacts by name, email, or phone number.
Required scope: contacts:read
curl "https://api.ohallo.eu/api/contacts?q=henrik" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | No | Search query — matches against name, email, and phone |
limit | integer | No | Max items to return (default 50, max 100) |
offset | integer | No | Number of items to skip (default 0) |
Response:
{ "items": [ { "id": "f7e8d9c0-b1a2-3456-7890-abcdef123456", "tenantId": "00112233-4455-4788-9899-aabbccddeeff", "name": "Henrik Larsen", "email": "henrik@nordic-parts.dk", "phone": "+45 31 23 45 67", "accountId": "12345678-abcd-4f01-a345-678901234567", "accountName": "Nordic Parts ApS", "externalRef": null, "createdAt": "2026-02-10T08:30:00.000Z", "updatedAt": "2026-03-15T14:30:00.000Z" } ], "total": 1}Get contact
Section titled “Get contact”Retrieve a single contact by ID.
Required scope: contacts:read
curl "https://api.ohallo.eu/api/contacts/f7e8d9c0-b1a2-3456-7890-abcdef123456" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "id": "f7e8d9c0-b1a2-3456-7890-abcdef123456", "tenantId": "00112233-4455-4788-9899-aabbccddeeff", "name": "Henrik Larsen", "email": "henrik@nordic-parts.dk", "phone": "+45 31 23 45 67", "accountId": "12345678-abcd-4f01-a345-678901234567", "accountName": "Nordic Parts ApS", "externalRef": null, "identities": [ { "channel": "email", "value": "henrik@nordic-parts.dk" } ], "createdAt": "2026-02-10T08:30:00.000Z", "updatedAt": "2026-03-15T14:30:00.000Z"}Link contact to account
Section titled “Link contact to account”Associate a contact with an existing account. This is useful when oHallo could not automatically resolve the account — for example, when the contact uses a personal email address.
Required scope: contacts:write
curl -X POST "https://api.ohallo.eu/api/contacts/f7e8d9c0-b1a2-3456-7890-abcdef123456/link-account" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "accountId": "12345678-abcd-4f01-a345-678901234567" }'Response:
{ "ok": true}Create contact
Section titled “Create contact”Create a contact manually, for example when importing from an external CRM.
Required scope: contacts:write
curl -X POST "https://api.ohallo.eu/api/contacts" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "Henrik Larsen", "email": "henrik@example.dk" }'Update contact
Section titled “Update contact”Update a contact’s details. Only included fields are changed.
Required scope: contacts:write
curl -X PATCH "https://api.ohallo.eu/api/contacts/f7e8d9c0-b1a2-3456-7890-abcdef123456" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "name": "Henrik B. Larsen" }'Delete contact
Section titled “Delete contact”Delete a contact. Associated conversations are not deleted.
Required scope: contacts:write
curl -X DELETE "https://api.ohallo.eu/api/contacts/f7e8d9c0-b1a2-3456-7890-abcdef123456" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Accounts
Section titled “Accounts”List accounts
Section titled “List accounts”Search accounts by name, VAT number, or company registration number.
Required scope: accounts:read
curl "https://api.ohallo.eu/api/accounts?q=nordic" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | No | Search query — matches against name, VAT number, and registration number |
limit | integer | No | Max items to return (default 50, max 100) |
offset | integer | No | Number of items to skip (default 0) |
Response:
{ "items": [ { "id": "12345678-abcd-4f01-a345-678901234567", "tenantId": "00112233-4455-4788-9899-aabbccddeeff", "name": "Nordic Parts ApS", "vatNumber": "DK12345678", "address": { "street": "Vesterbrogade 42", "city": "Copenhagen", "postalCode": "1620", "country": "DK" }, "website": "https://nordic-parts.dk", "industry": "Industrial equipment", "externalRef": null, "contactCount": 3, "createdAt": "2026-01-20T10:00:00.000Z", "updatedAt": "2026-03-10T11:15:00.000Z" } ], "total": 1}Get account
Section titled “Get account”Retrieve a single account by ID.
Required scope: accounts:read
curl "https://api.ohallo.eu/api/accounts/12345678-abcd-4f01-a345-678901234567" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "id": "12345678-abcd-4f01-a345-678901234567", "tenantId": "00112233-4455-4788-9899-aabbccddeeff", "name": "Nordic Parts ApS", "vatNumber": "DK12345678", "registrationNumber": "12345678", "address": { "street": "Vesterbrogade 42", "city": "Copenhagen", "postalCode": "1620", "country": "DK" }, "website": "https://nordic-parts.dk", "industry": "Industrial equipment", "externalRef": null, "enrichedAt": "2026-01-20T10:05:00.000Z", "createdAt": "2026-01-20T10:00:00.000Z", "updatedAt": "2026-03-10T11:15:00.000Z"}Get account contacts
Section titled “Get account contacts”List all contacts associated with an account.
Required scope: accounts:read
curl "https://api.ohallo.eu/api/accounts/12345678-abcd-4f01-a345-678901234567/contacts" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "items": [ { "id": "f7e8d9c0-b1a2-3456-7890-abcdef123456", "name": "Henrik Larsen", "email": "henrik@nordic-parts.dk", "phone": "+45 31 23 45 67", "createdAt": "2026-02-10T08:30:00.000Z" }, { "id": "a2b3c4d5-e6f7-8901-2345-678901abcdef", "name": "Mette Hansen", "email": "mette@nordic-parts.dk", "phone": null, "createdAt": "2026-03-01T11:00:00.000Z" } ], "total": 2}How contacts and accounts are resolved
Section titled “How contacts and accounts are resolved”When oHallo receives a message from an unknown sender, the following happens automatically:
- Contact creation — A contact record is created using the sender’s email address, phone number, or chat identity.
- Account resolution — For B2B workspaces, oHallo attempts to match the sender to an existing account:
- By email domain (e.g.,
@nordic-parts.dkmatches the Nordic Parts ApS account) - By VAT number or company registration number found in the message body
- By CRM lookup if an external CRM is connected via MCP
- By email domain (e.g.,
- Account enrichment — For newly created accounts, oHallo enriches the record with data from the company website and public business registries (VAT/CVR validation).
If automatic resolution fails, the contact is created without an account link. You can then link it manually using the POST /api/contacts/{id}/link-account endpoint or via the dashboard.