How Dify webhook triggers start workflows from other systems
A team that wants a ticket, a form submission or a system event to start a Dify workflow without someone clicking Run needs a trigger. In Dify, triggers are available for Workflow apps only, so a chatflow or a simple chat app cannot be started this way. Each trigger type answers a different question: a webhook trigger starts the workflow when another system sends an HTTP request, an integration trigger starts it from an event provided by a plugin, and a schedule trigger starts it at set times. The rest of this page covers how to choose among them and what to check before one goes live.
Webhook triggers are the most direct route for a ticketing tool, form service or internal application. When you add one, Dify gives the trigger a unique URL. The base of that URL comes from the TRIGGER_URL environment variable, which defaults to ` so a self-hosted instance must set it to an address the calling system can reach, or the URL it shows will be unusable from outside the host. A workflow can hold several webhook triggers, which lets one application serve different sources, but each one needs its own URL registered in the calling system. Confirm the public hostname, the TLS termination point and the reverse proxy route with your platform team before you hand any URL to another system. The Dify webhook trigger documentation sets out the configuration fields.
The configured HTTP method and content type must match each incoming request, or Dify rejects it. This is a useful control: a misconfigured sender fails loudly instead of starting a workflow with partial data. Values from query parameters, headers and the body become output variables that downstream nodes can read, so the sending system's payload design determines what the workflow can use. Agree on the method, content type and field names with the owner of the sending system, and record them in the workflow's design notes. Test with a non-production workflow and a sample request before you connect a live source, because a trigger that accepts requests from a production system is also an entry point into your workflow.
Choosing between webhook, integration and schedule triggers
Webhook triggers fit any system that can send an HTTP request when something happens, such as a ticketing tool, a form service, a payment notification or an internal application. Dify gives the workflow a unique URL, and the source system posts to it. The receiving side decides what the request must look like, because Dify compares the configured method and content type against the incoming request and rejects a mismatch. Values from query parameters, headers and body then become output variables that downstream nodes can use.
- Request shape: The sender must use the configured HTTP method and content type exactly, so confirm both before wiring the source.
- Payload design: Agree on the fields and their names with the sending team, since downstream nodes read them by name.
- Multiple entry points: A single workflow can have several webhook triggers, which helps when different systems send different event types.
- Network reachability: The source must reach the public base address that
TRIGGER_URLdefines, so internal-only sources need a route to that address. - Authentication: Confirm what your Dify version checks on incoming requests, and add controls at the gateway if the sender cannot sign requests.
Before committing to this type, confirm with the sending team that they can send the required method, content type and fields.
Integration triggers start a workflow from events that a plugin reports, so they fit cases where the event source already has a supported plugin and you do not want to build an HTTP sender yourself. The Dify docs list integration triggers as one of three trigger types, and the available sources depend on the plugins installed in your instance. Because plugins run in the plugin daemon, the operational footprint and trust decisions move to the plugin layer, which the plugin governance in your deployment must cover.
- Plugin availability: Check which event sources the plugins in your version support, since the Dify docs do not establish a complete catalog for this document.
- Plugin trust: Review the publisher, source and permissions of any plugin before installing it in a production workspace.
- Credentials: Plan who holds the account or token the plugin uses to subscribe to events, and where that secret is stored.
- Event scope: Confirm which events the plugin delivers and whether you can filter them before they start a run.
- Version coupling: Plugin behavior can change with upgrades, so retest triggers after each Dify or plugin update.
Before designing around this type, confirm the plugin list and its event coverage in the version you run, then record the approval for each plugin.
Schedule triggers start workflows at set times, which suits recurring work such as a daily summary, a periodic knowledge check or a weekly report. They need no action from an external system, so the main design questions concern timing, time zones and what the run should do when the previous run has not finished. The source system does not need to send anything, but the workflow must be able to read the data it needs at the scheduled moment.
- Timing rules: Define the schedule, the time zone and the expected run duration so overlapping runs are avoided.
- Data freshness: Confirm that the systems the workflow reads are available at the scheduled time.
- Output destination: Decide where results go, such as a message channel, a file or an internal API, and who receives them.
- Failure visibility: Plan how a missed or failed run is noticed, since a schedule that fails quietly can go unseen for a long time.
- Load planning: Stagger runs that share model endpoints or worker capacity with other scheduled and user-driven work.
Before relying on this type, test one run in a non-production workspace and confirm the schedule behaves as expected across a time zone change.
Choosing a trigger type depends mostly on what the event source can do. A system that can send HTTP requests is a webhook candidate, a system with a supported plugin is an integration trigger candidate, and work with no external event is a schedule candidate. Many real designs combine them, for example a webhook that handles incoming tickets and a schedule that reviews open items overnight. Mixing types should still be deliberate, because each type has its own failure modes and ownership.
- Push capability: Use a webhook only when the sender can post reliably and handle errors from Dify.
- Plugin coverage: Prefer an integration trigger when a plugin already covers the event and its trust review is complete.
- Polling need: A schedule can check a source for changes, but it adds delay compared with an event-driven design.
- Ownership split: Record which team owns the sender, the plugin or the schedule, since incidents often cross team lines.
- Mixed designs: Document each trigger in the workflow so reviewers can see every way a run can start.
Before settling on a design, list each event source with its capability and owner, then choose the trigger type that matches the weakest link.
Webhook trigger settings and when each fits
This table compares the webhook trigger settings that decide whether an inbound request starts a workflow and what data the workflow receives. Read each row alongside the configuration you will set in Dify and the matching setting in the sending system. The main takeaway is that method and content type are gatekeepers: a mismatch rejects the request before any parameter reaches your nodes.
| Setting | What it controls | What to match on the sending side |
|---|---|---|
| HTTP method | The single method the trigger accepts, such as POST or GET. Requests using another method are rejected. | Confirm the sender's method setting, since some SaaS tools default to POST and others offer GET only for polling. |
| Expected content type | The body format the trigger expects, such as JSON or form data. A mismatched content type causes rejection. | Check the Content-Type header the sender actually transmits, not only the payload shape it documents. |
| Query parameter extraction | Values from the URL query string become output variables available to downstream nodes. | Ask the sender whether identifiers arrive in the query string, which is often logged by proxies and easy to inspect. |
| Header extraction | Selected request headers become output variables, useful for event types, signatures or correlation IDs. | Confirm the exact header names the sender uses and whether it adds signature headers you will need to verify. |
| Body extraction | Fields from the request body become output variables for prompts, conditions and API calls. | Share a sample payload with the sender's team and confirm field names, nesting and optional fields. |
| Multiple webhook triggers | One workflow can hold several webhook triggers, each with its own URL and settings. | Use one trigger per sending system or event family so that method and content type rules stay simple to verify. |
| Self-hosted URL base | The TRIGGER_URL setting determines the public base of each generated URL. The default is localhost, which external senders cannot reach. | Set TRIGGER_URL to a host the sender can reach over the network path you have approved, and confirm it before testing. |
| Schedule and plugin triggers | Schedule triggers start on a timer, and integration triggers come from plugins, so the method and content type rules above do not apply in the same way. | Choose a webhook when an external system pushes events, and a schedule or plugin trigger when Dify should pull or wake on its own. |
Why TRIGGER_URL must match the public address
The base of every webhook trigger URL in a self-hosted Dify instance comes from the TRIGGER_URL environment variable, which defaults to Dify can generate a unique URL for each webhook trigger, but an external system can only call that URL if the base address is one it can reach. Until TRIGGER_URL` is set to the public address your senders will use, the generated URLs point at a host only your own machine can resolve, and events from other systems will never arrive. Set the variable before you create the first trigger, so every URL you hand to a sender is correct from the start.
Changing TRIGGER_URL later does not update URLs that are already in use. Any SaaS tool, payment provider or internal service that was configured with the old address will keep sending to it, and those calls will fail once the address changes or the old host stops routing to Dify. Treat the public base address as a stable identifier. If it must move, plan the change as a migration: create the new trigger URLs, reconfigure each sender, confirm events arrive, then retire the old address. Keep a list of which senders hold which URLs so this work is not guesswork.
Check the value against the full path a request takes. The host and scheme in TRIGGER_URL must match what your reverse proxy and TLS termination expose, including the external port and whether the sender uses https. A mismatch between the proxy's public hostname and the variable is a common reason webhooks look configured but receive nothing. Keep TRIGGER_URL in the .env file used by your Docker Compose deployment, and after any change, confirm behavior in the Dify version you run by sending a test request from outside your network and checking the trigger run. Versions can change how this setting is read, so verify against the Dify environment variable reference and your upgrade notes.
Setting up a webhook trigger on a self-hosted Dify
This sequence takes a Workflow app from a self-hosted Dify instance to a working webhook trigger that accepts events from a source system and passes their data into downstream nodes. Each step ends with a check you can run before the trigger goes near production data.
Confirm the app is a Workflow app
Open the app in the Dify console and check its type before anything else. Triggers are available for Workflow apps only, so a Chatflow or other app type cannot take a webhook trigger in the way this sequence describes. If the app is the wrong type, decide whether to build a new Workflow app or rebuild the logic in one, because the trigger cannot be added to the existing app. The check is that the app type shows as Workflow in the console before you continue.
Set TRIGGER_URL to the reachable base address
Set the TRIGGER_URL environment variable in the deployment
.envfile to the externally reachable base address of your Dify instance. The Dify docs say the default is and webhook URLs are built from this base, so a source system on another host cannot call a localhost address. Confirm with your network team that the address resolves and that the route from the source system reaches the Nginx entry point over TLS. Restart the services so the new value takes effect, then check that a trigger URL generated later begins with the address you set.Add a webhook trigger node
In the Workflow editor, add a webhook trigger as the start point of the workflow. A workflow can hold multiple webhook triggers, so decide whether each source system or event type gets its own trigger or whether one trigger handles several event shapes. Separate triggers keep each parameter schema simple and make failures easier to attribute. The check is that the trigger appears as a start node in the canvas and that the workflow still validates when you save it.
Define method, content type and parameters
Set the HTTP method and content type the source system will send, and define the query parameters, headers and body fields you need. Values from these three places become output variables for downstream nodes, so name them for the data they carry and keep the schema to what the workflow uses. Ask the source system owner to confirm the exact method and content type their sender uses, because a mismatch is rejected. The check is that the trigger's declared schema matches a sample payload from the source system's documentation.
Copy the generated URL and record its owner
Once the trigger is saved, copy the unique URL Dify generates for it and record which system will call it, which environment it belongs to, and who can rotate or remove it. The URL is built from the TRIGGER_URL base, so confirm the host matches the address you configured. Store the URL in the source system's configuration rather than in documents or chat threads, since anyone holding it can start a run. The check is that the URL in the source system's settings matches the one copied from Dify exactly.
Send a test request from the source system
Trigger a test event from the source system, or send a request with the same method, content type and fields from a separate client, using a test payload rather than live records. Point the test at a non-production Dify instance or a copy of the app where possible, so test runs do not write to production knowledge bases, conversation logs or downstream systems. Confirm that the run appears in the workflow logs. The check is that the run completes and that its input shows the fields you sent.
Verify rejection of wrong requests
Send deliberate bad requests to confirm the trigger refuses them: one with a wrong content type and one with the wrong HTTP method. Dify rejects a request whose method or content type does not match the configuration, so each test should return a rejection and produce no workflow run. Record the responses and check the logs to confirm no run started. This check matters because a trigger that accepts unexpected input can route it into downstream nodes without anyone noticing.
Confirm extracted variables reach downstream nodes
Add a downstream node, such as a template or an LLM node, that outputs the extracted query, header and body variables, then run a test and read the values in the node's output. Confirm that each field arrives in the expected variable with the expected type and that empty or missing fields behave as your workflow requires. Only after this check passes should the URL be connected to a production source system, with a named owner for the trigger and a plan for removing test runs from logs under your retention policy.
Testing triggers without polluting production data
A webhook or schedule trigger fires on real events, so a careless test can write to production knowledge bases, send messages or consume records. The cards below separate test and production at the instance, workspace, app and output levels, and list the checks to make before any production trigger goes live.
Separate test instance or workspace
Run test triggers on a separate Dify instance, or at minimum in a separate workspace, so that test URLs, app keys and knowledge bases never share state with production. Community edition is limited to a single workspace, so for a second workspace on the same instance you should confirm what your edition allows. Give the test instance its own TRIGGER_URL value so webhook URLs point at the test environment. Confirm the exact behavior in your version before relying on it.
Mark sample payloads clearly
Send sample payloads that carry an obvious marker, such as a test_run field or a dedicated header, and have the workflow branch on it so test records are easy to identify in logs and downstream systems. Use fictional identifiers rather than copies of customer records. Because the configured HTTP method and content type must match the incoming request, keep your test client identical to the production sender so the test exercises the real parameter extraction path.
Restrict outputs during tests
Trigger runs can reach any node the workflow contains, including knowledge base writes, HTTP requests and tool calls. Before testing, identify every node that writes or sends, and route it behind a condition that is off for marked test payloads or point it at a test knowledge base. Treat this as a review item in the workflow itself, not a memory task for the person running the test.
Test on a copy exported as DSL
Export the production app as a YAML DSL file and import it as a separate test app, then attach test triggers to the copy. The export carries app configuration, workflow nodes, model parameters and prompts, but leaves out third-party API keys, knowledge base content and usage logs, so you must reconnect credentials and point knowledge bases at test data. Keep the DSL under version control so the tested copy and the production app stay traceable.
Review run logs before going live
Before enabling a production trigger, read the run logs of the test runs node by node. Check which trigger fired, what the extracted query, header and body variables contained, and whether any branch reached a write or outbound call. Confirm that rejected requests with a wrong method or content type appear as expected. Record the review so the go-live decision has evidence behind it.
Confirm retention for trigger runs
Test runs are stored like any other run, so retention settings decide how long they remain. Confirm in your version whether trigger runs appear in workflow logs, how long they are kept, and whether scheduled cleanup applies to them. Align that setting with your privacy policy before sending real data through a trigger, because test payloads that include personal data will persist on the same schedule as production.
Questions teams ask before building Dify triggers
How much effort does a Dify trigger integration take?
Effort depends mostly on the source system, the shape of its payloads and how much testing the team needs before the workflow touches real data. A webhook that sends one flat JSON object with a fixed method and content type is a small task: you configure the trigger, map fields from the body, headers and query parameters into downstream nodes, and run test events. A source that signs requests, sends nested or variable payloads, retries deliveries or needs idempotent handling adds design and test work. Ask any partner to break the quote into source analysis, trigger configuration, parameter mapping, failure handling and test runs, so you can see which part your team could absorb.
Can our own team build Dify triggers without outside help?
Yes, if your engineers can own the source system's webhook or event configuration, read the Dify trigger documentation and keep a test instance for experiments. Dify triggers apply to Workflow apps and are configured inside the workflow, so a team with API and workflow experience can start quickly. Outside help tends to add value where the source system is poorly documented, where payloads carry sensitive data that needs filtering, or where the trigger must run reliably in a multi-service production layout. Decide this by comparing the skills you have against the source system and the failure modes you cannot tolerate.
What does the work need from our team before it starts?
The work needs four inputs: a reachable endpoint that the source system can call, sample payloads from every event you plan to handle, a test instance of Dify that mirrors your production configuration, and a named owner on the source side who can change its settings. For a self-hosted instance, the endpoint must be reachable from the source system, so network routing and TLS termination must be agreed early. Sample payloads should include failure and edge cases, not only the happy path. Without a test instance, teams often test against production data, which is the risk this topic is designed to avoid.
Why does TRIGGER_URL break my Dify webhook triggers?
Each webhook trigger receives a unique URL whose base comes from the TRIGGER_URL environment variable, which defaults to If you leave the default on a self-hosted instance, the generated URL points at localhost, which an external system cannot reach, so events never arrive. Set TRIGGER_URL` to the public base address that your source system can call, including the correct scheme and host, then restart the services so the new value applies. Confirm the setting after every change to hostnames, reverse proxies or certificates, because a stale base URL will silently send events to the wrong place.
Why are my webhook requests rejected even though the URL is correct?
Dify rejects a request when its HTTP method or content type does not match the trigger configuration. A trigger set to POST with JSON will refuse a GET request or a form-encoded body, even when the URL is right. Check the source system's method and Content-Type header against the trigger settings first, then confirm that any proxy in front of Dify does not rewrite headers or methods. Test each event type separately, because one source often sends different content types for different events.
Do schedule triggers replace our external cron jobs?
Schedule triggers can replace simple external cron jobs that only start a Dify workflow at fixed times, but they do not replace every scheduler. Dify lists schedule triggers as one of its three trigger types, alongside webhook and integration triggers. Keep an external scheduler where the job must coordinate with other systems, retry across failures, run on infrastructure outside Dify, or follow an existing change process. Before moving a job, confirm how the schedule is recorded, who can change it and how failures appear in your monitoring.
How do we test triggers without polluting production data?
Use a separate Dify instance or workspace for testing, point the test source system at it, and send synthetic events that use fake identifiers. Triggers feed workflow runs, so every test event can create logs, knowledge updates or downstream writes if the workflow includes those nodes. Replace external write actions with stubs in the test workflow, and remove test logs under your retention policy once testing ends. Document which events and payloads were tested, because this record helps auditors and the next engineer who changes the workflow.
Does the Dify webhook trigger need extra security controls?
Yes. A webhook URL is an open entry point, so anyone who learns it can start a workflow, which makes URL secrecy, request validation and input handling important. Limit the trigger to the methods and content types you expect, validate the fields a workflow uses before passing them to model or tool nodes, and keep the endpoint behind TLS. Review the outbound and secret settings for the whole instance as well, because workflow nodes can call external services. Confirm the exact signing or authentication options with the Dify documentation for your version before relying on them.
Keeping triggers working through upgrades
Every upgrade of a self-hosted Dify instance can change the settings that webhook and integration triggers depend on, so take a backup before each upgrade and follow the upgrade guide for the exact target version on the Dify releases page. The Docker Compose docs recommend the backup step explicitly. After the upgrade, compare your .env file against .env.example for the new release and look for variables that were added, renamed or given new defaults. TRIGGER_URL is the setting to check first, because it sets the base of every webhook URL your senders call. If the value in your file no longer matches the public address your senders use, or a reverse proxy in front of Dify has changed, triggers will still show as configured in the console while external systems send to a dead address.
Treat the trigger URL as a contract with every system that calls it. Keep a register that lists each sender, the workflow and trigger it targets, the HTTP method, the content type and the full URL. Before and after each upgrade, send a test request from a non-production sender to each trigger and confirm that it starts a run. Mismatched method or content type is rejected, so a sender that worked before an upgrade can fail silently if the trigger configuration was edited during the change window. Confirm with your change owner whether any upgrade notes for the target version mention trigger behavior, and record the result in the same register.
Monitor trigger failures as an operational signal, not only as a user complaint. Review the workflow run history for the trigger source after each upgrade and watch for a sudden drop in runs from a sender that normally calls often. Alert on the absence of expected events where the sending system can report its own delivery status, since a rejected request may never create a run that you can see. Ask your team to confirm, in your environment, where rejected requests are recorded and how long those records are kept. Store the sender register and the upgrade checklist with your deployment configuration so the next operator can see what changed and why.
Official sources for trigger configuration
These four sources cover what a trigger does, which settings change the URLs it generates, where related self-host pages sit, and how to track changes between versions. Read them in that order when you configure a trigger for the first time, then return to them before each upgrade.
Dify webhook trigger docs
The primary reference for webhook triggers in Workflow apps. It explains that each trigger gets a unique URL, that a workflow can hold several webhook triggers, and that the configured HTTP method and content type must match each incoming request or the request is rejected. Query parameters, headers and body values become output variables for downstream nodes. Read it before you wire an external system, then test each method and content type pair on a non-production app.
Environment variables reference
This page lists the settings a self-hosted instance uses to build its trigger addresses. The most important is TRIGGER_URL, which sets the base of every webhook URL and defaults to Set it to the public address your upstream systems can reach, or the generated URLs will point at a host those systems cannot call. Confirm it matches your reverse proxy and TLS setup before you copy any trigger URL into another system.
Self-host docs index
This is a machine-readable index of the self-hosted documentation set. It helps when a trigger question also touches deployment, configuration or upgrades. Search it for trigger, webhook and plugin pages so you read the documentation that matches your deployment. Keep it in your operations runbook, because a trigger decision often depends on settings described across several pages, and the index shows where each one lives.
Release notes on GitHub
The GitHub releases page lists each Dify version with its release notes, and minor releases have arrived roughly monthly. Trigger behavior, plugin interfaces and node options can change between versions, so review the notes for every release between your current version and your target. Take a backup before upgrading, as the Docker Compose upgrade guidance advises, and then recheck your trigger URLs and test requests on the new version.
How DeployOpen scopes Dify trigger work
DeployOpen scopes trigger work in writing before any build starts, because the trigger surface of a self-hosted Dify deployment touches your network edge, your event sources and your data retention. The agreed scope names each workflow that will start from an event, each trigger type (webhook, integration from a plugin or schedule), the sending systems, the HTTP methods and content types each sender uses, and the variables each downstream node needs. It also records where TRIGGER_URL will point, which public hostname and TLS path reach the instance, and who approves changes to those values. Work is planned and implemented inside your cloud accounts, data centers or air-gapped network, so the scope also states which environments are in play and who holds access to each.
The work is organized around three deliverables that you can check. The first is a test instance configured to mirror production trigger settings, so that senders can be pointed at a non-production trigger URL without writing test events into live workflow logs or knowledge bases. The second is a sender integration check, in which each upstream system is exercised against its trigger, including rejected requests from a wrong method or content type, so that you see the failure behavior before go-live. The third is handover documentation covering the trigger inventory, the URL and environment settings, the parameter mappings, and the steps to rotate or retire a trigger. Ask any partner to show you a sample of each deliverable before you sign, and confirm with them how they will handle any sender that cannot be changed.

