NodeTrigger User Guide

Everything you need to know to filter, transform, and route your webhooks reliably. This guide covers the Webhook Router product — the current flagship feature of NodeTrigger.

Overview

NodeTrigger is a WordPress plugin that acts as a webhook router and proxy. Think of it as a smart middleman between your webhook providers and your downstream tools.

Here's what it does, in one sentence:

You give Stripe/Shopify/etc. one URL, and NodeTrigger verifies the source, evaluates your filter rules, optionally reshapes the data, and forwards it to one or more destinations — all durably and asynchronously.

How It Works (High-Level)

1
Ingest. A provider sends a webhook to your unique NodeTrigger URL. The signature is verified (Stripe/Shopify HMAC), the payload is durably written to disk and queue, and we immediately return 200 OK.
2
Evaluate. NodeTrigger runs your filter rules against the payload. If the event matches, it proceeds to the next stage. If not, it's logged and stopped.
3
Transform. The payload can be reshaped per destination — rename fields, mask sensitive data, inject static values — using {{dot.path}} templating.
4
Deliver. The final payload is forwarded to your destination URLs. Delivery happens asynchronously in the background, with automatic retries on failure.

Quick Start

This assumes NodeTrigger is already installed and activated on your WordPress site. If you haven't installed it yet, follow the standard WordPress plugin installation process.

1
Open the Router Dashboard. Go to the page where you placed the [nodetrigger] shortcode, or navigate to the NodeTrigger admin area if your administrator configured a dedicated page.
2
Create your first Route. Click the "New Route" button and give it a descriptive name (e.g., "Stripe Checkout Events").
3
Copy the Inbound URL. Once created, you'll see a unique URL (e.g., /nodetrigger/v1/route/3/a1b2c3d4...). This is what you'll paste into Stripe/Shopify as the webhook endpoint.
4
Add a Destination. Open the route and add at least one destination URL — this is where filtered events will be forwarded.
5
Activate. Toggle the route to "Active". Your webhook is now live.

Tip: Use Learning Mode (enabled on route creation). Leave the route active without filters, send a real webhook from your provider, then return to the route. The captured sample payload will be available to help you build filter rules visually.

Routes & Inbound URLs

A Route is the core unit of NodeTrigger. Each route represents one inbound webhook URL and its associated rules, filters, transformations, and destinations. You can create as many routes as you need.

Inbound URL Structure

Every route gets a unique URL in the following format:

https://yoursite.com/wp-json/nodetrigger/v1/route/{route_id}/{signature}

Good to know: The signature is generated for you — there's nothing to configure. Just create a route and copy its inbound URL. (If your account's secret key is ever reset by an administrator, existing inbound URLs stop working and you'll need to re-copy the new URL for each route — but this isn't something you do in normal use.)

Route Statuses

StatusMeaning
ActiveRoute is accepting webhooks and processing them normally.
InactiveRoute is paused. Inbound webhooks are still accepted and logged (status paused) but are not forwarded to destinations.
Deleted (soft)Marked as deleted but recoverable. No events are processed.

Provider Source Verification

The inbound endpoint verifies the source signature according to the route's source type. Verification runs only when you've entered a source secret for the route — leave the secret blank and payloads are accepted unverified (true for every source type):

Failed verifications are logged with a red badge so you can see that a misconfigured source is hitting your endpoint — nothing is silently dropped.

Filter Rules

Filters let you decide which webhook events get forwarded and where they go. Without filters, every inbound event is forwarded to every destination (catch-all mode). With filters, you build precise conditional logic.

The Visual Rule Canvas

NodeTrigger provides a drag-and-drop canvas (powered by Drawflow) where you build rules visually:

Source Node — represents the inbound webhook. This is where events enter.
Filter Nodes — define conditions using operators. Each filter has one or more destinations attached.
Destination Nodes — where matching events are sent.

Filter Operators

