Skip to main content
npayload is launching soon.
npayloadDocs
Concepts

Event catalogue

Schema registry with versioning, validation, and governance for message payloads

The event catalogue is a centralized registry of event types and their schemas. It defines the structure of messages flowing through your channels, validates payloads at publish time, and tracks schema evolution over time.

What the event catalogue provides

CapabilityDescription
Schema registrationDefine the expected structure of message payloads using JSON Schema
VersioningTrack schema changes with semantic versioning
ValidationReject messages that do not conform to the registered schema
DiscoveryBrowse available event types and their documentation
GovernanceControl who can publish specific event types

Registering an event type

Define an event type with a name, version, and JSON Schema describing the payload.

await npayload.eventCatalogue.register({
  name: 'order.created',
  version: '1.0.0',
  description: 'Published when a new order is placed',
  schema: {
    type: 'object',
    required: ['orderId', 'customerId', 'items', 'total'],
    properties: {
      orderId: { type: 'string' },
      customerId: { type: 'string' },
      items: {
        type: 'array',
        items: {
          type: 'object',
          required: ['sku', 'quantity', 'price'],
          properties: {
            sku: { type: 'string' },
            quantity: { type: 'integer', minimum: 1 },
            price: { type: 'number', minimum: 0 },
          },
        },
      },
      total: { type: 'number', minimum: 0 },
    },
  },
});

Schema versioning

Event types follow semantic versioning (semver). When you update a schema, you publish a new version.

Version bumpWhen to useExample
Patch (1.0.0 to 1.0.1)Documentation changes, no structural changesUpdated field descriptions
Minor (1.0.0 to 1.1.0)New optional fields addedAdded optional couponCode field
Major (1.0.0 to 2.0.0)Breaking changes (removed or renamed fields)Renamed customerId to buyerId
// Register a new version with an additional optional field
await npayload.eventCatalogue.register({
  name: 'order.created',
  version: '1.1.0',
  description: 'Published when a new order is placed',
  schema: {
    type: 'object',
    required: ['orderId', 'customerId', 'items', 'total'],
    properties: {
      orderId: { type: 'string' },
      customerId: { type: 'string' },
      items: { type: 'array', items: { type: 'object' } },
      total: { type: 'number', minimum: 0 },
      couponCode: { type: 'string' },  // New optional field
    },
  },
});

Payload validation

When a channel is linked to an event type, npayload validates every published message against the registered schema. Invalid messages are rejected before delivery.

// Link a channel to an event type
await npayload.channels.create({
  name: 'orders',
  eventType: 'order.created',
  eventVersion: '1.x', // Accept any 1.x version
});

// This succeeds (valid payload)
await npayload.messages.publish({
  channel: 'orders',
  payload: {
    orderId: 'ord_123',
    customerId: 'cust_456',
    items: [{ sku: 'WIDGET-001', quantity: 2, price: 29.99 }],
    total: 59.98,
  },
});

// This is rejected (missing required field 'total')
await npayload.messages.publish({
  channel: 'orders',
  payload: {
    orderId: 'ord_124',
    customerId: 'cust_789',
    items: [{ sku: 'WIDGET-002', quantity: 1, price: 15.00 }],
    // Missing 'total' field
  },
});
// Throws: ValidationError: payload.total is required

Schema validation happens before fan-out. Invalid messages never reach subscribers, reducing noise and preventing downstream errors.

Schema evolution rules

npayload enforces compatibility rules to prevent breaking changes from affecting existing consumers.

RuleDescription
Backward compatibleNew schema can read data written by the old schema
Forward compatibleOld schema can read data written by the new schema
Full compatibleBoth backward and forward compatible

Major version bumps (breaking changes) require all active subscribers to acknowledge the new schema before it becomes the default. This prevents silent breakage.

Discovering event types

Browse the catalogue to find available event types, their schemas, and which channels use them.

// List all registered event types
const types = await npayload.eventCatalogue.list();

// Get details for a specific event type
const orderCreated = await npayload.eventCatalogue.get('order.created');

console.log(orderCreated.name);        // 'order.created'
console.log(orderCreated.versions);    // ['1.0.0', '1.1.0']
console.log(orderCreated.channels);    // ['orders']
console.log(orderCreated.schema);      // JSON Schema object

// List versions for an event type
const versions = await npayload.eventCatalogue.listVersions('order.created');

Governance

Control which applications and services can publish specific event types. This prevents unauthorized services from publishing events they do not own.

// Restrict who can publish an event type
await npayload.eventCatalogue.setOwnership({
  eventType: 'order.created',
  allowedPublishers: ['order-service', 'checkout-service'],
});

Use cases

Use caseHow the event catalogue helps
API contractsDefine the expected payload structure between services
DocumentationSelf-documenting event types with schemas and descriptions
Type generationGenerate TypeScript types from registered schemas
Data qualityReject malformed messages at the source
ComplianceAudit trail of schema changes and who made them

Next steps

  • Messages to understand how payloads are published and validated
  • Channels to learn how channels link to event types
  • Marketplace to discover and share event types across organisations

Was this page helpful?

On this page