Skip to main content
npayload is launching soon.
npayloadDocs
Concepts

Messages

JSON payloads published to channels with batch, transactional, and group semantics

A message is a JSON payload published to a channel. Once stored, messages are immutable. npayload handles validation, encryption, fan-out, and delivery tracking automatically.

Publishing a message

const message = await npayload.messages.publish({
  channel: 'orders',
  payload: {
    event: 'order.created',
    orderId: 'ord_123',
    customer: { id: 'cust_456', email: 'customer@example.com' },
    total: 59.98,
  },
});

console.log('Published:', message.gid);

Message properties

PropertyTypeRequiredDescription
channelstringYesChannel name or ID
payloadanyYesJSON payload (max 256 KB)
routingKeystringNoFor subscription filtering (e.g., order.created)
partitionKeystringNoFor ordered delivery within a partition
idempotencyKeystringNoPrevent duplicate messages
prioritynumberNoDelivery priority (higher = first)
groupKeystringNoFIFO ordering within a group
metadataobjectNoTrace IDs, correlation IDs, custom headers

Batch publish

Send up to 100 messages in a single API call. Reduces network overhead and improves throughput.

const result = await npayload.messages.publishBatch({
  channel: 'events',
  messages: [
    { payload: { event: 'user.signup', userId: 'user_1' } },
    { payload: { event: 'user.signup', userId: 'user_2' } },
    { payload: { event: 'user.login', userId: 'user_3' } },
  ],
});

console.log(`${result.succeeded} succeeded, ${result.failed} failed`);

Batch publish supports partial failure: some messages may succeed while others fail. Check the response for per-message status.

Transactional publish

Publish to multiple channels atomically. Either all messages are published or none are. This guarantees consistency across channels.

await npayload.messages.publishTransactional([
  {
    channel: 'orders',
    payload: { event: 'order.created', orderId: 'ord_123' },
  },
  {
    channel: 'inventory',
    payload: { event: 'stock.reserved', sku: 'WIDGET-001', quantity: 2 },
  },
  {
    channel: 'notifications',
    payload: { event: 'order.confirmation', userId: 'cust_456' },
  },
]);

Transactional publish is atomic within a single instance. Cross-instance transactions use eventual consistency with guaranteed delivery.

Message groups

Message groups provide FIFO ordering within a group key. Messages with the same groupKey are delivered in publish order, even when fan-out delivers to multiple subscribers in parallel.

// These messages are delivered in order for groupKey 'cust_456'
await npayload.messages.publish({
  channel: 'orders',
  groupKey: 'cust_456',
  payload: { event: 'order.created', orderId: 'ord_1' },
});

await npayload.messages.publish({
  channel: 'orders',
  groupKey: 'cust_456',
  payload: { event: 'order.paid', orderId: 'ord_1' },
});

Report messages

Report messages provide receipt confirmation from subscribers. When a subscriber processes a message, it can send a report back through npayload, confirming delivery and optionally including processing results.

await npayload.messages.report({
  messageId: 'msg_abc123',
  subscriptionId: 'sub_xyz789',
  status: 'processed',
  result: { fulfillmentId: 'ful_001' },
});

Idempotency

Use idempotencyKey to prevent duplicate messages. If a message with the same key already exists in the retention window, the existing message is returned instead of creating a new one.

await npayload.messages.publish({
  channel: 'payments',
  idempotencyKey: `payment-${paymentId}-completed`,
  payload: { event: 'payment.completed', paymentId },
});

This is essential for systems that may retry publishes (network timeouts, process restarts).

Message lifecycle

StatusDescription
pendingCreated, awaiting fan-out
processingFan-out in progress
deliveredAll deliveries successful
partialSome deliveries failed
failedAll deliveries failed

Payload limits

LimitValue
Max payload size256 KB
Max batch size100 messages
Max batch payload10 MB total

Next steps

Was this page helpful?

On this page