Shared shapes
The objects endpoints return — a conversation, a message, a contact, an app… described once, here.
Conversation
A conversation: one contact on one WhatsApp number — the 24-hour window and the delivery receipts.
idstringThe conversation id.
channelIdstringThe channel it lives on.
channelTypestringThe kind of channel.
whatsappchannelNamestringThe channel's name in Nodium.
contactobjectWho you are talking to.
Show fields
idstringThe contact id.
displayNamestringTheir name, or
null.identitystringTheir phone number, or their WhatsApp user id when the number is hidden.
identityKindstringWhat
identityis.phoneemailexternalblockedbooleanBlocked contacts are kept out of the inbox.
windowobjectThe WhatsApp 24-hour customer service window.
Show fields
appliesbooleanfalseoutside WhatsApp.openbooleanWhether free text can be sent now. Always
truewhen the rule does not apply.expiresAtstringWhen it closes, ISO 8601, or
null.minutesLeftintegerMinutes left,
0when closed,nullwhen the rule does not apply.
lastInboundAtstringWhen the contact last wrote, ISO 8601. This opens the 24-hour window.
createdAtstringISO 8601.
lastMessageobjectThe latest message, or
null.Show fields
idstringThe message id.
directionstringFrom the contact, or to them.
inboundoutboundtextContentstringIts text.
statusstringIts delivery status.
createdAtstringISO 8601.
{ "id": "…", "channelId": "…", "channelType": "whatsapp", "channelName": "…", "contact": { "id": "…", "displayName": "…", "identity": "…", "identityKind": "phone", "blocked": true }, "window": { "applies": true, "open": true, "expiresAt": "…", "minutesLeft": 0 }, "lastInboundAt": "…", "createdAt": "…", "lastMessage": { "id": "…", "direction": "inbound", "textContent": "…", "status": "…", "createdAt": "…" }}Message
One message, in either direction.
idstringThe message id.
conversationIdstringIts conversation.
channelTypestringThe kind of channel.
whatsappdirectionstringinboundfrom the contact,outboundto them.inboundoutboundsenderstringWho speaks: the contact, your software (
api, through a key), a person in the console (user), or Nodium (system).contactapiusersystemsenderNamestringThe person's name, or your key's label.
apiKeyIdstringThe key that sent it, when it went through the API.
typestringtext,template,interactive,image,audio,document…textContentstringIts text. For a template, the rendered text.
mediaUrlstringWhere to download its file (
GET /messages/{id}/media), ornull.statusstringDelivery status.
queued: waiting to leave (queue: true).queuedsendingsentdeliveredreadfailedproviderMessageIdstringThe id at the messaging provider (WhatsApp
wamid), ornull.errorstringWhy it failed, as the provider said, or
null.errorInfoobjectThe failure explained, when
statusisfailedand the provider gave a code; otherwisenull. A send can answer HTTP 200 or 201 withstatus: "failed": teststatus, then read this.Show fields
codeintegerThe provider's error code (Meta's, for example
131047).titlestringWhat happened, in a sentence.
actionstringWhat to do about it. When
actorisclient, written to be passed on to your client as is.actorstringWho acts:
you(your code or console),client(the owner of the number),nodium, orwait(the refusal is temporary: nobody needs to act).youclientnodiumwait
formobjectThe buttons or list sent with it, or
null.replyobjectFor a tapped button or chosen list row:
{ id, title }. Otherwisenull.locationobjectA location the contact sent:
{ latitude, longitude, name, address }, ornull.originstringphonewhen the message was written from the WhatsApp Business app of a coexistence number, otherwisenull.importedbooleanTrue for a message taken from the phone's chat history (coexistence), not received live.
createdAtstringISO 8601.
{ "id": "…", "conversationId": "…", "channelType": "whatsapp", "direction": "inbound", "sender": "contact", "senderName": "…", "apiKeyId": "…", "type": "…", "textContent": "…", "mediaUrl": "…", "status": "queued", "providerMessageId": "…", "error": "…", "errorInfo": { "code": 0, "title": "…", "action": "…", "actor": "you" }, "form": {}, "reply": {}, "location": {}, "origin": "…", "imported": true, "createdAt": "…"}SendResult
What a send returns.
conversationIdstringThe conversation the message belongs to — opened by this call, or reused.
messageMessageduplicatebooleantruewhen thisidempotencyKeywas already used: the message returned is the first one, nothing was sent again.
{ "conversationId": "…", "message": { "id": "…", "conversationId": "…", "channelType": "whatsapp", "direction": "inbound", "sender": "contact", "senderName": "…", "apiKeyId": "…", "type": "…", "textContent": "…", "mediaUrl": "…", "status": "queued", "providerMessageId": "…", "error": "…", "errorInfo": {}, "form": {}, "reply": {}, "location": {}, "origin": "…", "imported": true, "createdAt": "…" }, "duplicate": true}Contact
A person you talk to.
idstringThe contact id.
displayNamestringTheir name, or
null.phonestringTheir phone number, E.164 digits, or
null.emailstringTheir email address, or
null.externalIdstringYour own id for them, or
null.optInAtstringWhen they agreed to receive messages, or
null.optOutAtstringWhen they withdrew — on WhatsApp by tapping "Stop" — or
null. It overridesoptInAt.blockedbooleanBlocked contacts receive nothing.
conversationCountintegerHow many conversations they have.
createdAtstringISO 8601.
updatedAtstringISO 8601.
{ "id": "…", "displayName": "…", "phone": "…", "email": "…", "externalId": "…", "optInAt": "…", "optOutAt": "…", "blocked": true, "conversationCount": 0, "createdAt": "…", "updatedAt": "…"}Channel
A WhatsApp number the workspace speaks from.
idstringThe channel id — the
channelIdyou send from.typestringThe kind of channel.
whatsappnamestringIts name in Nodium.
identitystringIts public identity: the business phone number id.
isActivebooleanAn inactive channel neither sends nor receives.
qualityRatingstringWhatsApp quality rating:
GREEN,YELLOW,RED, ornull.messagingLimitstringMeta's sending tier, or
null.isTestbooleanA test channel: the sandbox (the shared Nodium number) or the demo channel.
paymentMissingbooleanMeta refused a paid message because the client's WhatsApp account has no payment method (error 131042). The client adds one in WhatsApp Manager; it clears once a template is delivered.
{ "id": "…", "type": "whatsapp", "name": "…", "identity": "…", "isActive": true, "qualityRating": "…", "messagingLimit": "…", "isTest": true, "paymentMissing": true}Template
A WhatsApp message template.
idstringThe template id — the
templateIdyou send.namestringIts name at Meta.
languagestringIts language code, e.g.
fr.categorystringMeta's category. Marketing ones are refused to contacts who opted out.
UTILITYMARKETINGAUTHENTICATIONstatusstringWhere it stands at Meta, across its client's WhatsApp accounts. Only
approvedcan be sent.failed: the deposit at Meta did not happen; deploy again.draftnot_deployedno_numbersubmittedapprovedrejectedpauseddisabledfailedclientIdstringThe client it belongs to.
deployedAtstringWhen it was first deployed, ISO 8601;
nullfor a draft.headerMediaobjectIts image, video or document header:
kind,sampleId,mimeType,filename,size.nullfor a text header or none.authenticationobjectFor an
AUTHENTICATIONtemplate:securityRecommendationandcodeExpirationMinutes(null= no expiry line).nullfor any other category.bodystringIts text, with
{{1}},{{2}}… placeholders. For anAUTHENTICATIONtemplate, a readable copy of the text Meta writes.createdAtstringISO 8601.
updatedAtstringISO 8601.
{ "id": "…", "name": "…", "language": "…", "category": "UTILITY", "status": "draft", "clientId": "…", "deployedAt": "…", "headerMedia": {}, "authentication": {}, "body": "…", "createdAt": "…", "updatedAt": "…"}WebhookSubscription
An address Nodium calls, and for which events.
idstringThe subscription id.
urlstringThe https address called.
eventsstring[]The events delivered;
*means all.channelIdsstring[]The channels (numbers) whose events are delivered; empty means all channels.
labelstringIts name.
isActivebooleanA paused subscription receives nothing.
lastDeliveredAtstringThe last successful call, ISO 8601, or
null.lastErrorstringWhat went wrong last time, or
null.previousSecretValidUntilstringDuring a rotation: until when the old secret still signs.
nullotherwise.createdAtstringISO 8601.
{ "id": "…", "url": "…", "events": [ "…" ], "channelIds": [ "…" ], "label": "…", "isActive": true, "lastDeliveredAt": "…", "lastError": "…", "previousSecretValidUntil": "…", "createdAt": "…"}WebhookDelivery
One event delivered — or to deliver — to one subscription.
idstringThe delivery id, also sent as
X-Nodium-Delivery.subscriptionIdstringThe subscription.
eventstringThe event name.
eventIdstringThe event's own id (
evt_…), the same across redeliveries: deduplicate on it.statusstringfailedafter six attempts.pendingdeliveredfailedattemptsintegerAttempts so far.
responseStatusintegerThe HTTP status your server answered, or
null.lastErrorstringWhat went wrong, or
null.nextAttemptAtstringWhen the next attempt is due, for a pending delivery.
createdAtstringISO 8601.
deliveredAtstringISO 8601, or
null.
{ "id": "…", "subscriptionId": "…", "event": "…", "eventId": "…", "status": "pending", "attempts": 0, "responseStatus": 0, "lastError": "…", "nextAttemptAt": "…", "createdAt": "…", "deliveredAt": "…"}ApiRequest
One call made with an API key.
idstringThe log line id.
apiKeyIdstringThe key used.
keyLabelstringThe key's label.
keyPrefixstringThe key's public prefix,
nod_….clientIdstringThe client the call acted on, or
nullfor an account-level call (/tenants,/keys).methodstringHTTP method.
pathstringThe address called, without its query string.
statusintegerThe HTTP status returned.
errorCodestringThe error
codereturned, ornull.durationMsintegerHow long it took.
requestIdstringThe request id, also returned in errors.
createdAtstringISO 8601.
{ "id": "…", "apiKeyId": "…", "keyLabel": "…", "keyPrefix": "…", "clientId": "…", "method": "…", "path": "…", "status": 0, "errorCode": "…", "durationMs": 0, "requestId": "…", "createdAt": "…"}ApiKey
An API key of your account. Its secret is shown once, at creation, and never again.
idstringThe key id.
labelstringA name for you, shown in Nodium.
keyPrefixstringThe public prefix of the secret,
nod_…: enough to recognise the key, not to use it.clientIdstringThe client the key is pinned to, or
null: every client of the account, named with theNodium-Tenantheader ("My company" without it).clientNamestringThe name of that client, or
null.isActivebooleanfalseonce revoked.createdBystringWho created it, or
nullwhen a key did.lastUsedAtstringIts last call, ISO 8601, or
nullif never used.revokedAtstringWhen it was revoked, ISO 8601, or
null.expiresAtstringWhen it stops working, ISO 8601, or
nullif it never expires.isActiveisfalseonce this date has passed.createdAtstringISO 8601.
{ "id": "…", "label": "…", "keyPrefix": "…", "clientId": "…", "clientName": "…", "isActive": true, "createdBy": "…", "lastUsedAt": "…", "revokedAt": "…", "expiresAt": "…", "createdAt": "…"}Tenant
One of your customers: a client of your account, isolated from the others.
idstringThe tenant id — what the
Nodium-Tenantheader accepts, with yourexternalId.externalIdstringYour identifier for this customer, or
null. Unique in your account.namestringYour customer's name.
slugstringIts address in the Nodium console. Follows the name.
statusstringA suspended tenant neither sends nor receives.
activesuspendedlocalestringLanguage of the hosted connect page.
frentimezonestringIANA time zone.
whatsappobjectIts WhatsApp state.
Show fields
statusstringconnected: at least one number;link_sent: a connect link is waiting;not_connected: neither.connectedlink_sentnot_connectednumbersintegerHow many WhatsApp numbers are connected.
displayPhonestringThe first connected number, as displayed, or
null.
connectLinkobjectIts latest hosted connect link, or
nullif none was ever created.Show fields
statestringpending: still usable;used: it connected a number;expired: it can no longer be used.pendingusedexpiredexpiresAtstringWhen it stops working, ISO 8601.
usedAtstringWhen it was used, ISO 8601, or
null.createdAtstringISO 8601.
activeThisMonthbooleanWhether it sent or received a message in the current UTC month.
eventsThisMonthintegerIts messages in the current UTC month.
createdAtstringISO 8601.
updatedAtstringISO 8601.
{ "id": "…", "externalId": "…", "name": "…", "slug": "…", "status": "active", "locale": "fr", "timezone": "…", "whatsapp": { "status": "connected", "numbers": 0, "displayPhone": "…" }, "connectLink": { "state": "pending", "expiresAt": "…", "usedAt": "…", "createdAt": "…" }, "activeThisMonth": true, "eventsThisMonth": 0, "createdAt": "…", "updatedAt": "…"}Error
Every refusal of `/api/v1`.
errorobjectWhat went wrong.
Show fields
statusintegerThe HTTP status, repeated.
codestringA stable code. Test this, never the text.
messagestringWhat it means, in English: the same sentence for a given code.
detailstringThe specific reason for this call, in English. A few refusals not translated yet still carry a French reason.
nullforrate_limited,quota_exceededandplan_limit(messageanddatasay it all), and for an unexpected 500.paramstringThe field of the body or query that was refused (
to,type,location.latitude,variables.1);nullwhen the refusal is not about one field.doc_urlstringThe line of the guide « Responses and errors » that explains
code;nullfor a code the guide does not list.requestIdstringQuote it to us if you need help.
dataobjectExtra facts attached to some refusals (e.g.
issues).
{ "error": { "status": 0, "code": "…", "message": "…", "detail": "…", "param": "…", "doc_url": "…", "requestId": "…", "data": {} }}