Privacy and analytics

We use necessary technical cookies and, only with your consent, analytics and marketing pixels to improve the website and measure campaigns.

Privacy policyCookie policy
Docs
English
EspañolEnglishFrançaisDeutschItalianoPortuguês

Getting started

  • What is Nömad?
  • Getting started with Nömad
  • Create your brand and complete the Genome
  • Invite your team
  • Glossary

Brand OS

  • What is inside Brand OS
  • What is the Genome?
  • Who is Nödo?
  • Messages: your team and Nödo
  • What does a Brand Manager do?
  • Brand Kit and Library
  • Posts and calendar
  • Connections
  • Meetings
  • Files we send you with NödoTransfer

Work

  • Work and tasks
  • Ordering work
  • Following, reviewing and approving deliveries
  • Approving the posts Nömad prepares
  • Custom quotes
  • Brand history
  • Yes, there are humans behind it

Account and billing

  • Plans and pricing
  • Billing and payments
  • People and access
  • Organization and brand roles
  • Workspaces and multiple brands
  • Your name and @username
  • Languages, apps and data
  • Leave, close or delete: account, brands and workspaces
  • Notifications: how we let you know
  • Push notifications on your phone and browser
  • Nömad emails and your preferences

Help

  • How to get help

API

  • Brand API
    • Errors
    • Permissions and roles
    • Events and webhooks
    • Brand
    • Genome
    • Brand Kit
    • Library
    • Works
    • Calendar
    • Connections
    • Publishing
    • Inbox
    • Team
    • Account and team
    • Conversation
    • Memory
    • Questions
    • Media
    • Store
    • Plan
    • Orders
    • Activity
    • Workspace
    • Your account
    • Billing
    • Sync
    • Website and domains
    • Events

MCP

  • MCP server

Connectors

  • Brand connectors

Nödo and agents

  • Nödo in the brand

Genome

  • Genome specification
API/Brand API
Guide2 min read

Events and webhooks

What changes, in order, and signed notices to your systems.

On this page
  • The event
  • Read in order
  • Webhooks
  • Verify the signature

Updated on January 1, 1970

Русский
한국어
日本語
中文
हिन्दी
Open the app
Previous
Permissions and roles
NextBrand

In this section

  • Errors
  • Permissions and roles
  • Brand
  • Genome
  • Brand Kit
  • Library
  • Works
  • Calendar
Can't find what you need? Write to usWrite to usGo to the app
© 2026 Nömad · Nömad documentationLinkedInInstagramThreadsFacebookTikTokYouTubeX
Go to nomad.oooBack to top

On this page

  • The event
  • Read in order
  • Webhooks
  • Verify the signature

Every change made in Nömad (through the screens, the API, the MCP or Nödo) leaves an ordered event: <entity>.<verb>, who did it, where and which records it touched (their ids and the names of the fields, never their values). Read events with events.list from a cursor, or receive them in your system with a signed webhook. The log keeps 30 days.

The event

{
  "id": "1042",
  "object": "event",
  "type": "works.tasks.update",
  "schema_version": 1,
  "operation": "works.tasks.update",
  "plane": "client",
  "occurred_at": "2026-10-26T12:00:00Z",
  "actor": {
    "kind": "person",
    "id": "…",
    "client": null
  },
  "door": "web",
  "scope": "brand",
  "brand_id": "…",
  "workspace_id": "…",
  "data": {
    "object_ids": [
      "…"
    ],
    "changed_fields": [
      "title",
      "status"
    ]
  },
  "request_id": "…"
}

You only see events of what you can read, with the same keys as the records. For the data, read the record with its operation.

Read in order

  • events.list with after = the last id you read; next_cursor is the next one. It advances even when there is nothing you can see.
  • from_now: true returns the current cursor: take it before copying the state and follow from it.
  • cursor_expired: your cursor is older than the log. Copy the state again.

Webhooks

  • In the workspace › Developers (or with workspace.webhooks.create): a public HTTPS address and the types: *, an exact one or a prefix works.*. You can limit it to some brands.
  • The secret (whsec_…) is shown once. Rotating keeps the previous one signing for 24 h.
  • Each POST carries Nomad-Signature: t=<unix>,v1=<hex>: HMAC-SHA256 of <t>.<body>. Reject signatures older than 300 s. Also Nomad-Event-Id, Nomad-Event-Type, Nomad-Delivery-Id and Nomad-Delivery-Attempt.
  • Answer 2xx within 10 s. Otherwise we retry after 1 min, 5 min, 30 min, 2 h, 5 h, 10 h, 10 h, 24 h. An endpoint failing for 3 days in a row turns off; turn it on once fixed.
  • Use Nomad-Event-Id to avoid processing the same event twice: a retry or a replay repeats it.

Verify the signature

import { createHmac, timingSafeEqual } from 'node:crypto'

// header = request.headers['nomad-signature'], body = the raw request body
export function verify(body, header, secret, now = Math.floor(Date.now() / 1000)) {
  const pairs = header.split(',').map((part) => part.split('='))
  const t = Number(pairs.find(([key]) => key === 't')?.[1])
  if (!t || Math.abs(now - t) > 300) return false
  const expected = createHmac('sha256', secret).update(`${t}.${body}`).digest()
  return pairs.filter(([key]) => key === 'v1').some(([, value]) => {
    const given = Buffer.from(value, 'hex')
    return given.length === expected.length && timingSafeEqual(given, expected)
  })
}