OperatorDescriptionExample
equalsExact matchtype equals checkout.session.completed
containsString/array contains valueemail contains @gmail.com
existsField is present (non-null)metadata.order_id exists
greater_than / less_thanNumeric comparisonamount > 10000
in_listValue is in a predefined setcurrency in [EUR, GBP, USD]
regexRegular expression matchcustomer_email matches /@company\.com$/

Every operator also has its negation — for example: not_equals, not_contains, not_exists.

Branch Logic: Match All vs. Match Any

A single filter can combine multiple conditions using either:

Branch Array (How Rules Run)

Rules are evaluated as a branch array — each branch is independent. The engine evaluates every branch against the incoming payload, and matching branches fan out to their respective destinations.

The filter engine is decoupled from the visual canvas. Even if you can't load the canvas (e.g., offline or CDN failure), your saved rules still execute normally — only the visual editor is affected.

Payload Transformation

Transformations let you reshape the payload before it reaches each destination. This is useful when different destinations expect different data schemas, or when you need to mask sensitive fields.

Transformation Types

TypeHow It Works
Field Mapping (map) Pull a value from the source payload using dot-path syntax and assign it to a target field. Example: map data.object.customer_emailemail.
Static / Computed (static) Set a field to a fixed value, or use {{dot.path}} templates to interpolate values from the source. Example: "source": "{{event.type}}".
Redaction Remove or mask sensitive keys. Actions: remove (delete the key) or mask (replace value with ***).

Base Mode

You choose whether to start from:

Transform Resolution Order

When multiple transforms exist (global branch transform + per-destination transform), NodeTrigger resolves them as:

