n8n API Integration Patterns
HTTP Request node configuration, authentication, pagination, response handling, and batch requests for n8n v1.x.
Quick Reference
| Task |
Solution |
| Call a REST API |
HTTP Request node with method, URL, and authentication |
| Authenticate with API key |
Predefined credential or Generic Credential (Header Auth / Query Auth) |
| Authenticate with OAuth2 |
Predefined OAuth2 credential with callback URL configuration |
| Handle paginated responses |
HTTP Request node pagination options (offset, cursor, or link-based) |
| Download a file |
HTTP Request node with Response Format set to File |
| Send JSON body |
Body Content Type = JSON, provide key-value pairs or raw JSON |
| Send form data |
Body Content Type = Form-Data (multipart or URL-encoded) |
| Batch API calls |
Split In Batches node before HTTP Request node |
| Handle API errors |
Enable Retry On Fail and/or Continue On Fail per node |
| Access response metadata |
$response.statusCode, $response.headers, $response.body |
Decision Tree: Which Authentication Method
Need to call an external API?
├── API has a built-in n8n node? → Use the dedicated node with its predefined credential
├── API uses API key?
│ ├── Key goes in header? → Generic Credential (Header Auth)
│ ├── Key goes in query string? → Generic Credential (Query Auth)
│ └── Key goes in request body? → Use HTTP Request node with expressions
├── API uses OAuth2?
│ ├── n8n has predefined OAuth2 credential? → Use it (ALWAYS preferred)
│ └── No predefined credential? → Generic OAuth2 API credential
├── API uses Basic Auth?
│ └── Generic Credential (Basic Auth) or HTTP Request Header Auth credential
└── API uses Bearer Token?
└── Generic Credential (Header Auth) with `Authorization: Bearer <token>`
Decision Tree: Which Pagination Strategy
API returns paginated results?
├── Response includes next page URL?
│ └── Use "Response Contains Next URL" pagination mode
├── Response includes cursor/token for next page?
│ └── Use "Response Contains Next URL" with cursor parameter mapping
├── API uses offset + limit?
│ └── Use "Specify How Each Page Is Determined" with offset increment
└── API uses page numbers?
└── Use "Specify How Each Page Is Determined" with page number increment
HTTP Request Node Configuration
Methods
| Method |
Use Case |
| GET |
Retrieve data (NEVER include a body) |
| POST |
Create resources, send data |
| PUT |
Full resource replacement |
| PATCH |
Partial resource update |
| DELETE |
Remove resources |
| HEAD |
Check resource existence without body |
URL Configuration
- ALWAYS use the full URL including protocol:
https://api.example.com/v1/resource
- Use expressions for dynamic URLs:
https://api.example.com/v1/users/{{ $json.userId }}
- NEVER hardcode credentials in the URL — use authentication options instead
Body Content Types
| Type |
When to Use |
| JSON |
REST APIs expecting JSON payloads (most common) |
| Form URL-Encoded |
APIs expecting application/x-www-form-urlencoded |
| Form-Data (Multipart) |
File uploads, mixed data + file payloads |
| Binary |
Sending raw binary data (images, PDFs) |
| Raw |
Custom content types (XML, plain text, GraphQL) |
| n8n Binary File |
Sending a binary file from a previous node's output |
Headers and Query Parameters
- Add custom headers via the Headers section (key-value pairs)
- Add query parameters via the Query Parameters section
- Use expressions in values:
{{ $json.token }} or {{ $vars.apiVersion }}
- ALWAYS set
Content-Type explicitly when using Raw body type
Response Handling
| Response Format |
Output |
| JSON |
Parsed JSON object in $json |
| Text |
Raw text string in $json.data |
| File |
Binary data attached to item (for downloads) |
| Autodetect |
n8n determines format from Content-Type header |
Response metadata (available ONLY in HTTP Request node context):
$response.statusCode — HTTP status code (200, 404, etc.)
$response.headers — Response headers object
$response.body — Response body
$response.statusMessage — Status message string
Authentication Options
Predefined Credentials
ALWAYS use predefined credentials when available. n8n includes credentials for 400+ services.
- Open HTTP Request node settings
- Set Authentication to "Predefined Credential Type"
- Select the service from the dropdown
- Create or select existing credential
Generic Credentials
Use when no predefined credential exists for your API.
| Generic Type |
Injection Point |
| Header Auth |
Custom header (e.g., X-API-Key: <value>) |
| Query Auth |
URL query parameter (e.g., ?api_key=<value>) |
| Basic Auth |
Authorization: Basic <base64(user:pass)> header |
| Digest Auth |
HTTP Digest authentication |
| OAuth1 API |
OAuth 1.0a flow |
| OAuth2 API |
OAuth 2.0 flow (Authorization Code, Client Credentials) |
| Custom Auth |
Arbitrary headers, query params, or body fields |
OAuth2 Configuration
- Create a new OAuth2 API credential in n8n
- Configure these fields:
- Authorization URL — Provider's authorization endpoint
- Access Token URL — Provider's token endpoint
- Client ID — From API provider's developer console
- Client Secret — From API provider's developer console
- Scope — Required permissions (space-separated)
- Auth URI Query Parameters — Additional params if needed
- Copy the OAuth Callback URL from n8n (displayed in credential form)
- Register this callback URL in the API provider's developer console
- Click Connect my account to complete the authorization flow
Token refresh: n8n handles token refresh automatically when Refresh Token is provided. NEVER store tokens manually in workflow logic.
Callback URL format: https://<n8n-host>/rest/oauth2-credential/callback
Pagination
Automatic Pagination Modes
Enable pagination in HTTP Request node under Options > Pagination.
Mode 1: Response Contains Next URL
- n8n extracts the next page URL from the response
- Configure the Next URL expression:
{{ $response.body.next }} or {{ $response.headers.link }}
- ALWAYS set a Maximum Pages limit to prevent infinite loops
Mode 2: Specify How Each Page Is Determined
- Configure page parameters manually for offset, cursor, or page-number APIs
- Set Page Size parameter name and value
- Set Pagination Parameter with increment logic
- Access current page count via
$pageCount
Pagination Completion
ALWAYS configure a stop condition:
- Maximum Pages — Hard limit on pages fetched
- Complete When expression — Stop when response indicates no more data
- Example:
{{ $response.body.results.length === 0 }}
- Example:
{{ $response.body.hasMore === false }}
Batch Requests
Split In Batches Pattern
When sending many items to an API (rate-limited or bulk operations):
- Add Split In Batches node before HTTP Request
- Set Batch Size to match API rate limits (e.g., 10 items per batch)
- Connect HTTP Request node to Split In Batches output
- Connect a Wait node after HTTP Request if rate limiting requires delays
- Loop back to Split In Batches node
Item-Level Processing
The HTTP Request node processes each input item separately by default. If you have 50 items, it makes 50 HTTP calls.
- ALWAYS use Split In Batches when calling APIs with rate limits
- NEVER send all items at once to rate-limited APIs — this causes 429 errors
Error Handling for API Calls
Retry On Fail
Enable in node Settings tab:
- Retry On Fail: true
- Max Tries: 3 (recommended for transient errors)
- Wait Between Tries: 1000ms (increase for rate-limited APIs)
ALWAYS enable Retry On Fail for external API calls. Network issues and rate limits cause transient failures.
Continue On Fail
Enable in node Settings tab to prevent workflow failure on API errors:
- Failed items receive
$json.error with error details
- Use an IF node after to route errors vs. successes
Error Output Branch
The HTTP Request node supports an error output (second output connector):
- Route failed requests to a separate processing path
- Check
$json.error, $json.statusCode for error details
Status Code Handling
Use the IF node after HTTP Request to branch on status codes:
{{ $response.statusCode === 200 }} — Success path
{{ $response.statusCode === 429 }} — Rate limited, needs retry/wait
{{ $response.statusCode >= 400 }} — Client/server error path
Generic Credential Request Pattern
For custom APIs without a dedicated n8n node:
- Create a Generic Credential (Header Auth, Query Auth, or OAuth2)
- Configure the credential with your API's auth details
- In HTTP Request node, select Authentication > Predefined Credential Type
- Choose the generic credential type you created
- Build requests using URL, method, headers, query params, and body
This pattern keeps credentials encrypted and reusable across multiple HTTP Request nodes.
Key Rules
- ALWAYS use predefined credentials over manual header injection
- ALWAYS set pagination limits to prevent infinite request loops
- ALWAYS enable Retry On Fail for external API calls
- ALWAYS use Split In Batches for bulk API operations with rate limits
- NEVER hardcode API keys, tokens, or secrets in expressions or URLs
- NEVER use the Code node for HTTP requests — ALWAYS use the HTTP Request node
- NEVER send request bodies with GET or HEAD methods
- NEVER ignore
$response.statusCode — ALWAYS handle non-200 responses
Reference Files
- methods.md — HTTP Request node options, OAuth2 flow, pagination options, generic credentials
- examples.md — REST API integration, OAuth2 flow, paginated fetching, batch requests
- anti-patterns.md — Common integration mistakes and corrections
1---2name: n8n-impl-integrations3description: Use when integrating external APIs in n8n v1.x via HTTP Request node or OAuth2 credentials. Prevents pagination bugs from missing response handling or incorrect credential configuration. Covers HTTP Request node configuration, OAuth2 credential flows, pagination handling, generic credential usage for custom APIs, binary downloads, batch request patterns, and API error handling. Keywords: n8n, HTTP Request, API integration, OAuth2, pagination, credentials, connect to API, HTTP request, OAuth login, pagination, download file, batch requests..4license: MIT5---67# n8n API Integration Patterns89> HTTP Request node configuration, authentication, pagination, response handling, and batch requests for n8n v1.x.1011## Quick Reference1213| Task | Solution |14|------|----------|15| Call a REST API | HTTP Request node with method, URL, and authentication |16| Authenticate with API key | Predefined credential or Generic Credential (Header Auth / Query Auth) |17| Authenticate with OAuth2 | Predefined OAuth2 credential with callback URL configuration |18| Handle paginated responses | HTTP Request node pagination options (offset, cursor, or link-based) |19| Download a file | HTTP Request node with Response Format set to File |20| Send JSON body | Body Content Type = JSON, provide key-value pairs or raw JSON |21| Send form data | Body Content Type = Form-Data (multipart or URL-encoded) |22| Batch API calls | Split In Batches node before HTTP Request node |23| Handle API errors | Enable Retry On Fail and/or Continue On Fail per node |24| Access response metadata | `$response.statusCode`, `$response.headers`, `$response.body` |2526## Decision Tree: Which Authentication Method2728```29Need to call an external API?30├── API has a built-in n8n node? → Use the dedicated node with its predefined credential31├── API uses API key?32│ ├── Key goes in header? → Generic Credential (Header Auth)33│ ├── Key goes in query string? → Generic Credential (Query Auth)34│ └── Key goes in request body? → Use HTTP Request node with expressions35├── API uses OAuth2?36│ ├── n8n has predefined OAuth2 credential? → Use it (ALWAYS preferred)37│ └── No predefined credential? → Generic OAuth2 API credential38├── API uses Basic Auth?39│ └── Generic Credential (Basic Auth) or HTTP Request Header Auth credential40└── API uses Bearer Token?41 └── Generic Credential (Header Auth) with `Authorization: Bearer <token>`42```4344## Decision Tree: Which Pagination Strategy4546```47API returns paginated results?48├── Response includes next page URL?49│ └── Use "Response Contains Next URL" pagination mode50├── Response includes cursor/token for next page?51│ └── Use "Response Contains Next URL" with cursor parameter mapping52├── API uses offset + limit?53│ └── Use "Specify How Each Page Is Determined" with offset increment54└── API uses page numbers?55 └── Use "Specify How Each Page Is Determined" with page number increment56```5758## HTTP Request Node Configuration5960### Methods6162| Method | Use Case |63|--------|----------|64| GET | Retrieve data (NEVER include a body) |65| POST | Create resources, send data |66| PUT | Full resource replacement |67| PATCH | Partial resource update |68| DELETE | Remove resources |69| HEAD | Check resource existence without body |7071### URL Configuration7273- ALWAYS use the full URL including protocol: `https://api.example.com/v1/resource`74- Use expressions for dynamic URLs: `https://api.example.com/v1/users/{{ $json.userId }}`75- NEVER hardcode credentials in the URL — use authentication options instead7677### Body Content Types7879| Type | When to Use |80|------|-------------|81| JSON | REST APIs expecting JSON payloads (most common) |82| Form URL-Encoded | APIs expecting `application/x-www-form-urlencoded` |83| Form-Data (Multipart) | File uploads, mixed data + file payloads |84| Binary | Sending raw binary data (images, PDFs) |85| Raw | Custom content types (XML, plain text, GraphQL) |86| n8n Binary File | Sending a binary file from a previous node's output |8788### Headers and Query Parameters8990- Add custom headers via the **Headers** section (key-value pairs)91- Add query parameters via the **Query Parameters** section92- Use expressions in values: `{{ $json.token }}` or `{{ $vars.apiVersion }}`93- ALWAYS set `Content-Type` explicitly when using Raw body type9495### Response Handling9697| Response Format | Output |98|-----------------|--------|99| JSON | Parsed JSON object in `$json` |100| Text | Raw text string in `$json.data` |101| File | Binary data attached to item (for downloads) |102| Autodetect | n8n determines format from Content-Type header |103104**Response metadata** (available ONLY in HTTP Request node context):105- `$response.statusCode` — HTTP status code (200, 404, etc.)106- `$response.headers` — Response headers object107- `$response.body` — Response body108- `$response.statusMessage` — Status message string109110## Authentication Options111112### Predefined Credentials113114ALWAYS use predefined credentials when available. n8n includes credentials for 400+ services.1151161. Open HTTP Request node settings1172. Set **Authentication** to "Predefined Credential Type"1183. Select the service from the dropdown1194. Create or select existing credential120121### Generic Credentials122123Use when no predefined credential exists for your API.124125| Generic Type | Injection Point |126|--------------|-----------------|127| Header Auth | Custom header (e.g., `X-API-Key: <value>`) |128| Query Auth | URL query parameter (e.g., `?api_key=<value>`) |129| Basic Auth | `Authorization: Basic <base64(user:pass)>` header |130| Digest Auth | HTTP Digest authentication |131| OAuth1 API | OAuth 1.0a flow |132| OAuth2 API | OAuth 2.0 flow (Authorization Code, Client Credentials) |133| Custom Auth | Arbitrary headers, query params, or body fields |134135### OAuth2 Configuration1361371. Create a new **OAuth2 API** credential in n8n1382. Configure these fields:139 - **Authorization URL** — Provider's authorization endpoint140 - **Access Token URL** — Provider's token endpoint141 - **Client ID** — From API provider's developer console142 - **Client Secret** — From API provider's developer console143 - **Scope** — Required permissions (space-separated)144 - **Auth URI Query Parameters** — Additional params if needed1453. Copy the **OAuth Callback URL** from n8n (displayed in credential form)1464. Register this callback URL in the API provider's developer console1475. Click **Connect my account** to complete the authorization flow148149**Token refresh**: n8n handles token refresh automatically when `Refresh Token` is provided. NEVER store tokens manually in workflow logic.150151**Callback URL format**: `https://<n8n-host>/rest/oauth2-credential/callback`152153## Pagination154155### Automatic Pagination Modes156157Enable pagination in HTTP Request node under **Options > Pagination**.158159**Mode 1: Response Contains Next URL**160- n8n extracts the next page URL from the response161- Configure the **Next URL** expression: `{{ $response.body.next }}` or `{{ $response.headers.link }}`162- ALWAYS set a **Maximum Pages** limit to prevent infinite loops163164**Mode 2: Specify How Each Page Is Determined**165- Configure page parameters manually for offset, cursor, or page-number APIs166- Set **Page Size** parameter name and value167- Set **Pagination Parameter** with increment logic168- Access current page count via `$pageCount`169170### Pagination Completion171172ALWAYS configure a stop condition:173- **Maximum Pages** — Hard limit on pages fetched174- **Complete When** expression — Stop when response indicates no more data175 - Example: `{{ $response.body.results.length === 0 }}`176 - Example: `{{ $response.body.hasMore === false }}`177178## Batch Requests179180### Split In Batches Pattern181182When sending many items to an API (rate-limited or bulk operations):1831841. Add **Split In Batches** node before HTTP Request1852. Set **Batch Size** to match API rate limits (e.g., 10 items per batch)1863. Connect HTTP Request node to Split In Batches output1874. Connect a **Wait** node after HTTP Request if rate limiting requires delays1885. Loop back to Split In Batches node189190### Item-Level Processing191192The HTTP Request node processes each input item separately by default. If you have 50 items, it makes 50 HTTP calls.193194- ALWAYS use Split In Batches when calling APIs with rate limits195- NEVER send all items at once to rate-limited APIs — this causes 429 errors196197## Error Handling for API Calls198199### Retry On Fail200201Enable in node Settings tab:202- **Retry On Fail**: true203- **Max Tries**: 3 (recommended for transient errors)204- **Wait Between Tries**: 1000ms (increase for rate-limited APIs)205206ALWAYS enable Retry On Fail for external API calls. Network issues and rate limits cause transient failures.207208### Continue On Fail209210Enable in node Settings tab to prevent workflow failure on API errors:211- Failed items receive `$json.error` with error details212- Use an IF node after to route errors vs. successes213214### Error Output Branch215216The HTTP Request node supports an **error output** (second output connector):217- Route failed requests to a separate processing path218- Check `$json.error`, `$json.statusCode` for error details219220### Status Code Handling221222Use the IF node after HTTP Request to branch on status codes:223- `{{ $response.statusCode === 200 }}` — Success path224- `{{ $response.statusCode === 429 }}` — Rate limited, needs retry/wait225- `{{ $response.statusCode >= 400 }}` — Client/server error path226227## Generic Credential Request Pattern228229For custom APIs without a dedicated n8n node:2302311. Create a **Generic Credential** (Header Auth, Query Auth, or OAuth2)2322. Configure the credential with your API's auth details2333. In HTTP Request node, select **Authentication > Predefined Credential Type**2344. Choose the generic credential type you created2355. Build requests using URL, method, headers, query params, and body236237This pattern keeps credentials encrypted and reusable across multiple HTTP Request nodes.238239## Key Rules240241- ALWAYS use predefined credentials over manual header injection242- ALWAYS set pagination limits to prevent infinite request loops243- ALWAYS enable Retry On Fail for external API calls244- ALWAYS use Split In Batches for bulk API operations with rate limits245- NEVER hardcode API keys, tokens, or secrets in expressions or URLs246- NEVER use the Code node for HTTP requests — ALWAYS use the HTTP Request node247- NEVER send request bodies with GET or HEAD methods248- NEVER ignore `$response.statusCode` — ALWAYS handle non-200 responses249250## Reference Files251252- [methods.md](references/methods.md) — HTTP Request node options, OAuth2 flow, pagination options, generic credentials253- [examples.md](references/examples.md) — REST API integration, OAuth2 flow, paginated fetching, batch requests254- [anti-patterns.md](references/anti-patterns.md) — Common integration mistakes and corrections