N8n Webhooks
Register (or update) an n8n webhook for ERP entity changes.
POST/api/nodered/webhook
Expects JSON body: { "webhook_url": "https://n8n.example.com/webhook/inwendo-erp", "reference_class_name": "CRMCompany", // optional, null = all classes "database_action": "update", // optional, null = all actions "webhook_token": "...", // optional shared secret "delivery": "mqtt", // Node-RED only: over the ERP's MQTT broker "instance_id": "..." // mqtt only, instead of webhook_url }
database_action may also be a timed booking event (booking_pre_start, booking_start, booking_end, booking_post_end or booking_timed for all four, integration_booking_timed_events_enabled); such a webhook gets only those events.
With delivery mqtt (integration_mqtt_trigger_enabled) the ERP publishes the webhook on its broker and the answer carries "mqtt" (url, username, password, client_id, topic, valid_until) like the lock bridge's registration; the node registers again before valid_until.
If a non-deleted webhook with the same notificationUrl and notificationClientId = 'n8n' already exists, it is updated in place (or returned unchanged if every field already matches).
Responses
default
curl --request POST \
--url https://your-instance.iw-erp.de/api/nodered/webhook \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'POST', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/nodered/webhook', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/nodered/webhook"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.post(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://your-instance.iw-erp.de/api/nodered/webhook', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/nodered/webhook"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/nodered/webhook")
.post(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/nodered/webhook"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with package:http (no controller in the iw_erp_api package)
import 'package:http/http.dart' as http;
final response = await http.post(
Uri.parse('https://your-instance.iw-erp.de/api/nodered/webhook'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);Unregister all n8n webhooks for a given webhook URL.
DELETE/api/nodered/webhook
Expects JSON body: { "webhook_url": "https://n8n.example.com/webhook/inwendo-erp" } or, for a Node-RED trigger with MQTT delivery, {"instance_id": "..."}.
Soft-deletes all non-deleted rows whose notificationUrl matches and whose notificationClientId is 'n8n'. Other clients' webhooks are untouched.
Responses
default
curl --request DELETE \
--url https://your-instance.iw-erp.de/api/nodered/webhook \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'DELETE', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/nodered/webhook', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/nodered/webhook"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.delete(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://your-instance.iw-erp.de/api/nodered/webhook', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Delete,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/nodered/webhook"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/nodered/webhook")
.delete(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/nodered/webhook"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with package:http (no controller in the iw_erp_api package)
import 'package:http/http.dart' as http;
final response = await http.delete(
Uri.parse('https://your-instance.iw-erp.de/api/nodered/webhook'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);Register (or update) an n8n webhook for ERP entity changes.
POST/api/n8n/webhook
Expects JSON body: { "webhook_url": "https://n8n.example.com/webhook/inwendo-erp", "reference_class_name": "CRMCompany", // optional, null = all classes "database_action": "update", // optional, null = all actions "webhook_token": "...", // optional shared secret "delivery": "mqtt", // Node-RED only: over the ERP's MQTT broker "instance_id": "..." // mqtt only, instead of webhook_url }
database_action may also be a timed booking event (booking_pre_start, booking_start, booking_end, booking_post_end or booking_timed for all four, integration_booking_timed_events_enabled); such a webhook gets only those events.
With delivery mqtt (integration_mqtt_trigger_enabled) the ERP publishes the webhook on its broker and the answer carries "mqtt" (url, username, password, client_id, topic, valid_until) like the lock bridge's registration; the node registers again before valid_until.
If a non-deleted webhook with the same notificationUrl and notificationClientId = 'n8n' already exists, it is updated in place (or returned unchanged if every field already matches).
Responses
default
curl --request POST \
--url https://your-instance.iw-erp.de/api/n8n/webhook \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'POST', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/n8n/webhook', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/n8n/webhook"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.post(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://your-instance.iw-erp.de/api/n8n/webhook', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/n8n/webhook"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/n8n/webhook")
.post(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/n8n/webhook"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with package:http (no controller in the iw_erp_api package)
import 'package:http/http.dart' as http;
final response = await http.post(
Uri.parse('https://your-instance.iw-erp.de/api/n8n/webhook'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);Unregister all n8n webhooks for a given webhook URL.
DELETE/api/n8n/webhook
Expects JSON body: { "webhook_url": "https://n8n.example.com/webhook/inwendo-erp" } or, for a Node-RED trigger with MQTT delivery, {"instance_id": "..."}.
Soft-deletes all non-deleted rows whose notificationUrl matches and whose notificationClientId is 'n8n'. Other clients' webhooks are untouched.
Responses
default
curl --request DELETE \
--url https://your-instance.iw-erp.de/api/n8n/webhook \
--header 'x-iw-jwt-token: <TOKEN>'const options = {method: 'DELETE', headers: {'x-iw-jwt-token': '<TOKEN>'}};
fetch('https://your-instance.iw-erp.de/api/n8n/webhook', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://your-instance.iw-erp.de/api/n8n/webhook"
headers = {"x-iw-jwt-token": "<TOKEN>"}
response = requests.delete(url, headers=headers)
print(response.text)<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://your-instance.iw-erp.de/api/n8n/webhook', [
'headers' => [
'x-iw-jwt-token' => '<TOKEN>',
],
]);
echo $response->getBody();using System.Net.Http.Headers;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Delete,
RequestUri = new Uri("https://your-instance.iw-erp.de/api/n8n/webhook"),
Headers =
{
{ "x-iw-jwt-token", "<TOKEN>" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
}OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://your-instance.iw-erp.de/api/n8n/webhook")
.delete(null)
.addHeader("x-iw-jwt-token", "<TOKEN>")
.build();
Response response = client.newCall(request).execute();package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-instance.iw-erp.de/api/n8n/webhook"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("x-iw-jwt-token", "<TOKEN>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}Dart with package:http (no controller in the iw_erp_api package)
import 'package:http/http.dart' as http;
final response = await http.delete(
Uri.parse('https://your-instance.iw-erp.de/api/n8n/webhook'),
headers: {'x-iw-jwt-token': '<TOKEN>'},
);
print(response.body);