> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/n8n-io/n8n/llms.txt
> Use this file to discover all available pages before exploring further.

# API Authentication

> Learn how to authenticate your API requests using API keys and manage access scopes

## Overview

n8n uses API key authentication to secure its REST API. Each API key can be configured with specific scopes to control access to different resources and operations.

## Creating an API Key

You can create API keys through the n8n user interface:

<Steps>
  <Step title="Navigate to Settings">
    Go to **Settings → API** in your n8n instance.
  </Step>

  <Step title="Create New Key">
    Click **Create API Key** and provide:

    * A descriptive label
    * Selected scopes (permissions)
    * Optional expiration date
  </Step>

  <Step title="Save the Key">
    Copy the generated API key immediately. It won't be shown again for security reasons.
  </Step>
</Steps>

<Warning>
  API keys are sensitive credentials. Store them securely and never commit them to version control.
</Warning>

## Authentication Methods

### API Key Header (Recommended)

Pass your API key in the `X-N8N-API-KEY` header:

```bash theme={null}
curl -H "X-N8N-API-KEY: your-api-key" \
  https://your-n8n-instance.com/api/v1/workflows
```

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET \
      -H "X-N8N-API-KEY: n8n_api_1234567890abcdef" \
      -H "Content-Type: application/json" \
      https://your-n8n-instance.com/api/v1/workflows
    ```
  </Tab>

  <Tab title="JavaScript (fetch)">
    ```javascript theme={null}
    const response = await fetch('https://your-n8n-instance.com/api/v1/workflows', {
      headers: {
        'X-N8N-API-KEY': 'n8n_api_1234567890abcdef',
        'Content-Type': 'application/json'
      }
    });

    const workflows = await response.json();
    ```
  </Tab>

  <Tab title="Python (requests)">
    ```python theme={null}
    import requests

    headers = {
        'X-N8N-API-KEY': 'n8n_api_1234567890abcdef',
        'Content-Type': 'application/json'
    }

    response = requests.get(
        'https://your-n8n-instance.com/api/v1/workflows',
        headers=headers
    )

    workflows = response.json()
    ```
  </Tab>

  <Tab title="Node.js (axios)">
    ```javascript theme={null}
    const axios = require('axios');

    const response = await axios.get('https://your-n8n-instance.com/api/v1/workflows', {
      headers: {
        'X-N8N-API-KEY': 'n8n_api_1234567890abcdef',
        'Content-Type': 'application/json'
      }
    });

    const workflows = response.data;
    ```
  </Tab>
</Tabs>

## Managing API Keys

### List API Keys

Retrieve all API keys for your account.

```http theme={null}
GET /api/v1/api-keys
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -H "X-N8N-API-KEY: your-api-key" \
    https://your-n8n-instance.com/api/v1/api-keys
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://your-n8n-instance.com/api/v1/api-keys', {
    headers: { 'X-N8N-API-KEY': 'your-api-key' }
  });
  const keys = await response.json();
  ```
</CodeGroup>

**Response:**

```json theme={null}
[
  {
    "id": "key_123",
    "label": "Production API Key",
    "apiKey": "n8n_api_••••••••••••cdef",
    "createdAt": "2024-01-15T10:30:00.000Z",
    "updatedAt": "2024-01-15T10:30:00.000Z",
    "expiresAt": null,
    "scopes": ["workflow:read", "workflow:execute"]
  }
]
```

<Note>
  API keys in list responses are redacted for security. Only the first few and last few characters are visible.
</Note>

### Create API Key

Generate a new API key with specified permissions.

```http theme={null}
POST /api/v1/api-keys
```

<ParamField body="label" type="string" required>
  A descriptive name for the API key
</ParamField>

<ParamField body="scopes" type="string[]" required>
  Array of permission scopes for this key
</ParamField>

<ParamField body="expiresAt" type="number" default="null">
  Unix timestamp (seconds) when the key expires. `null` for no expiration.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    -H "X-N8N-API-KEY: your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "label": "Integration API Key",
      "scopes": ["workflow:read", "execution:read"],
      "expiresAt": null
    }' \
    https://your-n8n-instance.com/api/v1/api-keys
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://your-n8n-instance.com/api/v1/api-keys', {
    method: 'POST',
    headers: {
      'X-N8N-API-KEY': 'your-api-key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      label: 'Integration API Key',
      scopes: ['workflow:read', 'execution:read'],
      expiresAt: null
    })
  });

  const newKey = await response.json();
  console.log('Save this key:', newKey.rawApiKey);
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "id": "key_456",
  "label": "Integration API Key",
  "apiKey": "n8n_api_••••••••••••cdef",
  "rawApiKey": "n8n_api_1234567890abcdef1234567890abcdef",
  "createdAt": "2024-02-19T14:20:00.000Z",
  "updatedAt": "2024-02-19T14:20:00.000Z",
  "expiresAt": null,
  "scopes": ["workflow:read", "execution:read"]
}
```

<Warning>
  The `rawApiKey` field is only returned on creation. Store it securely as it cannot be retrieved again.
</Warning>

### Update API Key

Modify an existing API key's label or scopes.

```http theme={null}
PATCH /api/v1/api-keys/:id
```

<ParamField path="id" type="string" required>
  The API key ID
</ParamField>

