Skip to content
Get an API key
Reference

Tenants

9 endpoints in this family.

List your tenants

GET/api/v1/tenants

A tenant is one of your customers: a client of your account, with its own WhatsApp numbers, contacts, conversations and templates, isolated from the others. Each one comes with its WhatsApp state, its latest hosted connect link and its activity this month (a tenant is active once it has sent or received a message in the current UTC month).

"My company" — the client your account was born with — is not listed: calls without the Nodium-Tenant header act on it. Requires a key that is not pinned to a client. Newest first, paginated with cursor.

Query parameters

  • externalIdstring

    Only the tenant carrying this identifier of yours.

  • limitinteger

    Page size, 1 to 100. Default 50.

  • cursorstring

    The nextCursor of the previous page.

Response

The tenants of your account, newest first.

  • data.itemsTenant[]

    The tenants.

  • data.nextCursorstring

    Pass it as cursor for the next page; null at the end.

  • data.hasMoreboolean

    Whether another page exists.

Refusals

  • 403all_clients_requiredThe key is pinned to a client.
curl https://nodium.io/api/v1/tenants \ -H "Authorization: Bearer $NODIUM_KEY"

Response

200 OK
{ "data": { "items": [ {} ], "nextCursor": "…", "hasMore": true }}

Create a tenant

POST/api/v1/tenants

Adds one of your customers to your account. It has no human member: you drive it through the API with the Nodium-Tenant header (or a key pinned to it, POST /keys with clientId). Your customer then connects their WhatsApp number through a hosted link (POST /tenants/{id}/connect-links) — they never need a Nodium account.

Pass your own identifier as externalId: it is unique in your account, so replaying the call returns 409 tenant_exists with the existing tenant id instead of creating a duplicate. The clients limit of your plan applies to the whole account.

Body

  • namestringrequired

    Your customer's name, 2 to 80 characters.

  • externalIdstring

    Your identifier for this customer, up to 200 characters. Unique in your account.

  • localestring

    Language of the hosted connect page.

    fren

  • timezonestring

    IANA time zone. Default Europe/Paris.

Response

The tenant, ready for a connect link.

Refusals

  • 402plan_limitYour plan has no room for another client (the Build plan includes none besides "My company").
  • 403all_clients_requiredThe key is pinned to a client.
  • 409tenant_existsA tenant already carries this `externalId`; its id is in `details.tenantId`.
curl -X POST https://nodium.io/api/v1/tenants \ -H "Authorization: Bearer $NODIUM_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Optique Martin", "externalId": "cust_1042", "timezone": "Europe/Paris" }'

Response

200 OK
{ "data": { "tenant": { "id": "…", "externalId": "…", "name": "…", "slug": "…", "status": "active", "locale": "fr", "timezone": "…", "whatsapp": {}, "connectLink": {}, "activeThisMonth": true, "eventsThisMonth": 0, "createdAt": "…", "updatedAt": "…" } }}

Close a tenant

DEL/api/v1/tenants/{id}

Closes the tenant: its channels are switched off, the numbers it connected through Meta's signup window are disconnected at Meta and freed so they can be connected elsewhere, the keys pinned to it are revoked, and its connect links stop working at once. Nothing is erased — conversations and messages are kept — but the tenant no longer appears in your list, and its externalId becomes free for a new tenant. This cannot be undone through the API.

Path parameters

  • idstring

    The tenant id, or your externalId.

Response

Confirmation, and what was switched off.

  • data.deletedboolean

    Always true.

  • data.channelsSwitchedOffinteger

    How many active channels were switched off.

  • data.numbersDisconnectedinteger

    How many numbers were disconnected at Meta and freed.

  • data.numbersToCleaninteger

    How many numbers Meta refused to disconnect: Nodium is alerted and cleans them.

  • data.keysRevokedinteger

    How many keys pinned to the tenant were revoked.

Refusals

  • 403all_clients_requiredThe key is pinned to a client.
  • 404tenant_not_foundNo such tenant in your account.
curl -X DELETE https://nodium.io/api/v1/tenants/<id> \ -H "Authorization: Bearer $NODIUM_KEY"

Response

200 OK
{ "data": { "deleted": true, "channelsSwitchedOff": 0, "numbersDisconnected": 0, "numbersToClean": 0, "keysRevoked": 0 }}

Get a tenant

GET/api/v1/tenants/{id}

Returns one tenant of your account, with its WhatsApp state, its latest hosted connect link and its activity this month. The path accepts either the Nodium id or your own externalId; "My company" answers here too, by its id. A tenant of another account answers 404, exactly like one that does not exist.

