Authentication
All programmatic access to the oHallo API uses API keys. Keys are scoped to your account and carry explicit permissions that control which endpoints you can call.
API key format
Section titled “API key format”API keys follow a structured format that identifies the environment:
sf_live_v1_a3Bx9kLmP2qR7wYz... (production)sf_test_v1_j8Hn4vCf6dWs1xTe... (sandbox)| Prefix | Environment |
|---|---|
sf_live_v1_ | Production — real data, real conversations |
sf_test_v1_ | Sandbox — safe for development and testing |
The full key is a cryptographically random string. Only the SHA-256 hash is stored on the server side. The raw key is shown exactly once at creation — store it securely.
Creating an API key
Section titled “Creating an API key”- Open the oHallo dashboard and navigate to Settings > API Access.
- Click + New API key.
- Enter a descriptive name (e.g., “Reporting script”, “CRM sync”).
- Select the scopes you need (see the full list below).
- Optionally restrict the key to a specific brand or workspace.
- Optionally set an expiration date.
- Click Create and copy the key immediately — it will not be shown again.
Using the key
Section titled “Using the key”Pass the key in the Authorization header as a Bearer token:
curl https://api.ohallo.eu/api/conversations \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"In TypeScript:
const response = await fetch("https://api.ohallo.eu/api/conversations?workspaceId=ws_abc123", { headers: { "Authorization": "Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx", "Content-Type": "application/json", },});
const data = await response.json();Scopes
Section titled “Scopes”Each API key carries a set of scopes that determine which endpoints it can access. Request only the scopes you need.
| Scope | Access |
|---|---|
conversations:read | List and read conversations, messages, attachments, attention items, consumption metrics, and agent activity |
conversations:write | Reply, compose, resolve, take over, release, assign, unassign, approve guardrail-gated actions, resolve attention items |
kb:read | List, search, and view pending knowledge base entries (including widget management reads) |
kb:write | Create, update, approve, reject, and delete KB entries; manage KB widgets |
policy:read | List, search, and view pending policy entries |
policy:write | Create, update, approve, reject, and delete policy entries |
contacts:read | List, search, and view contacts; read contact-form widgets |
contacts:write | Create, update, delete contacts; link contacts to accounts; manage contact-form widgets |
accounts:read | List, search, and view accounts; list account contacts |
agents:read | List platform and custom agent definitions |
agents:write | Create, update, and delete custom agents; update agent instructions |
channels:read | Read channel configuration |
channels:write | Update channels; store channel credentials; test connectivity; retry provisioning |
calendar:read | List calendar connections, calendars, and bookings |
calendar:write | Update or delete calendar connections |
billing:read | Read subscription, invoices, billing summary, and pricing catalog |
quality:read | Read CSAT statistics, circuit breakers, CSAT config, and entity-level quality scores |
quality:write | Update CSAT config and resolve circuit breakers |
workspaces:read | List and read workspaces, list channels in a workspace |
workspaces:write | Create, update, and delete workspaces |
Scope examples
Section titled “Scope examples”A reporting integration that only needs to read conversation data:
scopes: ["conversations:read", "contacts:read", "accounts:read"]A CI/CD pipeline that syncs knowledge base entries from documentation:
scopes: ["kb:read", "kb:write"]A full integration that manages conversations and CRM data:
scopes: ["conversations:read", "conversations:write", "contacts:read", "contacts:write", "accounts:read"]Scope enforcement
Section titled “Scope enforcement”Scope checks apply to programmatic API-key callers only. Endpoints that accept both schemes (dual auth) do not gate dashboard JWT sessions on scopes — operators acting via the oHallo dashboard always have full access to the endpoints surfaced in the UI. The granular scopes documented above govern what an API-key integration can do; they do not restrict a logged-in human.
Scoping keys to brand or workspace
Section titled “Scoping keys to brand or workspace”By default, an API key has access to all data within your account. You can restrict a key to a specific scope:
| Scope level | Effect |
|---|---|
| Organisation-wide (default) | Key can access data across all brands and workspaces |
| Brand | Key can only access data in workspaces belonging to that brand |
| Workspace | Key can only access data in that specific workspace |
This is useful when you have multiple integrations or partners that should only see a subset of your data.
Key expiration
Section titled “Key expiration”API keys can optionally have an expiration date. After expiry, any request using the key returns 401 Unauthorized. Non-expiring keys remain valid until manually revoked.
Set an expiration when creating keys for:
- Temporary integrations or proof-of-concept projects
- Third-party partners with time-limited access
- Compliance policies that require key rotation
Security best practices
Section titled “Security best practices”Rotate keys regularly. Create a new key, update your integration, then revoke the old key. There is no downtime — both keys work simultaneously during the transition.
Use minimum scopes. Grant only the permissions your integration actually needs. A reporting tool should not have conversations:write access.
Never expose keys in client-side code. API keys are server-side credentials. Do not embed them in browser JavaScript, mobile apps, or public repositories. If you need client-side access, proxy requests through your own backend.
Store keys in a secrets manager. Use your platform’s secrets management (AWS Secrets Manager, HashiCorp Vault, environment variables in CI/CD) rather than hardcoding keys in source files.
Monitor key usage. The dashboard shows the last-used timestamp for each key. Revoke keys that have not been used recently or that belong to decommissioned integrations.
Error responses
Section titled “Error responses”401 Unauthorized
Section titled “401 Unauthorized”Returned when the API key is missing, malformed, expired, or revoked.
{ "error": "Unauthorized"}403 Forbidden
Section titled “403 Forbidden”Returned when the API key is valid but does not have the required scope for the endpoint.
{ "error": "Forbidden"}For example, calling POST /api/conversations/{id}/reply with a key that only has conversations:read scope returns 403.