- name
- n8n-api-reference
- description
- n8n REST API reference with all endpoints, authentication, and curl examples. Use when making direct API calls, writing scripts that interact with n8n API, or when MCP tools are unavailable. Reference-only skill.
# n8n REST API Reference
## Overview
n8n Public API, OpenAPI 3.0. The bundled `references/n8n-api.json` is the **n8n 2.41.6 public API, bundled from the n8n repo at tag `n8n@2.41.6`**: **154 operations across 26 tags** (Audit, CommunityPackage, Credential, DataTable, Discover, Evaluation, Executions, Folders, Insights, LogStreaming, N8nPackage, NodeTypePolicy, Projects, Promotions, Role, RoleMappingRule, SecurityPolicy, SettingsLdap, SettingsOtel, SettingsSsoOidc, SettingsSsoSaml, SourceControl, Tags, User, Variables, Workflow). `info.version` reads `1.1.1`; n8n does not bump it.
The public API allows programmatic access to workflows, executions, credentials, tags, users, variables, projects, folders, data tables, source control, evaluations, roles and audit features, plus instance administration for enterprise setups.
Full OpenAPI spec available at: `references/n8n-api.json`.
> **Match the spec to your instance.** Routes are version-specific (the table notes say from which n8n version where it matters). For the exact surface of the instance you target, open its API playground (`/api/v1/docs`) or read `GET /api/v1/discover`, which lists what the calling key may do.
---
## Authentication
All API requests require an API key passed via the `X-N8N-API-KEY` header.
### Generating an API Key
1. Open your n8n instance
2. Go to **Settings** → **n8n API**
3. Click **Create an API key** and choose its scopes and expiry
4. Copy the generated key (it is shown once)
The key carries **scopes** (for example `workflow:read`, `workflow:update`, `workflow:activate`); a call outside the key's scopes answers `403`, and each operation below lists the scope it needs. Besides `X-N8N-API-KEY`, the spec allows `BearerAuth` (JWT) and `CookieAuth` — an API key is the right choice for scripts.
### Base URL
`N8N_API_URL` may hold the instance root or already end in `/api/v1` — `n8n-mcp` accepts both.
Derive the root once per shell, then build every path from `N8N_BASE`:
```bash
N8N_BASE="${N8N_API_URL%/}"; N8N_BASE="${N8N_BASE%/api/v1}"
```
Every endpoint below is `${N8N_BASE}/api/v1/...`.
### Header Format
```
X-N8N-API-KEY: <your-api-key>
```
### Quick Verification
```bash
curl -H "X-N8N-API-KEY: $N8N_API_KEY" "$N8N_BASE/api/v1/workflows?limit=1"
```
If you get a 200 response with workflow data, authentication is working.
---
## Endpoint Reference by Tag
Every operation below comes from `references/n8n-api.json`. **Scope** is the API key scope the operation needs (`x-required-scope`); a key without it gets `403`. Paths are relative to `/api/v1`.
### Workflow (17 operations)
The spec also carries the deprecated `activate` and `deactivate` aliases of publish and unpublish; they are left out of the table. The deprecated version route is marked.
| Method | Endpoint | Description | Scope |
|--------|----------|-------------|-------|
| `GET` | `/workflows` | Retrieve all workflows | `workflow:list` |
| `POST` | `/workflows` | Create a workflow | `workflow:create` |
| `GET` | `/workflows/{id}/{versionId}` | **Deprecated.** Get one version of a workflow. Use `/workflows/{workflowId}/versions/{workflowVersionId}` instead (deprecated since n8n 2.39). | `workflow:read` |
| `GET` | `/workflows/{workflowId}` | Retrieve a workflow | `workflow:read` |
| `PUT` | `/workflows/{workflowId}` | Update a workflow. A published workflow is re-published unless `publishIfActive=false`. | `workflow:update` |
| `DELETE` | `/workflows/{workflowId}` | Delete a workflow | `workflow:delete` |
| `POST` | `/workflows/{workflowId}/archive` | Archive (soft-delete) a workflow. Idempotent. | `workflow:delete` |
| `GET` | `/workflows/{workflowId}/history` | List the saved versions of a workflow. | `workflow:read` |
| `POST` | `/workflows/{workflowId}/publish` | Publish a workflow so it responds to triggers. Optional body `{versionId, name, description}`. | `workflow:activate` |
| `GET` | `/workflows/{workflowId}/tags` | Get workflow tags | `workflowTags:list` |
| `PUT` | `/workflows/{workflowId}/tags` | Update tags of a workflow | `workflowTags:update` |
| `PUT` | `/workflows/{workflowId}/transfer` | Transfer a workflow to another project | `workflow:move` |
| `POST` | `/workflows/{workflowId}/unarchive` | Restore an archived workflow. | `workflow:delete` |
| `POST` | `/workflows/{workflowId}/unpublish` | Unpublish a workflow. Stops trigger-based execution. | `workflow:deactivate` |
| `GET` | `/workflows/{workflowId}/versions/{workflowVersionId}` | Retrieve a workflow version | `workflow:read` |
**Query parameters for `GET /workflows`:**
- `limit` — number of results (default 100, max 250); `cursor` — pagination cursor from the previous response; `offset` — legacy offset
- `active` — filter by published status (`true`/`false`)
- `tags` — filter by tag name; `name` — filter by workflow name; `projectId` — filter by project
- `excludePinnedData` — leave pinned data out of the response (default `false`)
**Publish, unpublish, re-publish.** In n8n 2.x a workflow body is a *draft*; what runs in production is the *published version*. `POST /workflows/{id}/publish` (n8n 2.33+, scope `workflow:activate`) takes an optional `versionId` (without it the latest version is published) and answers **409** when an open workflow review blocks it (`reason`, `workflowReviewRequestId`) or the webhook path collides with another workflow. `PUT /workflows/{id}` on a published workflow **re-publishes the update** unless the query has `publishIfActive=false`; the re-publication needs the `workflow:activate` scope **and** the `workflow:publish` project permission, otherwise the new version is stored as a draft and the response is `403` naming the missing permission (the published version stays live).
### Executions (8 operations)
| Method | Endpoint | Description | Scope |
|--------|----------|-------------|-------|
| `GET` | `/executions` | Retrieve all executions | `execution:list` |
| `POST` | `/executions/stop` | Stop multiple executions | `execution:stop` |
| `GET` | `/executions/{executionId}` | Retrieve an execution | `execution:read` |
| `DELETE` | `/executions/{executionId}` | Delete an execution | `execution:delete` |
| `POST` | `/executions/{executionId}/retry` | Retry an execution | `execution:retry` |
| `POST` | `/executions/{executionId}/stop` | Stop an execution | `execution:stop` |
| `GET` | `/executions/{executionId}/tags` | Get execution tags | `executionTags:list` |
| `PUT` | `/executions/{executionId}/tags` | Update tags of an execution | `executionTags:update` |
**Query parameters for `GET /executions`:**
- `workflowId`, `projectId` — filters
- `status` — `canceled`, `crashed`, `error`, `new`, `running`, `success`, `unknown`, `waiting`
- `limit` (default 100, max 250), `cursor`
- `includeData` (default `false`), `ignoreDataSizeLimit`, `redactExecutionData` — control the execution data in the response
- `startedAfter` / `startedBefore` — date range (ISO 8601)
### Credential (8 operations)
| Method | Endpoint | Description | Scope |
|--------|----------|-------------|-------|
| `GET` | `/credentials` | List credentials | `credential:list` |
| `POST` | `/credentials` | Create a credential | `credential:create` |
| `GET` | `/credentials/schema/{credentialTypeName}` | Show credential data schema | |
| `GET` | `/credentials/{credentialId}` | Get credential by ID | `credential:read` |
| `PATCH` | `/credentials/{credentialId}` | Update credential by ID | `credential:update` |
| `DELETE` | `/credentials/{credentialId}` | Delete credential by ID | `credential:delete` |
| `POST` | `/credentials/{credentialId}/test` | Test credential by ID | `credential:read` |
| `PUT` | `/credentials/{credentialId}/transfer` | Transfer a credential to another project. | `credential:move` |
**Important:** `GET /credentials` never returns secret data. Use the schema endpoint to learn the required fields before creating one. `POST /credentials/{id}/test` runs the credential's own test.
### DataTable (15 operations)
| Method | Endpoint | Description | Scope |
|--------|----------|-------------|-------|
| `GET` | `/data-tables` | List all data tables | `dataTable:list` |
| `POST` | `/data-tables` | Create a new data table | `dataTable:create` |
| `GET` | `/data-tables/{dataTableId}` | Get a data table | `dataTable:read` |
| `PATCH` | `/data-tables/{dataTableId}` | Update a data table | `dataTable:update` |
| `DELETE` | `/data-tables/{dataTableId}` | Delete a data table | `dataTable:delete` |
| `GET` | `/data-tables/{dataTableId}/columns` | List columns of a data table | `dataTableColumn:read` |
| `POST` | `/data-tables/{dataTableId}/columns` | Add a column to a data table | `dataTableColumn:create` |
| `PATCH` | `/data-tables/{dataTableId}/columns/{columnId}` | Update a column | `dataTableColumn:update` |
| `DELETE` | `/data-tables/{dataTableId}/columns/{columnId}` | Delete a column | `dataTableColumn:delete` |
| `GET` | `/data-tables/{dataTableId}/rows` | Retrieve rows from a data table | `dataTableRow:read` |
| `POST` | `/data-tables/{dataTableId}/rows` | Insert rows into a data table | `dataTableRow:create` |
| `DELETE` | `/data-tables/{dataTableId}/rows/clear` | Clear all rows from a data table | `dataTableRow:delete` |
| `DELETE` | `/data-tables/{dataTableId}/rows/delete` | Delete rows from a data table | `dataTableRow:delete` |
| `PATCH` | `/data-tables/{dataTableId}/rows/update` | Update rows in a data table | `dataTableRow:update` |
| `POST` | `/data-tables/{dataTableId}/rows/upsert` | Upsert a row in a data table | `dataTableRow:upsert` |
`GET /data-tables/{id}/rows` takes `limit` (default 100, max 250), `cursor`, `filter`, `sortBy` and `search`. Deleting a column drops its values.
### Folders (5 operations)
| Method | Endpoint | Description | Scope |
|--------|----------|-------------|-------|
| `GET` | `/projects/{projectId}/folders` | Retrieve folders | `folder:list` |
| `POST` | `/projects/{projectId}/folders` | Create a folder | `folder:create` |
| `GET` | `/projects/{projectId}/folders/{folderId}` | Get folder details | `folder:read` |
| `PATCH` | `/projects/{projectId}/folders/{folderId}` | Update a folder | `folder:update` |
| `DELETE` | `/projects/{projectId}/folders/{folderId}` | Delete a folder | `folder:delete` |
`GET /projects/{projectId}/folders` takes `filter`, `select`, `sortBy` (`name`, `createdAt` or `updatedAt`, `:asc` / `:desc`), `skip` and `take`.
### Projects (8 operations)
| Method | Endpoint | Description | Scope |
|--------|----------|-------------|-------|
| `GET` | `/projects` | Retrieve projects | `project:list` |
View on GitHub