Skip to main content

Agencies and workspaces

An agency that runs WhatsApp for several clients keeps each one in a workspace: a complete account, with its own numbers, contacts, conversations, tags, fields, audiences, suppressions, flows, campaigns, templates, API keys, webhooks and sites. Nothing of one client shows up in another. Every workspace sits on the agency's subscription: one invoice, with numbers, messages, contacts and seats added up across the group.

Workspaces are created and managed in the panel, on the Workspaces screen of the agency's account. The API does not create or delete workspaces; what changes for an integration is below.

How many. The account's owner opens one workspace per WhatsApp number the plan allows, with nobody to ask: a three-number plan covers three clients. On a plan with no cap on numbers, there is no cap on workspaces.

A key belongs to one account​

An API key always belongs to one account — the agency's or a client's — and only reaches what is that account's. To integrate a client's site or system, create the key inside the client's workspace (enter the client from the panel's account switcher and go to API keys). A key of the agency's account does not send through a client's numbers, and a client's key does not see the others.

Everything else works as in any account: the key can be limited to some numbers, and the webhooks registered in a workspace only receive that client's events.

Knowing whose account it is​

GET /account/me returns parent: the agency that manages and pays for the account when it is a client's workspace, and null in an ordinary account.

{
"data": {
"id": "cm1clinic",
"name": "Smile Clinic",
"parent": { "id": "cm1agency", "name": "Acme Agency" },
"wabas": []
}
}

Billing each client for what it used​

GET /workspaces, with the agency account's key without a number restriction, returns the group: the agency's account first and then each workspace, with what it consumed in the billing period (usage: connected numbers, contacts and messages). It is the figure the agency uses to pass the cost on to each client.

curl https://api.joinotify.com/workspaces \
-H "Authorization: Bearer sk_live_AGENCY_KEY"

A workspace's key gets 409 not_principal, and a key limited to numbers gets 403: a client never learns about the others.

Reading every client's contacts​

GET /contacts?account=all, with the agency's key without a number restriction, lists the contacts of the agency and of every workspace, with the ordinary list's filters; ?account=<workspace id> lists one client's. Each contact carries workspace — the client it comes from, or null for the agency's own.

Handing assets to a client​

From the panel, the agency's owner hands what was in the agency's account to a client's workspace: contacts (those the agency still uses are copied; the others change account), a flow (copied as a draft) and an API key. A key handed over keeps the same secret: what the integration sends from then on lands in the client. The key can also be created straight in the workspace, from the agency's account.

Money belongs to the agency​

A workspace has no subscription, invoice, wallet or affiliate program of its own. /wallet and /affiliate answer 409 billed_by_parent with a workspace's key; anything about billing is read with the agency's key.

Clients that were mixed together​

An agency that already served several clients in one account moves each one into its workspace from the panel, one WABA at a time: the WABA comes with its numbers, templates, conversations, contacts and the keys limited only to those numbers. After that, those keys belong to the workspace — the integration keeps working without changing the key, but GET /account/me now answers with the client and with parent.