Create webhook

Learn how to create a webhook in NocoDB.

Accessing webhook page

  1. Click on table for which webhook needs to be configured on the left sidebar
  2. Open Details tab in topbar,
  3. Click on Webhooks tab
  4. Click Add New Webhook

Accessing webhook

Configuring webhook

Configuring webhook

  1. Name the webhook - Give a clear & descriptive name.

  2. Select the Trigger Source type :

    Trigger Source type View and Field are only available in the cloud & self-hosted enterprise plans.

    • Record - Triggers when a record is inserted, updated, or deleted, or for all actions if “Send me everything” is selected.
    • View - Triggers when a view is created, updated, or deleted, or for all actions if “Send me everything” is selected.
    • Field - Triggers when a field is created, updated, or deleted, or for all actions if “Send me everything” is selected.
    • Manual Trigger / Button Trigger - Trigger runs when a user manually clicks a webhook configured button.
  3. Select Trigger Event type : Refer table here for available events for each source

  4. [Optional] Trigger based on condition : details here

    Conditions are only applicable for Record trigger source events

    • Specify the condition for which webhook should be triggered
    • You can select multiple conditions
    • If no condition is selected, webhook will be triggered for all records
  5. [Optional] Trigger for updates in specific fields : details here

    This is only applicable for Record After Update event.

    • Select the fields for which webhook should be triggered.
    • If no field is selected, any field update will trigger webhook
  6. [Optional] Trigger only when specific form submitted: details here

    This is only applicable for Record After Insert event.

    • Select the form for which webhook should be triggered.
  7. Webhook Action : Select the action to be performed when webhook is triggered. Action can be one of the following:

    • HTTP Request : Send an HTTP request to a specified URL. You can configure the HTTP method, headers, parameters, and body of the request.

      • Method & URL : Specify the endpoint that the webhook will call when triggered. You can choose from the following HTTP methods: GET, POST, PUT, DELETE, PATCH, and HEAD.
      • Headers & Parameters : Configure Request headers & parameters
      • Body : Configure request body. You can use handlebar syntax to access and manipulate the data easily. For example, {{ json event }} will give you the complete event data (default behaviour if body not configured).
    • Run Script : Run a custom script using NocoDB's built-in scripting engine. You can write JavaScript code to perform various actions when the webhook is triggered.

      • Script : Select the script to be executed when the webhook is triggered. You can create and manage scripts in the Scripts tab in the left sidebar.
  8. [Optional] Click Test webhook button to verify if parameter are configured appropriately (with sample payload)

  9. Click Create Webhook button to complete webhook creation

Trigger Source and Event

Webhooks in NocoDB can be configured based on the source of the trigger and the type of event. The table below outlines the available combinations:

Trigger Source type View and Field are only available in the cloud & self-hosted enterprise plans.
Trigger SourceTrigger EventDescription
RecordSend Me EverythingTriggers on any record insert, update, or delete operation
After InsertTriggers after one or more records are inserted
After UpdateTriggers after one or more records are updated
After DeleteTriggers after one or more records are deleted
ViewSend Me EverythingTriggers on any view create, update, or delete operation
After CreateTriggers after a view is created
After UpdateTriggers after a view is updated
After DeleteTriggers after a view is deleted
FieldSend Me EverythingTriggers on any field create, update, or delete operation
After CreateTriggers after a field is created
After UpdateTriggers after a field is updated
After DeleteTriggers after a field is deleted
Button TriggerTriggers when a button field is clicked

For more details on using Button Trigger webhooks with the Button field, see the Button field documentation.

Webhook with conditions

Webhooks (record trigger related) in NocoDB can be configured to trigger only when specific conditions are met. For example, you may choose to trigger a webhook only when the Status field is set to Complete. You can define multiple conditions using logical operators like AND or OR—such as triggering the webhook on record update only when Status is Complete and Priority is High.

Webhook with conditions

