Skip to content

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 keys follow a structured format that identifies the environment:

sf_live_v1_a3Bx9kLmP2qR7wYz... (production)
sf_test_v1_j8Hn4vCf6dWs1xTe... (sandbox)
PrefixEnvironment
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.

  1. Open the oHallo dashboard and navigate to Settings > API Access.
  2. Click + New API key.
  3. Enter a descriptive name (e.g., “Reporting script”, “CRM sync”).
  4. Select the scopes you need (see the full list below).
  5. Optionally restrict the key to a specific brand or workspace.
  6. Optionally set an expiration date.
  7. Click Create and copy the key immediately — it will not be shown again.

Pass the key in the Authorization header as a Bearer token:

Terminal window
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();

Each API key carries a set of scopes that determine which endpoints it can access. Request only the scopes you need.

ScopeAccess
conversations:readList and read conversations, messages, attachments, attention items, consumption metrics, and agent activity
conversations:writeReply, compose, resolve, take over, release, assign, unassign, approve guardrail-gated actions, resolve attention items
kb:readList, search, and view pending knowledge base entries (including widget management reads)
kb:writeCreate, update, approve, reject, and delete KB entries; manage KB widgets
policy:readList, search, and view pending policy entries
policy:writeCreate, update, approve, reject, and delete policy entries
contacts:readList, search, and view contacts; read contact-form widgets
contacts:writeCreate, update, delete contacts; link contacts to accounts; manage contact-form widgets
accounts:readList, search, and view accounts; list account contacts
agents:readList platform and custom agent definitions
agents:writeCreate, update, and delete custom agents; update agent instructions
channels:readRead channel configuration
channels:writeUpdate channels; store channel credentials; test connectivity; retry provisioning
calendar:readList calendar connections, calendars, and bookings
calendar:writeUpdate or delete calendar connections
billing:readRead subscription, invoices, billing summary, and pricing catalog
quality:readRead CSAT statistics, circuit breakers, CSAT config, and entity-level quality scores
quality:writeUpdate CSAT config and resolve circuit breakers
workspaces:readList and read workspaces, list channels in a workspace
workspaces:writeCreate, update, and delete workspaces

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

By default, an API key has access to all data within your account. You can restrict a key to a specific scope:

Scope levelEffect
Organisation-wide (default)Key can access data across all brands and workspaces
BrandKey can only access data in workspaces belonging to that brand
WorkspaceKey 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.

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

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.

Returned when the API key is missing, malformed, expired, or revoked.

{
"error": "Unauthorized"
}

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.