Get started
CLI
The nodium command: check your setup, read your numbers and conversations, ship templates and webhooks, and replay events to your machine.
@nodium.io/cli is a thin layer over the TypeScript SDK: every command calls one of its methods, with the same key, the same client header and the same errors. Node 20 or later.
Install and log in
npm install -g @nodium.io/cli # or: npx @nodium.io/cli <command>nodium login # paste your key (nod_…): kept in ~/.config/nodium, readable by you onlynodium status # what the key is, your numbers, your webhooks, the next step- The key is looked up in this order:
--key, thenNODIUM_KEY, then the file saved bynodium login. It is never printed in full;nodium logoutdeletes the file. --tenant <id or externalId>acts for one of your clients, like theNodium-Tenantheader. Without it, a command acts on My company, or on the client the key is pinned to.nodium help <command>(or--help) describes each command and its options.
Check your setup
$ nodium statusAuthentication: authenticatedKey: nod_1a2b… "ci", never expiresAccount: Acme (acc_…)Access: every client of the accountClients: 12WhatsApp Numbers: 3 (3 on)Webhooks: 1 active of 1Next: nodium numbers list nodium send --channel <id> --to <+33…> --text "Hello"nodium statussays which key is used, its account, what it reaches (every client of the account, or the client it is pinned to), your clients and numbers, your webhooks, and what to run next.Clientsshows only for a key that is not pinned: a pinned key cannot list the other clients.Webhooks: not visible with this key (pinned to My company): the subscriptions of My company receive every client's events, so a key pinned to My company cannot read them. Use a key that is not pinned to see or manage them.
Read
nodium numbers list·numbers get <id>·numbers check <id>— your numbers, and a fresh check at Meta.nodium conversations list·conversations get <id>·messages list <conversationId>·messages get <id>.nodium contacts list·contacts get <id>·templates list·templates get <id>.nodium webhooks list·webhooks deliveries --failed·tenants list·tenants get <id>.nodium events --after <seq>reads the event log;nodium healthexits 1 when a number needs attention.- Lists show the newest 20;
--limit <n>shows more, following the pages for you.
Write
nodium templates new --input order_ready.json # a draft: nothing goes to Meta yetnodium templates deploy tpl_123 # asks "Proceed? [y/N]"nodium templates wait tpl_123 --timeout 10m # exit 0 approved, 1 refused or timed outnodium send --channel ch_123 --to +33612345678 --template order_ready --language en --var 1=Karimnodium sendtakes--textor--template; any other message (a file bymediaId, buttons, a list, a location) as the JSON ofPOST /messages, with--input <file.json>or--stdin. A send Meta refuses exits 1.nodium templates new|update --input <file.json>,deploy,refresh,wait,delete.nodium webhooks new --url <https://…> --event message.receivedprints the signing secret once; alsoupdate,delete,test,redeliver <deliveryId>,rotate-secret.nodium tenants new --name "Agence Horizon" --external-id crm-4187 --connect-linkadds a client and prints the link to send it;nodium connect-link new --tenant <id>makes a new one.nodium flows deploy flow.jsoncreates a draft Flow at Meta (--id <flowId>: a new version of a draft) and prints Meta's validation problems with their line.--publishpublishes it only when there are none — publishing is final.
Approval before a write
A command that sends or changes something — send, templates deploy|delete, webhooks new|update|delete|redeliver|rotate-secret, tenants new, connect-link new, flows deploy — says what it is about to do and asks Proceed? [y/N]. Outside a terminal there is nobody to ask: it refuses with exit code 2 unless you pass --yes.
Scripts and AI agents
# Piped, every command prints the API's object as JSONnodium conversations list --limit 5 | jq '.[].contact.identity'# Outside a terminal, a command that sends or changes something needs --yesecho '{"channelId":"ch_123","to":"+33612345678","type":"text","text":"Hello"}' \ | nodium send --stdin --yes# A refusal goes to stderr, as JSON, with exit code 1# { "error": { "status": 404, "code": "not_found", "message": "…", "requestId": "req_…" } }--output json|human. The default ishumanin a terminal, ending with aNext:block of the commands that usually follow, andjsonwhen the output is piped — what a script or an agent sees. JSON is the object the SDK returns, unchanged.- Exit codes:
0done,1refused by Nodium or Meta (or a template refused, a Flow with problems),2a wrong command line or a missing approval. - For an agent: read first (
status,numbers list,templates get), show the person what will be sent, and pass--yesonly once they agreed. Give the agent a key pinned to one client.
Develop locally
export NODIUM_KEY=nod_…npx @nodium.io/cli listen \ --forward http://localhost:3000/webhook \ --secret whsec_… \ --events message.received,message.failed# 10:32:01 message.received 200 12 ms evt_5f1c0a9e…# 10:32:07 message.failed 500 4 ms evt_8c2d41b7…# Try it: send a message to your own phone, then answer it.npx @nodium.io/cli send --channel <channel id> --to +33612345678 --text "Hello"nodium listen reads your event log and calls your local server with real, signed deliveries — no tunnel, no public address. Ctrl+C stops it and prints where to resume (--from <seq>). See Webhooks.