A webhook will only be triggered if the condition transitions from not met to met during a record event. For instance (for above example), if the original record has Status = Complete and Priority = Low, and you update it to Priority = High, the webhook will trigger—since the condition was not met before but is met after the update. However, if a record already satisfies the condition (Status = Complete and Priority = High) and you update unrelated fields, the webhook will not be triggered.

In short, a webhook is triggered only when the condition changes from false (old record) to true (new record).

Conditions are not applicable for Manual Trigger webhook.

Webhook on field changes ☁

This feature is only available in the paid plans, in both cloud & self-hosted.

For After Update event, you can configure webhook to trigger only when certain fields are updated. For example, trigger webhook only when Status is updated. You can also configure multiple fields.

Webhook on field changes

Webhook on specific form submission ☁

This feature is only available in the paid plans, in both cloud & self-hosted.

For After Insert event, you can configure webhook to trigger only when a specific form is submitted. For example, if you have multiple forms for a table, you can choose to trigger webhook only when Form A is submitted.

Webhook on specific form submission

Webhook with custom payload ☁

This feature is only available in cloud & self-hosted enterprise plans.

Custom payload lets you fully control the body a webhook sends when an event is triggered. You can send the entire event object, a specific field, a compact row summary, or transform rows into arrays/objects that downstream services expect.

NocoDB exposes the current event as event inside custom payload. These are processed with Handlebars-like expressions and a built-in json helper (examples below).

Example event object

This is the sample event generated by NocoDB after a record is inserted.

{
  "type": "records.after.insert",
  "id": "0698517a-d83a-4e72-bf7a-75f46b704ad1",
  "version": "v3",
  "data": {
    "table_id": "m969t01blwprpef",
    "table_name": "Table-2",
    "view_id": "vwib3bvfxdqgymun",
    "view_name": "Table-2",
    "rows": [
      {
        "Id": 1,
        "Tags": "Sample Text",
        "CreatedAt": "2024-04-11T10:40:20.998Z",
        "UpdatedAt": "2024-04-11T10:40:20.998Z"
      }
    ]
  }
}

In custom payload, you will typically access paths such as event.data.table_name or event.data.rows.[0].Tags.

Adding a custom payload

To add a custom payload, open your webhook in NocoDB's UI and follow these steps:

  1. Click on the Body tab
  2. Enter your template using Handlebars expressions and the json helper.
  3. Create/update Webhook or use the Test Webhook action to verify rendering.

Webhook custom payload

Some applications require specific headers to process webhook payloads correctly. For example, if you're sending JSON data, ensure you include the appropriate Content-Type header in your webhook configuration (commonly application/json).

The json helper is used to safely serialize values into valid JSON, whether they’re strings, objects, or arrays. It ensures proper quoting and escaping, preventing common errors with quotes, newlines, or special characters. For example, {{ json event }} outputs the full event object, while {{ json event.data.rows.[0].Title }} safely inserts a single field as a JSON string. This makes it the most reliable way to embed dynamic values in webhook payloads.

