Editorial independence: AI Agent Square is not paid by the vendors we review. We currently earn no commissions from links on this site, and no vendor can pay to influence scores, rankings, or review content. How reviews are made is on our methodology page.
Everything you need to manage n8n workflows programmatically — API key auth, the main public endpoints, cURL and Node.js examples, and the gotchas to plan for.
Last updated: May 2026 · Reviewed by Fredrik Filipsson
TL;DR: n8n exposes a JSON REST API for managing workflows, executions, credentials, users, tags, variables, projects and more. Authenticate with an API key sent in the X-N8N-API-KEY header. It is available on every self-hosted edition and on the Cloud Starter, Pro and Enterprise plans, but not on the free trial; only Enterprise adds scope-limited keys.
n8n is an open-source workflow automation platform — a Zapier and Make alternative that runs as a Node.js application you can self-host or buy as a managed cloud service. The public REST API sits on top of that platform and lets external systems do everything the n8n web UI does, except via HTTP.
Almost everything in this guide applies equally to self-hosted and Cloud editions. The main divergence is scopes: Enterprise lets you restrict an API key to a subset of resources and actions, while non-Enterprise keys have full access to the account's resources. The built-in Swagger playground is self-hosted only. Walk through the full n8n review for a complete platform tour; this guide is the developer-side companion.
n8n's documented method is an API key sent in a request header. Treat each key like a password, store it in a secrets manager, and rotate it on a schedule.
Log into your n8n instance, open the user menu in the bottom-left corner, and select Settings → n8n API. Click Create an API key. Give it a Label (something like "ci-deploy" or "datadog-poller") and an Expiration. If you are on Enterprise, you can also tick Scopes to limit access.
Every API request must include the header X-N8N-API-KEY: <your-key>.
cURL example:
curl -X GET "https://your-instance.app.n8n.cloud/api/v1/workflows" \
-H "X-N8N-API-KEY: n8n_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Accept: application/json"
Node.js (fetch) example:
const res = await fetch('https://your-instance.app.n8n.cloud/api/v1/workflows', {
headers: {
'X-N8N-API-KEY': process.env.N8N_API_KEY,
'Accept': 'application/json'
}
});
const { data, nextCursor } = await res.json();
Every endpoint lives under /api/v1/ on your n8n instance. Your full base URL depends on deployment:
https://<your-subdomain>.app.n8n.cloud/api/v1http://localhost:5678/api/v1https://n8n.your-domain.com/api/v1If you front your self-hosted instance with Nginx or Caddy, make sure the proxy passes the X-N8N-API-KEY header through unchanged.
The endpoint reference lists 27 groups, from audit and data tables to SSO settings and log streaming. These are the ones most teams use.
The most-used endpoints. GET /workflows lists workflows with pagination; POST /workflows creates a workflow from JSON; GET /workflows/{id} retrieves one with its full node graph; PUT /workflows/{id} replaces it; DELETE /workflows/{id} removes it; POST /workflows/{id}/publish and /unpublish put it live or take it offline. n8n v1 called this activating; the /activate and /deactivate paths are deprecated. Archive, transfer, version history and tag endpoints also exist.
The tags query parameter on GET /workflows filters by tag — useful in CI to deploy only workflows tagged prod. Pagination uses limit (max 250) and cursor from the previous page's response.
GET /executions lists historical executions with filters for workflowId, projectId, status (for example success, error, waiting, running) and startedAfter / startedBefore. GET /executions/{id} returns the full execution data including each node's input and output payload. DELETE /executions/{id} removes one, and there are endpoints to retry or stop executions. There is no endpoint to start a new execution; that goes through the workflow's webhook URL.
POST /credentials creates a credential (an OAuth token, API key, or DB connection string) without exposing it in plaintext to your CI logs. GET /credentials/schema/{credentialTypeName} returns the JSON schema for a credential type so you know which fields to populate. GET /credentials lists credentials for the instance owner and admins without their secret data; there is no endpoint to read secrets back.
GET /users and GET /users/{id} (owner only), POST /users, DELETE /users/{id} and PATCH /users/{id}/role let you provision and de-provision users.
Tags (/tags) organize workflows. Variables (/variables) store environment-style config values that the $vars expression in any workflow node can read. Projects (/projects) group workflows and credentials, with endpoints to manage project members and roles.
If your instance is connected to a Git repository, the source control endpoints let you preview pending changes, pull and push from outside the UI. This is how teams that prefer GitOps-style workflow deployment automate the round-trip.
curl "$BASE/workflows?active=true&projectId=$PROJECT_ID&limit=100" \
-H "X-N8N-API-KEY: $N8N_API_KEY"
curl "$BASE/workflows/$WORKFLOW_ID" \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
| jq '.' > workflows/customer-onboarding.json
# From a GitHub Actions step on push to main
curl -X POST "$PROD_BASE/workflows" \
-H "X-N8N-API-KEY: $N8N_PROD_API_KEY" \
-H "Content-Type: application/json" \
--data @workflows/customer-onboarding.json
SINCE=$(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
curl "$BASE/executions?status=error&startedAfter=$SINCE&limit=250" \
-H "X-N8N-API-KEY: $N8N_API_KEY"
prod after a maintenance windowIDS=$(curl -s "$BASE/workflows?tags=prod&active=false&limit=250" \
-H "X-N8N-API-KEY: $N8N_API_KEY" | jq -r '.data[].id')
for id in $IDS; do
curl -X POST "$BASE/workflows/$id/publish" \
-H "X-N8N-API-KEY: $N8N_API_KEY"
done
curl -X POST "$BASE/credentials" \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
-H "Content-Type: application/json" \
--data "{\"name\":\"Slack Prod\",\"type\":\"slackApi\",\"data\":{\"accessToken\":\"$SLACK_TOKEN\"}}"
Every list endpoint paginates with cursor-based navigation. The response shape is { "data": [...], "nextCursor": "abc123" | null }. When nextCursor is null, you have reached the end. Page size defaults to 100 and maxes at 250. The cursor is opaque — do not parse it; just pass it back unchanged on the next request.
Errors follow standard HTTP codes. 400 means your request body or query string is malformed. 401 means the API key is missing, malformed, or expired. 403 means the key is valid but lacks scope (Enterprise only) or you are trying to mutate a workflow owned by another user. 404 means the resource ID does not exist.
One edge case to plan for: credential data is opaque. When you GET a workflow that uses a credential, its secret values are not included, so you cannot fully clone a workflow across instances via the API alone. You must POST the credential separately first.
n8n's webhook trigger nodes give every workflow a public URL of the form https://your-instance/webhook/<path>. External services call that URL and the workflow runs. The REST API is for the inverse: your code calling n8n to manage the workflows themselves.
In production, you use both. Webhooks for the actual data flow (Stripe pings n8n, n8n syncs a customer to Salesforce). The REST API for the operational layer (CI deploys the workflow, observability pulls execution stats, an admin tool toggles workflows on/off during maintenance). The two are authenticated separately: webhook authentication is configured on the webhook node, the API uses an API key.
n8n does not ship a language SDK, but its docs recommend the n8n CLI, which wraps the public API, for scripting and CI/CD, and the n8n API node calls the API from inside workflows. Raw fetch or requests also works.
The official API reference is generated from an OpenAPI 3.0 spec, and self-hosted instances serve a Swagger UI playground at /api/v1/docs. Point a code generator such as openapi-typescript or openapi-generator at the spec for a typed client.
Five things to do before the API touches a production workload. First, set a non-zero expiration on every key — 90 days is the right default. Second, use a dedicated key per integration (one for CI, one for observability, one for the admin tool) so revoking one does not break the others. Third, store keys in a secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault) and never commit them to source control. Fourth, log all API access at the reverse-proxy layer so you have an audit trail independent of n8n's own logs. Fifth, restrict outbound network access from your CI runners to only your n8n instance — if a CI runner is compromised, you do not want the leaked key to be reachable from arbitrary internet IPs.
Generate an API key in Settings > n8n API, then send it as the X-N8N-API-KEY header on every request. Enterprise users can additionally restrict keys with scopes. Non-Enterprise keys have full access to the account's resources.
It is included in every self-hosted edition, including the free Community edition, and on the n8n Cloud Starter, Pro and Enterprise plans. It isn't available during the Cloud free trial.
If you are evaluating n8n itself rather than just the API, read our full n8n review for 2026 — pricing, feature depth, and where it wins versus Zapier. For the head-to-head: n8n vs Zapier and n8n vs Make. For the pricing-only deep-dive, see n8n Pricing 2026.
Start on self-hosted n8n Community or a paid n8n Cloud plan; the API isn't available on the Cloud free trial.
Read the Full Review Pricing Guide