Most workflow templates require credentials for external services — databases, Slack, APIs, etc. This guide covers how to configure each credential type in n8n.
n8n stores credentials encrypted in its database. You create credential entries in the UI, then reference them in workflow nodes. Credentials are never stored in the workflow JSON files, so importing a template won't expose any secrets.
1. Go to Settings → Credentials in the n8n sidebar
2. Click "Add Credential"
3. Search for the service type (e.g., "PostgreSQL", "Slack")
4. Fill in the connection details
5. Click "Save" — n8n tests the connection automatically
Used by: most monitoring, reporting, and data processing workflows.
| Field | Example Value | Notes |
|---|---|---|
| Host | localhost | Use postgres if running in Docker alongside n8n |
| Port | 5432 | Default PostgreSQL port |
| Database | myapp | Your application database name |
| User | readonly_user | Use a read-only user for monitoring/reporting |
| Password | •••••••• | Stored encrypted by n8n |
| SSL | false | Set to true for remote/cloud databases |
Tip: Create a dedicated read-only database user for n8n workflows. This limits the blast radius if a workflow has a bug.
Used by: notification, monitoring, and reporting workflows.
Option A: Webhook (simpler, limited)
HTTP Request nodes with the webhook URLOption B: OAuth App (full access)
1. Create a Slack app at api.slack.com/apps
2. Add OAuth scopes: chat:write, channels:read
3. Install to your workspace
4. Copy the Bot User OAuth Token
5. In n8n, create a "Slack API" credential with the token
Used by: email digest, invoice, and report workflows.
| Field | Gmail | Outlook | Custom |
|---|---|---|---|
| Host | smtp.gmail.com | smtp-mail.outlook.com | Your SMTP host |
| Port | 587 | 587 | Usually 587 (TLS) or 465 (SSL) |
| User | you@gmail.com | you@outlook.com | Your email |
| Password | App Password | App Password | Your password |
| SSL/TLS | STARTTLS | STARTTLS | Depends |
Gmail note: You need an "App Password" (not your regular password). Enable 2FA, then generate one at myaccount.google.com/apppasswords.
Used by: GitHub, Stripe, OpenAI, Airtable, Jira, and custom API integrations.
For APIs that use Bearer tokens or API keys:
1. Create a "Header Auth" credential
2. Set the header name (usually Authorization)
3. Set the value (usually Bearer YOUR_API_KEY_HERE)
For the GitHub Issue Sync workflow:
1. Generate a Personal Access Token at github.com/settings/tokens
2. Select scopes: repo (for private repos) or public_repo (for public only)
3. Create a "Header Auth" credential with Authorization: token YOUR_TOKEN
For the Stripe Webhook Handler:
1. Get your webhook signing secret from the Stripe dashboard → Developers → Webhooks
2. Set up a webhook endpoint pointing to your n8n webhook URL
3. Select the events you want to receive
For the SMS Alert Pipeline:
1. Sign up at twilio.com
2. Get your Account SID and Auth Token from the dashboard
3. Buy a phone number for sending SMS
4. Create a "Basic Auth" credential with SID as username and Auth Token as password
Some workflows reference environment variables using $env.VARIABLE_NAME. Set these in your Docker Compose environment section or .env file:
# GitHub integration
GITHUB_ORG=your-github-org
GITHUB_REPO=your-repo-name
# Application settings
APP_NAME=MyApp
ALERT_EMAIL=team@example.com
MONITORING_SLACK_CHANNEL=#monitoring1. Least privilege: Create database users with only the permissions each workflow needs
2. Rotate tokens: Set calendar reminders to rotate API tokens quarterly
3. Audit access: Periodically review which credentials are in use — delete unused ones
4. Network isolation: If n8n is in Docker, use Docker networks to limit which services it can reach
5. Webhook secrets: For incoming webhooks, always validate request signatures when the source supports it (Stripe, GitHub, etc.)
Without error handling, a failing node silently stops your workflow. A stale-data alert that never fires is worse than no alert at all — you think you're monitoring when you're not. These patterns ensure your workflows fail loudly and recover gracefully.
The simplest approach: create a dedicated "error handler" workflow that catches failures from any other workflow.
1. Create a workflow with an Error Trigger node as the start
2. The Error Trigger fires whenever any workflow in your n8n instance fails
3. Format the error details and send a notification
workflows/notifications/slack-alert-on-error.jsonThis template is included in the collection and implements exactly this pattern.
n8n nodes have a secondary "error" output. You can route errors to a different path instead of letting them stop the workflow.
1. Click the node that might fail
2. In Settings, enable "Continue on Fail"
3. Add an IF node after it to check for errors:
{{ $json.error }} exists4. Route errors to a notification node
5. Route successes to the next step
[HTTP Request] → [IF has error?]
├── YES → [Log Error] → [Notify]
└── NO → [Process Data] → [Continue...]
For transient failures (API rate limits, network blips), retry the operation with increasing delays.
// Retry logic with exponential backoff
const maxRetries = 3;
const baseDelay = 1000; // 1 second
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
// Your API call here
const response = await this.helpers.httpRequest({
method: 'GET',
url: 'https://api.example.com/data',
timeout: 10000,
});
return [{ json: response }];
} catch (error) {
if (attempt === maxRetries) {
return [{ json: { error: error.message, attempts: attempt, failed: true } }];
}
// Exponential backoff: 1s, 2s, 4s
const delay = baseDelay * Math.pow(2, attempt - 1);
await new Promise(resolve => setTimeout(resolve, delay));
}
}When a record fails to process, don't lose it — save it to a "dead letter" table for manual review and reprocessing.
1. Main processing path: try to process the record
2. On failure: insert the record into a dead_letter_queue table with the error message
3. Create a separate workflow that periodically retries dead-letter items
CREATE TABLE dead_letter_queue (
id SERIAL PRIMARY KEY,
workflow_name TEXT NOT NULL,
original_data JSONB NOT NULL,
error_message TEXT,
retry_count INTEGER DEFAULT 0,
max_retries INTEGER DEFAULT 3,
status TEXT DEFAULT 'pending', -- pending, retrying, failed, resolved
created_at TIMESTAMP DEFAULT NOW(),
last_retry_at TIMESTAMP
);If an external service is down, stop hammering it. Track failure counts and "open the circuit" after N consecutive failures.
1. Use a Function node to check a "circuit state" variable
2. If the circuit is open, skip the API call and use cached data
3. If closed, make the call and track success/failure
4. After 5 consecutive failures, open the circuit for 5 minutes
Design workflows so running them twice produces the same result. This makes retries safe.
ON CONFLICT ... DO UPDATE in SQLINSERT INTO processed_records (external_id, data, processed_at)
VALUES ($1, $2, NOW())
ON CONFLICT (external_id) DO UPDATE SET
data = EXCLUDED.data,
processed_at = NOW();Real workflows typically combine multiple patterns:
1. Error Trigger as a global safety net
2. Try/Catch on individual nodes that might fail
3. Retry with Backoff for API calls
4. Dead Letter Queue for records that fail all retries
5. Idempotent Operations so retries are always safe
Start simple (Pattern 1) and add more sophisticated handling as your workflows mature.
Get the full N8N Workflow Templates and unlock everything.
Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.
Access all interactive tools with complete data, all workload profiles, and the full scenario library.
Downloadable source code, configuration files, and working examples from every chapter.
Free updates for life. Every new chapter, tool, and improvement included.