Skip to main content
Kapso returns Meta-compatible objects by default. You can opt in to extra fields by passing the fields=kapso(...) selector on list endpoints. The SDK also ships helpers so you can include the full set with one line.

Helpers

import {
  KAPSO_MESSAGE_FIELDS,
  buildKapsoFields,
  buildKapsoMessageFields
} from '@kapso/whatsapp-cloud-api';

// All default Kapso message fields
const allExtras = buildKapsoFields();

// A subset (example)
const subset = buildKapsoMessageFields('flow_response', 'flow_token');

const page = await client.messages.query({
  phoneNumberId: '123',
  limit: 20,
  fields: allExtras
});
Server-side equivalents: kapso(default), kapso(*), or kapso(all) map to the same default set. Use kapso() to omit Kapso fields.

Message fields

FieldDescription
directionInbound or outbound based on the business number.
statusServer-side message status when available.
processing_statusInternal processing status when available.
phone_numberBusiness phone number for the message.
has_mediaTrue when a media blob is attached.
media_dataURL, filename, content type, and byte size for stored media.
media_urlDirect URL to the attached media. Inbound: immediate. Outbound: appears shortly after send.
whatsapp_conversation_idInternal conversation identifier.
contact_nameDisplay name when known.
message_type_dataPer-type hints such as caption, sticker info, or location values.
flow_responseParsed Flows response JSON.
flow_tokenToken from a Flows response when present.
flow_nameName from a Flows response when present.
order_textOptional note from order messages.

Conversation fields

Use these with fields=kapso(...) on GET /{phone_number_id}/conversations.
FieldDescription
contact_nameDisplay name for the contact linked to the conversation.
messages_countTotal number of stored messages in the conversation.
last_message_idWAMID of the most recent message in the conversation.
last_message_typeType of the most recent message (for example text, image, reaction).
last_message_timestampISO 8601 timestamp of the most recent message.
last_message_textText or caption preview when available (may be empty for non-text types).
last_inbound_atISO 8601 timestamp of the most recent inbound message.
last_outbound_atISO 8601 timestamp of the most recent outbound message.

Examples

All Kapso fields:
await client.messages.query({
  phoneNumberId: '123',
  limit: 20,
  fields: buildKapsoFields() // or 'kapso(default)'
});
Subset only:
await client.messages.query({
  phoneNumberId: '123',
  limit: 20,
  fields: 'kapso(flow_response,flow_token)'
});
Omit Kapso fields:
await client.messages.query({
  phoneNumberId: '123',
  limit: 20,
  fields: 'kapso()'
});

Webhooks

The SDK includes a normalization helper for Meta webhooks. It returns the same structure as history queries and sets kapso.direction. SMB echoes are tagged with kapso.source = "smb_message_echo". Other webhook fields are available under events.raw.<fieldName>.
import { normalizeWebhook, verifySignature } from '@kapso/whatsapp-cloud-api/server';

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  if (!verifySignature({
    appSecret: process.env.META_APP_SECRET!,
    rawBody: req.body,
    signatureHeader: req.headers['x-hub-signature-256'] as string
  })) return res.status(401).end();

  const events = normalizeWebhook(JSON.parse(req.body.toString('utf8')));
  events.messages.forEach(m => console.log(m.type, m.kapso?.direction));
  res.sendStatus(200);
});
I