Handlebars expressions allow you to dynamically access and manipulate data within templates, similar to how the json helper works for serialization. You can reference fields using dot or bracket notation, iterate over arrays with {{#each ...}}, and conditionally include content with {{#if ...}}. Learn more about using Handlebars expressions in Handlebars documentation.

Examples

Here are some common payload templates you can use as a starting point:

  1. Full event object: Sends the complete event data as JSON
{
  "event": {{ json event }}
}
  1. Single field value: Sends just the Title field of the first row
{
  "content": {{ json event.data.rows.[0].Title }}
}
  1. Compact row summary: Sends all fields of the first row as a JSON object
{
  "row": {{ json event.data.rows.[0] }}
}
  1. All rows as array: Sends all rows in the event as a JSON array
{
  "rows": {{ json event.data.rows }}
}
  1. Custom object with metadata: Sends an object with table name, row count, and all rows
{
  "table": {{ json event.data.table_name }},
  "count": {{ json event.data.rows.length }},
  "rows": {{ json event.data.rows }}
}
  1. Custom text with field value: Sends a simple message including the Title field
{
  "message": "New record created with title: {{ event.data.rows.[0].Title }}"
}
  1. Handlebar logic example: Sends different payloads based on whether rows exist
{{#if event.data.rows.length}}
{
  "hasRows": true,
  "rows": {{ json event.data.rows }}
}
{{else}}
{
  "hasRows": false
}
{{/if}}
  1. Multiple rows with formatting: Sends all rows with only Id and Title, formatted as a JSON array
{
  "records": [
    {{#each event.data.rows}}
      {{#if @first}}{{else}},{{/if}}
      {
        "Id": {{ Id }},
        "Title": {{ json Title }}
      }
    {{/each}}
  ]
}

Webhook response sample

Record trigger

{
  "type": "records.after.insert",
  "id": "c245c528-8759-4e10-b7d5-e2626dd7c321",
  "version": "v3",
  "data": {
    "table_id": "mbmppjnstflsqq1",
    "table_name": "Features",
    "rows": [
      {
        "Id": 4,
        "CreatedAt": "2025-05-07 17:18:37+00:00",
        "UpdatedAt": null,
        "Title": "Task-2",
        "Status": "Ongoing",
        "Priority": "Low"
      }
    ]
  }
}
{
  "type": "records.after.update",
  "id": "f5e6a827-fb37-4a04-8cd9-be7831f9d897",
  "version": "v3",
  "data": {
    "table_id": "mbmppjnstflsqq1",
    "table_name": "Features",
    "previous_rows": [
      {
        "Id": 3,
        "CreatedAt": "2025-05-07 17:18:33+00:00",
        "UpdatedAt": null,
        "Title": null,
        "Status": null,
        "Priority": null
      }
    ],
    "rows": [
      {
        "Id": 3,
        "CreatedAt": "2025-05-07 17:18:33+00:00",
        "UpdatedAt": "2025-05-07 17:18:37+00:00",
        "Title": "Task-1",
        "Status": "Complete",
        "Priority": "High"
      }
    ]
  }
}
{
  "type": "records.after.delete",
  "id": "4cad2ff8-9ee6-4889-8c85-9969361a1df0",
  "version": "v3",
  "data": {
    "table_id": "mbmppjnstflsqq1",
    "table_name": "Features",
    "rows": [
      {
        "Title": "Task-2",
        "Id": 2,
        "Status": "Ongoing",
        "Priority": "Low"
      },
      {
        "Title": "Task-1",
        "Id": 3,
        "Status": "Complete",
        "Priority": "High"
      }
    ]
  }
}

View trigger

{
  "type": "view.after.create",
  "id": "2f62c921-4dcc-4f37-8e3d-fd3612aaf269",
  "version": "v3",
  "data": {
    "table_id": "ma334932sjnwp3e",
    "table_name": "AllTypes",
    "views": [
      {
        "id": "vw45okb4letthls6",
        "table_id": "ma334932sjnwp3e",
        "title": "Grid-1",
        "type": "grid",
        "lock_type": "collaborative",
        "created_at": "2025-09-22 06:51:13+00:00",
        "updated_at": "2025-09-22 06:51:13+00:00",
        "description": "Grid view sample description",
        "created_by": "usq6o3vavwf0twzr",
        "fields": [
          {
              "field_id": "cc5i4wkzktyqedh",
              "show": true
          },
          {
              "field_id": "ct41ytilwlxf7u3",
              "show": true
          },
          {
              "field_id": "cmbcaa8aoxtpdr9",
              "show": true
          }
        ],
        "options": {
          "row_height": "short"
        }
      }
    ]
  }
}
{
  "type": "view.after.update",
  "id": "08faf0d1-6c02-4f66-8851-2e6405c6c76b",
  "version": "v3",
  "data": {
    "table_id": "ma334932sjnwp3e",
    "table_name": "AllTypes",
    "previous_views": [
      {
        "id": "vw45okb4letthls6",
        "table_id": "ma334932sjnwp3e",
        "title": "Grid-1",
        "type": "grid",
        "lock_type": "collaborative",
        "created_at": "2025-09-22 06:51:13+00:00",
        "updated_at": "2025-09-22 06:51:13+00:00",
        "description": "",
        "created_by": "usq6o3vavwf0twzr",
        "fields": [
          {
            "field_id": "cc5i4wkzktyqedh",
            "show": true
          },
          {
            "field_id": "ct41ytilwlxf7u3",
            "show": true
          }
        ],
        "options": {
          "row_height": "short"
        }
      }
    ],
    "views": [
      {
        "id": "vw45okb4letthls6",
        "table_id": "ma334932sjnwp3e",
        "title": "Grid-1 Renamed",
        "type": "grid",
        "lock_type": "collaborative",
        "created_at": "2025-09-22 06:51:13+00:00",
        "updated_at": "2025-09-22 07:08:29+00:00",
        "description": "",
        "created_by": "usq6o3vavwf0twzr",
        "fields": [
          {
            "field_id": "cc5i4wkzktyqedh",
            "show": true
          },
          {
            "field_id": "ct41ytilwlxf7u3",
            "show": true
          }
        ],
        "options": {
          "row_height": "short"
        }
      }
    ]
  }
}
{
  "type": "view.after.delete",
  "id": "af6a6298-91e9-4642-a729-93fb0eae9d61",
  "version": "v3",
    "data": {
    "table_id": "ma334932sjnwp3e",
    "table_name": "AllTypes",
    "views": [
      {
        "id": "vw45okb4letthls6",
        "table_id": "ma334932sjnwp3e",
        "title": "Grid-1 Renamed",
        "type": "grid",
        "lock_type": "collaborative",
        "created_at": "2025-09-22 06:51:13+00:00",
        "updated_at": "2025-09-22 07:08:29+00:00",
        "description": "",
        "created_by": "usq6o3vavwf0twzr",
        "fields": [
          {
            "field_id": "cc5i4wkzktyqedh",
            "show": true
          },
          {
            "field_id": "ct41ytilwlxf7u3",
            "show": true
          }
        ],
        "options": {
          "row_height": "short"
        }
      }
    ]
  }
}

Field trigger

{
  "type": "field.after.create",
  "id": "2e97d383-1d94-48d7-8214-3a7fd013c801",
  "version": "v3",
  "data": {
    "table_id": "ma334932sjnwp3e",
    "table_name": "AllTypes",
    "fields": [
      {
        "id": "cqxah2exzt1lxbz",
        "table_id": "ma334932sjnwp3e",
        "title": "Financial Quarter",
        "type": "SingleSelect",
        "default_value": "'Q1'",
        "system": false,
        "options": {
          "choices": [
            {
              "title": "Q1",
              "color": "#cfdffe",
              "id": "shs9oq0ddo1ecnq"
            },
            {
              "title": "Q2",
              "color": "#d0f1fd",
              "id": "s65lkpm9822w8t7"
            },
            {
              "title": "Q3",
              "color": "#c2f5e8",
              "id": "swg8jzbgh99t36f"
            },
            {
              "title": "Q4",
              "color": "#ffdaf6",
              "id": "s9duce07erlzq5n"
            }
          ]
        },
        "description": "Specifies quarter in which this task is required to be included."
      }
    ]
  }
}
{
  "type": "field.after.update",
  "id": "6a4c9326-0bdc-4920-9089-6340394340b4",
  "version": "v3",
  "data": {
    "table_id": "ma334932sjnwp3e",
    "table_name": "AllTypes",
    "previous_fields": [
      {
        "id": "cqxah2exzt1lxbz",
        "table_id": "ma334932sjnwp3e",
        "title": "Financial Quarter",
        "type": "SingleSelect",
        "default_value": "'Q1'",
        "system": false,
        "options": {
          "choices": [
            {
              "title": "Q1",
              "color": "#cfdffe",
              "id": "shs9oq0ddo1ecnq"
            },
            {
              "title": "Q2",
              "color": "#d0f1fd",
              "id": "s65lkpm9822w8t7"
            },
            {
              "title": "Q3",
              "color": "#c2f5e8",
              "id": "swg8jzbgh99t36f"
            },
            {
              "title": "Q4",
              "color": "#ffdaf6",
              "id": "s9duce07erlzq5n"
            }
          ]
        },
        "description": "Specifies quarter in which this task is required to be included."
      }
    ],
    "fields": [
      {
        "id": "cqxah2exzt1lxbz",
        "table_id": "ma334932sjnwp3e",
        "title": "Financial Quarter",
        "type": "SingleSelect",
        "default_value": "'Quarter-1'",
        "system": false,
        "options": {
          "choices": [
            {
              "title": "Quarter-1",
              "color": "#cfdffe",
              "id": "shs9oq0ddo1ecnq"
            },
            {
              "title": "Quarter-2",
              "color": "#d0f1fd",
              "id": "s65lkpm9822w8t7"
            },
            {
              "title": "Quarter-3",
              "color": "#c2f5e8",
              "id": "swg8jzbgh99t36f"
            },
            {
              "title": "Quarter-4",
              "color": "#ffdaf6",
              "id": "s9duce07erlzq5n"
            }
          ]
        },
        "description": "Specifies quarter in which this task is required to be included."
      }
    ]
  }
}
{
  "type": "field.after.delete",
  "id": "8b2b293f-a926-4280-b116-493ac197ba10",
  "version": "v3",
  "data": {
    "table_id": "ma334932sjnwp3e",
    "table_name": "AllTypes",
    "fields": [
      {
        "id": "cqxah2exzt1lxbz",
        "table_id": "ma334932sjnwp3e",
        "title": "Financial Quarter",
        "type": "SingleSelect",
        "default_value": "'Quarter-1'",
        "system": false,
        "options": {
          "choices": [
            {
              "title": "Quarter-1",
              "color": "#cfdffe",
              "id": "shs9oq0ddo1ecnq"
            },
            {
              "title": "Quarter-2",
              "color": "#d0f1fd",
              "id": "s65lkpm9822w8t7"
            },
            {
              "title": "Quarter-3",
              "color": "#c2f5e8",
              "id": "swg8jzbgh99t36f"
            },
            {
              "title": "Quarter-4",
              "color": "#ffdaf6",
              "id": "s9duce07erlzq5n"
            }
          ]
        },
        "description": "Specifies quarter in which this task is required to be included."
      }
    ]
  }
}

Manual trigger

{
  "type": "records.manual.trigger",
  "id": "551a2010-d658-4185-a050-cf3fca56a5a9",
  "version": "v3",
  "data": {
    "table_id": "mzo4r3zrbcph43i",
    "table_name": "Features",
    "rows": [
      {
        "Id": 1,
        "Title": "dstala",
        "CreatedAt": "2024-08-12 11:56:15+00:00",
        "UpdatedAt": "2024-08-12 11:56:48+00:00",
        "Button": {
          "type": "url",
          "label": "Button",
          "url": "https://github.com/dstala"
        },
      }
    ]
  }
}

Discord Webhook

Discord webhook can be configured to send messages to a Discord channel. Discord request body should contain content, embeds or attachments, otherwise request will fail. Below is an example of Discord webhook payload. More details can be found here

{
  "content": "Hello, this is a webhook message",
  "embeds": [
    {
      "title": "Webhook",
      "description": "This is a webhook message",
      "color": 16711680
    }
  ]
}

To send complete event data to Discord, use below payload

{
  "content" : {{ json ( json event ) }}
}

One can also customize the payload as per the requirement. For example, to send only the Title field to Discord, use below payload. Note that, the value of content is what that will get displayed in the Discord channel.

{
   "content": "{{ event.data.rows.[0].Title }}"
}

Environment Variables

In self-hosted version, you can configure the following environment variables to customize the webhook behavior.

  • NC_ALLOW_LOCAL_HOOKS: Allow localhost based links to be triggered. Default: false

Find more about environment variables here