Overview

Axis Inbox is one HTTP API for connections, conversations and campaigns across WhatsApp, Meta (Facebook/Instagram), SMS, email, LiveChat and the social networks. Your app talks to Inbox; behind it sit vendor integrations you never name in code.

It is shared infrastructure, not a product surface. Several Axis apps call the same service, each scoped to its own tenants.

The mental model

A connection is one connected account — a WhatsApp number, a Facebook page, an email domain, the LiveChat widget. Inbound messages from that account arrive as provider webhooks, are verified, then normalised and ingested into a thread (a conversation) made of entries (individual messages or comments). You list threads, read one, and reply through the same connection. Everything is scoped to a tenant — a workspace — identified by a single request header. On top of that core sit tickets, contacts, labels, segments, templates, campaigns, flows and publishing, all built on the same threads and the same contact book.

What Inbox owns, and what it does not

Concern Owner
Connections, bindings, encrypted provider credentials Inbox
Threads, entries, participants Inbox
Tickets, labels, notes, canned replies Inbox
Contacts, identifiers, consent, segments Inbox
Templates, campaigns, flows, warm-up Inbox
Posts and publishing dispatch Inbox
Inbound and outbound webhooks Inbox
Users and sessions Axis Accounts
User groups (workspaces) Axis Accounts
Apps Axis Accounts (Inbox keeps a mirror row for local config)

Inbox stores no users. Every *UserId column in the schema — ownerUserId, sentByUserId, actorUserId, assignedUserId — holds an Accounts user id, never a foreign key to a local table. That is deliberate: identity has exactly one home, and Inbox never has to keep a copy in sync.

The two things to get right

Almost every integration problem is one of these two.

The credential. Inbox authenticates against Axis Accounts. You present either an Accounts service key (sk_…, a machine credential acting as the whole tenant) or an Accounts user session id (which carries the operator's identity, so ownership and assignment attribute to a real person). The key must carry inbox:* scopes, and those scopes must have been published to Accounts first — see Connect an app.

The tenant. Every tenant-scoped call sends X-Axis-Tenant: ws_<accountsUserGroupId>. A wrong value does not error. It silently provisions a fresh, empty workspace, and your data appears to have vanished. This is the single most common integration failure, and Tenancy exists mostly to explain it.

A note on the name

This service is Axis Inbox. It was historically called Axis Social, and you will still find that name in older code, package metadata and comments.

It is not the axis-social app registered in Axis Accounts. axis-social is one consuming app, alongside axis-engage, axis-workspace and axis-dashboard. Inbox is the infrastructure all of them call. The naming overlap has caused real, repeated confusion — including data migrated into the wrong app — so it is worth reading twice: an app slug in Accounts identifies a caller, never this service.

Where to go next

You want to Read
Get the service running on your machine Run it locally
Onboard a new consuming app Connect an app
Send and receive your first message Your first conversation
Understand the request pipeline and stack Architecture
Understand workspace scoping Tenancy
Find a model or a constraint Data model
Look up a word Glossary