Trigger n8n workflows from Port
This guide shows how to put existing n8n workflows under Port's management layer without changing how those workflows run.
Port becomes the trigger, permission, and agent-entry point. n8n stays the execution runtime. Each n8n workflow keeps its current nodes, credentials, and logic. A single Port workflow discovers the webhook path from the catalog and POSTs a payload to n8n.
A custom skill then lets Port AI or an MCP-connected assistant find every eligible n8n workflow and trigger them for a business event, such as onboarding a new enterprise customer.
Common use cases
- Centralize n8n triggers in Port so developers and agents start automations from the catalog instead of n8n.
- Attach permissions to n8n runs with Port workflow permissions, without rewriting n8n logic.
- Fan out one event to many n8n workflows. For example, onboard a customer by triggering Slack setup, CRM record creation, and an email sequence together.
- Let agents trigger n8n through the Port MCP server, using a skill that infers each webhook payload from the cataloged workflow definition.
Prerequisites
This guide assumes the following:
- You have completed the onboarding process.
- You have a working n8n instance (Cloud or self-hosted) with workflows that use a Webhook trigger node (
n8n-nodes-base.webhook). - Port's n8n integration is installed and the
n8nWorkflowblueprint exists in your catalog. - You have access to Port Workflows.
- (Optional, for agent-driven fan-out) Port's MCP server is connected in your IDE or assistant, and the
skillblueprint exists in your catalog.
Do not migrate n8n node logic into Port. The Port workflow in this guide only selects an n8nWorkflow entity, reads its webhook path, and forwards the payload. n8n continues to send emails, create CRM records, open Slack channels, and run every other step.
How it works
The pattern uses three layers:
- Catalog - The n8n Ocean integration syncs each n8n workflow as an
n8nWorkflowentity, includingis_activeand thenodesarray. - Trigger workflow - A Port workflow named
trigger_n8n_workflowappears on eachn8nWorkflowentity. It fetches the entity, extracts the firstn8n-nodes-base.webhookpath, and POSTswebhook_bodyto your n8n instance. - Skill - A custom skill tells Port AI to find every active webhook-triggered n8n workflow, map user-provided fields onto each payload, and invoke
trigger_n8n_workflowonce per workflow.
That split scales across many n8n workflows. You do not create one Port workflow per n8n workflow. You create one generic trigger and let the catalog plus the skill decide which n8n workflows to run.
Set up the n8n catalog
Follow the n8n integration installation and mapping steps so Port ingests n8nWorkflow entities.
After the sync completes, confirm that each n8n workflow you want to trigger has:
is_activeset totrue.- At least one node whose
typeisn8n-nodes-base.webhook. - A webhook
parameters.pathsuch as/onboarding/slack-setup.
Inactive workflows and workflows without a webhook trigger stay in the catalog for visibility. The Port workflow and skill in this guide skip them.
Store the n8n webhook base URL
The Port workflow needs the public base URL of your n8n webhook endpoint. Store it as a secret so you can rotate it without editing the workflow JSON.
- Open the Credentials modal.
- Click on the
Secretstab. - Click
+ Secretstab. - Add a secret named
N8N_WEBHOOK_BASE_URL. - Set the value to your n8n webhook base, with no trailing slash. For example,
https://n8n.example.com/webhook.
The workflow concatenates this secret with the path stored on the n8nWorkflow entity. If the cataloged path is /onboarding/email-sequence, the request goes to https://n8n.example.com/webhook/onboarding/email-sequence.
The base URL must be reachable from Port. A local n8n instance needs a tunnel or a publicly hosted n8n Cloud URL. If the tunnel is offline, the Port run succeeds through the fetch step and then fails on the n8n POST with a 404 from the tunnel provider.
Build the trigger workflow
The workflow has three nodes:
- Trigger - a self-service form with an
n8nWorkflowentity input and a JSONwebhook_body. AnENTITYcontext puts the workflow on the bolt menu of n8n workflow entities. - Fetch n8n workflow - a GET to Port's catalog API that loads
properties.nodesand extracts the webhook path. - Call n8n webhook - a synchronized POST that spreads
webhook_bodyinto the n8n request body.
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
If your account is on the US region, change https://api.port.io in the fetch node to https://api.us.port.io. Using the EU URL from a US organization returns 401 with no token provided.
Create the workflow
- Go to the Workflows page in Port.
- Click + Workflow.
- Fill out the Create new workflow form, then click Confirm.
- Click the
{...}button to open the JSON editor. - Copy and paste the workflow JSON below into the editor to replace the example workflow.
Trigger n8n workflow JSON (click to expand)
{
"identifier": "trigger_n8n_workflow",
"title": "Trigger n8n Workflow",
"icon": "Webhook",
"description": "Trigger this n8n workflow via webhook with custom payload. Only available for workflows with webhook triggers.",
"category": "n8n",
"allowAnyoneToViewRuns": true,
"nodes": [
{
"identifier": "trigger",
"config": {
"type": "SELF_SERVE_TRIGGER",
"permissions": {
"roles": ["Admin", "Member"]
},
"contexts": [
{
"on": "ENTITY",
"userInput": "n8n_workflow"
}
],
"userInputs": {
"properties": {
"n8n_workflow": {
"type": "string",
"format": "entity",
"blueprint": "n8nWorkflow",
"title": "n8n Workflow"
},
"webhook_body": {
"type": "object",
"title": "Webhook Payload",
"description": "JSON payload to send to the n8n workflow webhook",
"additionalProperties": true
}
},
"required": ["n8n_workflow", "webhook_body"],
"order": ["n8n_workflow", "webhook_body"]
}
}
},
{
"identifier": "fetch_n8n_workflow",
"title": "Fetch n8n workflow",
"config": {
"type": "WEBHOOK",
"url": "https://api.port.io/v1/blueprints/n8nWorkflow/entities/{{ .outputs.trigger.n8n_workflow }}",
"method": "GET",
"synchronized": true
},
"variables": {
"entity": "{{ .result.response.data.entity }}",
"webhook_path": "{{ .result.response.data.entity.properties.nodes | map(select(.type == \"n8n-nodes-base.webhook\")) | first | .parameters.path }}"
}
},
{
"identifier": "call_n8n_webhook",
"title": "Call n8n webhook",
"config": {
"type": "WEBHOOK",
"url": "{{ .secrets[\"N8N_WEBHOOK_BASE_URL\"] + .outputs.fetch_n8n_workflow.webhook_path }}",
"method": "POST",
"synchronized": true,
"agent": false,
"headers": {
"Content-Type": "application/json"
},
"body": {
"{{ spreadValue() }}": "{{ .outputs.trigger.webhook_body }}"
}
}
}
],
"connections": [
{
"sourceIdentifier": "trigger",
"targetIdentifier": "fetch_n8n_workflow"
},
{
"sourceIdentifier": "fetch_n8n_workflow",
"targetIdentifier": "call_n8n_webhook"
}
]
}
- Click Apply changes.
The self-service trigger is now available from the self-service hub and from the bolt menu on n8nWorkflow entities. You can restrict who can run it with dynamic permissions on the trigger node.
You do not need a separate Port workflow for Slack setup, CRM, email, or any other n8n automation. The webhook path comes from the selected n8nWorkflow entity at runtime. Add or activate n8n workflows in n8n, let Ocean sync them, and they become triggerable through this same Port workflow.
Create the trigger skill
A skill tells Port AI how to discover eligible n8n workflows and how to call trigger_n8n_workflow for each one. That is what makes the pattern repeatable across ~20 n8n workflows instead of hand-writing a Port workflow per automation.
If the skill blueprint does not exist yet, create it from the custom skills instructions.
Then create a skill entity:
- Go to the data model page in Port.
- Open the
skillcatalog page and create a new entity. - Switch to JSON mode and paste the entity below.
Trigger active n8n workflows skill (click to expand)
{
"identifier": "trigger-active-n8n-workflows",
"title": "Trigger active n8n workflows",
"blueprint": "skill",
"properties": {
"location": "global",
"description": "Trigger one or more active n8n workflows that have a webhook trigger node (n8n-nodes-base.webhook). Use this skill when the user wants to run, execute, fire, or kick off n8n workflows, especially when triggering multiple workflows for a single business event such as onboarding a new customer, responding to an incident, or any fan-out automation scenario.",
"instructions": "# Trigger active n8n workflows\n\nYou are an n8n workflow orchestrator operating through Port. Discover all active n8n workflow entities that have a webhook trigger, understand what payload each one expects, and invoke them via the `trigger_n8n_workflow` Port workflow.\n\n## Step 1 - Collect context from the user\n\nBefore doing anything, make sure you have:\n- The business event or goal (for example, onboard a new enterprise customer).\n- Any known data fields the user has provided (customer name, email, owner, and similar).\n\nIf the user has not provided a payload or context, ask for it before proceeding. Do not guess required values like email addresses or customer names.\n\n## Step 2 - Discover eligible workflows from Port\n\n1. Search entities of blueprint `n8nWorkflow`.\n2. Filter to entities where `is_active` is `true`.\n3. Keep only entities that contain at least one node with `type` equal to `n8n-nodes-base.webhook`.\n4. For each eligible workflow, extract:\n - `identifier` - the Port entity identifier.\n - `title` - human-readable name.\n - webhook path - `.properties.nodes[] | select(.type == \"n8n-nodes-base.webhook\") | .parameters.path`.\n - `httpMethod` - the same node's `.parameters.httpMethod` (default to `POST` if absent).\n\nIf no eligible workflows are found, stop and tell the user that there are no active n8n workflows with webhook triggers in the catalog.\n\n## Step 3 - Infer the payload for each workflow\n\nFor each eligible workflow:\n1. Read all non-webhook nodes to understand what data the workflow uses. Look at Set nodes, expressions that reference `$json.body.*`, Slack templates, and HTTP request bodies.\n2. Map those fields against the data the user provided.\n3. Construct a `webhook_body` JSON object with the fields that workflow needs.\n\nIf a workflow references a field the user has not provided and it cannot be reasonably inferred, note it as missing. Do not fabricate values. Ask the user for any critical missing fields before proceeding.\n\nIf multiple workflows share the same payload shape, reuse the same `webhook_body` for all of them.\n\n## Step 4 - Invoke each workflow\n\nFor each eligible workflow, call `trigger_run` with this structure. Do not rename or nest fields:\n\n{\n \"type\": \"WORKFLOW\",\n \"identifier\": \"trigger_n8n_workflow\",\n \"nodeIdentifier\": \"trigger\",\n \"inputs\": {\n \"n8n_workflow\": \"<the Port entity identifier of the n8nWorkflow entity>\",\n \"webhook_body\": { }\n }\n}\n\nPut the constructed payload fields in `inputs.webhook_body` as a flat JSON object. Always invoke through `trigger_n8n_workflow`. Never call the n8n webhook URL directly.\n\n## Step 5 - Report results\n\nAfter all invocations complete, output a summary table with workflow title, webhook path, status, and notes. Include the error message for any failure. List skipped workflows separately with the fields that were missing.\n\n## Rules\n\n- Never trigger workflows where `is_active` is `false` or where no `n8n-nodes-base.webhook` node is present.\n- Never fabricate payload values. Use only what the user provided or what can be clearly inferred.\n- If the user asks to trigger only a subset of workflows, respect that filter.\n- Always show the summary table, even if only one workflow was triggered."
}
}
- Click Create.
The skill does not copy n8n logic into Port. It only decides which cataloged n8n workflows to start and which fields to send.
Trigger n8n workflows from Port AI
You can run a single n8n workflow from the catalog, or ask an agent to fan out to every eligible workflow.
Trigger one workflow from the catalog
- Open an
n8nWorkflowentity that is active and has a webhook node. - Click the bolt menu and select Trigger n8n Workflow.
- Enter the JSON payload the n8n workflow expects. For example:
{
"customer_name": "ACME Corp",
"contact_email": "cto@acme.com",
"account_owner": "Jane Doe"
}
- Click Execute.
Port fetches the entity, resolves the webhook path, and POSTs the payload to n8n.
Fan out from an assistant
With the Port MCP server connected, ask your assistant to load the skill and run the event. An onboarding prompt looks like this:
We just signed ACME Corp as an enterprise customer. Can you kick off all the onboarding workflows for them? Contact is cto@acme.com and Jane Doe is the account owner.
The assistant should:
- Call
load_skillwithtrigger-active-n8n-workflows. - List active
n8nWorkflowentities that contain a webhook node. - Infer a shared payload from n8n expressions such as
$json.body.customer_name,$json.body.contact_email, and$json.body.account_owner. - Invoke
trigger_n8n_workflowonce per eligible workflow. - Return a summary table.
If three onboarding workflows are in the catalog, the result looks like this:
| Workflow | Webhook path | What n8n does |
|---|---|---|
| Enterprise Onboarding – Slack Setup | /onboarding/slack-setup | Creates a customer Slack channel and invites the account owner. |
| Enterprise Onboarding – CRM Record | /onboarding/crm-record | Creates an enterprise CRM account. |
| Enterprise Onboarding – Email Sequence | /onboarding/email-sequence | Sends a welcome email to the contact. |
n8n still owns those three implementations. Port only starts them with the same payload.
Example payloads
n8n workflows typically read fields from $json.body. Map those expression names to webhook_body keys.
| n8n expression | webhook_body field | Example value |
|---|---|---|
$json.body.customer_name | customer_name | ACME Corp |
$json.body.contact_email | contact_email | cto@acme.com |
$json.body.account_owner | account_owner | Jane Doe |
Reuse one payload object when several n8n workflows expect the same fields. Only split payloads when a workflow needs extra keys.
Troubleshooting
What's next
- Tighten execute access with workflow permissions so only specific teams or roles can trigger n8n from Port.
- Add the skill to a dedicated AI agent that owns onboarding, incident fan-out, or another business event.