Path parameters

  • idstring

    The tenant id, or your externalId.

Response

The tenant and its state.

Refusals

  • 403all_clients_requiredThe key is pinned to a client.
  • 404tenant_not_foundNo such tenant in your account.
curl https://nodium.io/api/v1/tenants/<id> \ -H "Authorization: Bearer $NODIUM_KEY"

Response

200 OK
{ "data": { "tenant": { "id": "…", "externalId": "…", "name": "…", "slug": "…", "status": "active", "locale": "fr", "timezone": "…", "whatsapp": {}, "connectLink": {}, "activeThisMonth": true, "eventsThisMonth": 0, "createdAt": "…", "updatedAt": "…" } }}

Update a tenant

PATCH/api/v1/tenants/{id}

Changes what you send, leaves the rest. externalId: null removes your identifier. Renaming changes the tenant's slug.

Path parameters

  • idstring

    The tenant id, or your externalId.

Body

  • namestring

    New name, 2 to 80 characters.

  • externalIdstring

    New identifier of yours, or null to remove it.

  • localestring

    Language of the hosted connect page.

    fren

  • timezonestring

    IANA time zone.

Response

The tenant as it now is.

Refusals

  • 403all_clients_requiredThe key is pinned to a client.
  • 404tenant_not_foundNo such tenant in your account.
  • 409tenant_existsAnother tenant already carries this `externalId`.
curl -X PATCH https://nodium.io/api/v1/tenants/<id> \ -H "Authorization: Bearer $NODIUM_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "…", "externalId": "…" }'

Response

200 OK
{ "data": { "tenant": { "id": "…", "externalId": "…", "name": "…", "slug": "…", "status": "active", "locale": "fr", "timezone": "…", "whatsapp": {}, "connectLink": {}, "activeThisMonth": true, "eventsThisMonth": 0, "createdAt": "…", "updatedAt": "…" } }}

List the channels of a tenant

GET/api/v1/tenants/{id}/channels

The WhatsApp numbers of one tenant, in the same shape as GET /channels. Call it after the hosted connect link redirects back to you, to confirm the number and store its channelId.

Path parameters

  • idstring

    The tenant id, or your externalId.

Response

The channels of the tenant.

Refusals

  • 403all_clients_requiredThe key is pinned to a client.
  • 404tenant_not_foundNo such tenant in your account.
curl https://nodium.io/api/v1/tenants/<id>/channels \ -H "Authorization: Bearer $NODIUM_KEY"

Response

200 OK
{ "data": { "items": [ {} ] }}

Create a hosted connect link

POST/api/v1/tenants/{id}/connect-links

Returns a link you send to your customer. It opens a Nodium-hosted page where they connect their WhatsApp number through Meta's signup window — they never create a Nodium account. When they finish, they are sent back to redirectUrl with status=connected&channel_id=…; if they give up, with status=cancelled.

"My company" can have one too: open it yourself to connect your own number. The link works once and expires after expiresInDays (7 by default, 30 at most). The address is shown only here: Nodium keeps a hash of it. Create a new one if it is lost. After the redirect, confirm with GET /tenants/{id}/channels.

Path parameters

  • idstring

    The tenant id, or your externalId.

Body

  • redirectUrlstring

    Where to send your customer back. Must start with https://.

  • expiresInDaysinteger

    Lifetime in days, 1 to 30. Default 7.

Response

The hosted link, shown only here, and when it expires.

  • data.idstring

    The link id.

  • data.urlstring

    The address to send to your customer. Shown only here.

  • data.expiresAtstring

    When it stops working, ISO 8601.

  • data.redirectUrlstring

    Where your customer goes back, or null.

Refusals

  • 402plan_limitThe tenant is not "My company" and your plan includes no clients (Build).
  • 403all_clients_requiredThe key is pinned to a client.
  • 403tenant_closedThe tenant is suspended or closed.
  • 404tenant_not_foundNo such tenant in your account.
  • 422invalid_request`redirectUrl` is not an https address, or `expiresInDays` is out of range.
curl -X POST https://nodium.io/api/v1/tenants/<id>/connect-links \ -H "Authorization: Bearer $NODIUM_KEY" \ -H "Content-Type: application/json" \ -d '{ "redirectUrl": "https://app.example.com/settings/whatsapp" }'

Response

200 OK
{ "data": { "id": "…", "url": "…", "expiresAt": "…", "redirectUrl": "…" }}