1
Per-destination transform (highest priority — if defined for a destination, it's used)
2
Branch-level transform (fallback — if the destination has no custom transform)
3
Raw passthrough (if neither exists, the original payload is forwarded unchanged)

Destinations

A destination is any URL that receives forwarded webhook events. Each destination can have its own payload transformation.

Adding a Destination

Open a route and click on a Destination node in the canvas (or use the pencil icon to open the destination drawer). Enter the target URL — this is typically a webhook endpoint on your CRM, automation tool (n8n, Make), Slack channel, or custom API.

Sending to Multiple Destinations

A single route can fan out to any number of destinations. Each filter branch defines which destinations receive matching events. This means one inbound webhook can:

Legacy compatibility: Destinations stored as plain URL strings (without transform objects) are still accepted and work normally — the payload is forwarded as-is.

Fail-Safe Storage

NodeTrigger uses a double-storage strategy to guarantee no webhook event is ever lost, even if your database crashes mid-write.

How It Works

1
Write-Ahead Log (WAL). Every inbound webhook is first appended to a durable JSON-lines file on disk, before the database insert. The file is stored in a hardened, inaccessible directory with .htaccess deny rules and an unguessable path.
2
Database Insert. After the disk write succeeds, the event is inserted into the database queue.
3
ACK. The provider receives 200 OK as soon as the disk write succeeds, even if the database insert fails. The event is safe on disk.

Storage Integrity

The dashboard includes a Fail-Safe Storage widget (🛡️) showing real-time status:

Resurrection (Disaster Recovery)

If the database loses events (crash, corruption), an admin can run the "Resurrection" tool. It scans the durable log files, identifies any events missing from the database, and re-injects them into the queue. Events are de-duplicated by their event_uid, so duplicates are impossible.

Retention Policy

DataRetentionCleanup Trigger
Disk log files30 daysDaily cron
Database events14 daysDaily cron
Unpaid/quota-hold eventsFollows plan lifecyclePlan-dependent
Raw payload history per route50 most recentAutomatic pruning

Retries & Delivery

Two-Stage Processing

NodeTrigger separates ingestion from delivery to avoid keeping your providers waiting:

Retry Behavior

Concurrency safety: Even if multiple webhooks arrive simultaneously and each triggers the worker, only one drainer runs at a time. The named lock prevents race conditions on shared hosting.

Flow Log & Replay

Event History

Every webhook received by NodeTrigger is logged with:

Search

The flow log supports full-text search across stored payloads — useful for finding a specific event by customer ID, order number, or any field present in the JSON body.

Replay

You can replay any stored event at any time. The replay action re-inserts the original raw payload as a new queued event and processes it through the route's current rules (not the rules from when it originally arrived).

Replay uses current rules. If you've changed your filters since the event originally arrived, the replay will route according to the new configuration. The UI shows a yellow .ntr-replay-note warning to make this explicit.

Overview Dashboard

The Overview Dashboard provides a global control plane across all your routes. It displays:

Usage Widget

A sidebar widget shows your monthly consumption (used / quota, a progress bar, and the reset date). If your plan has a quota and you're approaching the limit, a badge will appear.

Security

Signature Verification

When a source secret is configured on a route, NodeTrigger validates the provider signature on every inbound webhook (with no secret set, payloads are accepted unverified):

URL Signature

Each inbound URL contains a cryptographic signature derived from your account's automatically-generated secret key: hash_hmac('sha256', 'route_'.$id, account_secret_key). This means:

SSRF Protection

NodeTrigger refuses to forward events to private, loopback, or reserved addresses (e.g., 127.0.0.1, 10.x.x.x, 192.168.x.x). This prevents attackers from using your route to probe your internal network.

Header Safety

When forwarding to destinations, NodeTrigger only passes a safe subset of headers — it never forwards authentication headers, cookies, or the Host header from the original inbound request.

Access Control

All administrative actions (creating routes, running resurrection, viewing events) require: authentication (is_user_logged_in()) + ownership verification (you can only interact with your own routes).

Plans & Quota

NodeTrigger's plan system is configured by your site administrator in Settings → Pricing / Plan. Here's what you need to know as a user.

Default Plan ("All-In")

FeatureValue
Monthly webhooks100,000 / month
Equivalent daily average~3,300 events/day
RoutesUnlimited
All featuresFilters, transforms, replay, fail-safe storage, signature verification — all included
Price€29/month (excl. VAT)
Unpaid retention30 days (events held, not deleted)

Quota Enforcement

Quota enforcement is role-based. Your administrator assigns a WordPress role (e.g., "Subscriber" or a custom role) that determines who is on the paid plan.

If no plan role is set, everyone can route freely with no quota enforcement. Administrators (manage_options capability) are always exempt from quota limits.

What Happens When You Hit Quota?

  1. Inbound webhooks continue to be stored (fail-safe still applies).
  2. Events are marked as quota_hold instead of queued — the worker does not forward them.
  3. A once-per-month email alert is sent (if enabled by your admin).
  4. On the monthly reset, the counter resets to zero, and held events are automatically re-queued (their count deducts from the new month's quota).

Monthly Reset

The webhook counter resets on the first day of each month (driven by the daily maintenance cron). If WP-Cron is disabled on your site, the administrator needs to ensure it runs or the reset won't fire.

Rate Limiting

To protect your server from traffic spikes, NodeTrigger enforces a per-user rate limit on inbound webhooks.

Details
Limit typePer-user, per-second ceiling (default 10 webhooks/second)
Response when exceeded429 Too Many Requests + Retry-After header
Provider behaviorStripe, Shopify, Make, and n8n all respect 429 and retry — so no data is lost
BackendObject-cache aware (Redis/Memcached/APCu) — no database write on the hot path
ConfigurableFilterable via nt_router_rate_limit hook

The rate limiter is intentionally designed to never add a database write to the webhook hot path. It uses in-memory counters (a persistent object cache like Redis/Memcached if available, otherwise APCu). If neither is present, rate limiting is simply not applied — the durable queue and single-worker lock already protect the server, so it never falls back to a database-backed counter. This keeps ingestion fast.

Best Practices

1. Start with Learning Mode

When creating a new route, enable Learning Mode and send a real webhook before building filters. The captured sample payload makes filter building much easier — you can click on actual fields instead of guessing JSON paths.

2. Use Specific Filters Before Catch-Alls

Build your most specific filter branches first, then use a catch-all (source → destination direct link) as the fallback. The branch array is evaluated in order, so more specific rules should come first.

3. Copy the Inbound URL Exactly

Your inbound URL is signed for you — there's no key to manage. Just copy each route's full URL into your provider exactly as shown. (The only thing that invalidates a URL is an administrator resetting your account's secret key, which isn't part of normal use; if it happens, re-copy the new URL for each route.)

4. Monitor the Fail-Safe Widget

The storage sync percentage should always be at 100%. If it drops below 100%, run the resurrection tool. A persistent desync may indicate a database issue that needs administrator attention.

5. Transform Payloads Per Destination

If you're forwarding the same event to both Slack and HubSpot, use per-destination transforms to reshape the data for each tool. Slack needs a text field; HubSpot expects properties.email — don't send the same shape to both.

6. Redact Sensitive Data

Use the redaction feature to mask or remove sensitive fields (card_number, customer_ip, etc.) before forwarding to third-party destinations. This is especially important when sending events to tools not under your direct control.

7. Check Flow Log Bedge Colors

A quick scan of green/yellow/red badges in your flow log tells you the health of your pipelines. A sudden spike in yellow (retrying) or red (failed) badges usually means a destination is down.

8. Respect the Retention Windows

Database events older than 14 days are pruned automatically. If you need long-term archives, export the flow log regularly or forward events to a persistent logging system as one of your destinations.

FAQ & Troubleshooting

My inbound URL stopped working. Why?

Check that the provider is calling the exact URL shown for your route — a truncated or edited URL will fail the signature check. In the rare case an administrator reset your account's secret key, every route's URL changes: open each route and copy the new inbound URL into Stripe/Shopify/etc.

I see a red badge with "invalid_url_signature". What does that mean?

A webhook hit your endpoint with an incorrect URL signature — usually the provider is configured with an old, truncated, or edited URL (or your account's secret key was reset by an admin). Re-copy the current inbound URL from the route and update your provider's webhook configuration. The event is logged so you know it happened — it's not silently dropped.

My webhooks are being received but not forwarded (grey badge).

Grey badges mean the event is held, not queued for delivery. Two possible reasons:

How do I know if my destination is down?

Check the event drawer for any delivery. Each destination shows its HTTP response. A 5xx status or connection timeout means the destination is unreachable. The retry badge (🟡) will appear until 5 attempts are exhausted.

Can I use NodeTrigger without WordPress?

No — NodeTrigger is a WordPress plugin. It requires a WordPress installation (self-hosted or managed WordPress hosting). It uses WordPress's REST API, cron system, and database layer.

What happens if WordPress cron is disabled on my site?

Two things: the monthly quota reset and the daily storage cleanup rely on WP-Cron. The async delivery loopback still works (it doesn't depend on cron), but the fallback worker (1-minute cron) won't fire. Your administrator should ensure WP-Cron is operational or use a real server cron to trigger wp-cron.php.

How fast is the ingestion pipeline?

Ingestion is designed to be fast — payload is written to disk and 200 is returned within a few milliseconds under normal conditions. However, raw throughput depends on your hosting. For high-volume scenarios (>10 events/second sustained), consider using an object cache (Redis) and a fast disk (SSD/NVMe).

Can I trigger NodeTrigger from my own code?

Yes. The inbound endpoint accepts any POST with a JSON body from any source. For non-Stripe/Shopify providers, select the Generic source type. To keep it verified, set a shared secret and have your sender include it in the X-NT-Secret header; leave the secret blank to accept payloads unverified.

What's the difference between Replay and Retry?

Are webhooks stored in my WordPress database?

Yes. Events are stored in the wp_nt_route_events table (and also in durable JSON log files on disk as a backup). This means webhook data counts toward your database size. Old events are automatically pruned (14 days DB, 30 days disk).