<ParamField body="label" type="string">
  New label for the API key
</ParamField>

<ParamField body="scopes" type="string[]">
  Updated array of permission scopes
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH \
    -H "X-N8N-API-KEY: your-api-key" \
    -H "Content-Type: application/json" \
    -d '{
      "label": "Updated API Key",
      "scopes": ["workflow:read", "workflow:update"]
    }' \
    https://your-n8n-instance.com/api/v1/api-keys/key_456
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "success": true
}
```

### Delete API Key

Revoke an API key permanently.

```http theme={null}
DELETE /api/v1/api-keys/:id
```

<ParamField path="id" type="string" required>
  The API key ID to delete
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X DELETE \
    -H "X-N8N-API-KEY: your-api-key" \
    https://your-n8n-instance.com/api/v1/api-keys/key_456
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "success": true
}
```

### Get Available Scopes

Retrieve the list of scopes available for your user role.

```http theme={null}
GET /api/v1/api-keys/scopes
```

**Response:**

```json theme={null}
[
  "workflow:read",
  "workflow:create",
  "workflow:update",
  "workflow:delete",
  "workflow:execute",
  "credential:read",
  "credential:create",
  "credential:update",
  "credential:delete",
  "execution:read",
  "execution:list"
]
```

## API Key Scopes

### Workflow Scopes

<ParamField query="workflow:read" type="scope">
  Read workflow configurations and metadata
</ParamField>

<ParamField query="workflow:create" type="scope">
  Create new workflows
</ParamField>

<ParamField query="workflow:update" type="scope">
  Modify existing workflows
</ParamField>

<ParamField query="workflow:delete" type="scope">
  Delete workflows
</ParamField>

<ParamField query="workflow:execute" type="scope">
  Trigger workflow executions
</ParamField>

<ParamField query="workflow:list" type="scope">
  List all accessible workflows
</ParamField>

<ParamField query="workflow:activate" type="scope">
  Activate workflows to run automatically
</ParamField>

<ParamField query="workflow:deactivate" type="scope">
  Deactivate active workflows
</ParamField>

### Credential Scopes

<ParamField query="credential:read" type="scope">
  Read credential metadata (not sensitive data)
</ParamField>

<ParamField query="credential:create" type="scope">
  Create new credentials
</ParamField>

<ParamField query="credential:update" type="scope">
  Update existing credentials
</ParamField>

<ParamField query="credential:delete" type="scope">
  Delete credentials
</ParamField>

<ParamField query="credential:list" type="scope">
  List all accessible credentials
</ParamField>

### Execution Scopes

<ParamField query="execution:read" type="scope">
  Read execution data and results
</ParamField>

<ParamField query="execution:list" type="scope">
  List workflow executions
</ParamField>

<ParamField query="execution:retry" type="scope">
  Retry failed executions
</ParamField>

<ParamField query="execution:stop" type="scope">
  Stop running executions
</ParamField>

<ParamField query="execution:delete" type="scope">
  Delete execution records
</ParamField>

## Security Best Practices

<AccordionGroup>
  <Accordion title="Rotate Keys Regularly">
    Generate new API keys periodically and revoke old ones to minimize security risks.
  </Accordion>

  <Accordion title="Use Minimum Required Scopes">
    Only grant the scopes necessary for your integration. This limits potential damage if a key is compromised.
  </Accordion>

  <Accordion title="Set Expiration Dates">
    For temporary integrations or testing, set an expiration date on API keys.
  </Accordion>

  <Accordion title="Monitor API Usage">
    Regularly review your API keys and their usage patterns to detect unauthorized access.
  </Accordion>

  <Accordion title="Use Environment Variables">
    Store API keys in environment variables, never hardcode them in your application.

    ```bash theme={null}
    export N8N_API_KEY="your-api-key"
    ```
  </Accordion>

  <Accordion title="Implement Request Signing (Advanced)">
    For high-security scenarios, consider implementing request signing or using OAuth where available.
  </Accordion>
</AccordionGroup>

## License Requirements

<Note>
  API Key Scopes is an enterprise feature. Without a license, API keys have access to all available scopes for the user's role.
</Note>

## Common Issues

### 401 Unauthorized

**Problem:** Request returns `401 Unauthorized`

**Solutions:**

* Verify the API key is correct
* Check that the key hasn't expired
* Ensure you're using the correct header name: `X-N8N-API-KEY`

### 403 Forbidden

**Problem:** Request returns `403 Forbidden`

**Solutions:**

* Verify your API key has the required scope for the operation
* Check that the key is active and not revoked
* Ensure you have access to the requested resource

### Rate Limiting

**Problem:** Request returns `429 Too Many Requests`

**Solutions:**

* Implement exponential backoff
* Reduce request frequency
* Cache responses when possible
* Contact support for higher limits if needed

## Next Steps

<CardGroup cols={2}>
  <Card title="Workflows API" icon="diagram-project" href="/api/workflows">
    Start managing workflows programmatically
  </Card>

  <Card title="Executions API" icon="play" href="/api/executions">
    Monitor and control workflow executions
  </Card>

  <Card title="Credentials API" icon="lock" href="/api/credentials">
    Manage authentication credentials
  </Card>

  <Card title="API Overview" icon="book" href="/api/overview">
    Return to API overview
  </Card>
</CardGroup>
