Introduction
Connecting apps doesn't require a large integration team. With n8n, you can connect to any API--REST or GraphQL--in minutes using an HTTP Request Node, reusable credentials (API Key, Basic Auth, OAuth2), and Visual Logic. This guide shows you step-by-step how to build reliable n8n API integrations that handle headers, query parameters, JSON bodies, pagination, rate limits, retries, and webhooks, ensuring your data flows smoothly without requiring manual intervention. Whether you're syncing CRM contacts, pushing orders to ERP, or pulling analytics for a dashboard, you'll learn practical patterns that you can copy, adapt, and quickly ship into production.
1. Understand the n8n Building Blocks
- Nodes: Each node acts (e.g., HTTP call, transform, IF check, etc.).
- Credentials: Save API keys or OAuth2 once; reuse safely across nodes.
- Expressions: Use
{{$json.field}}and{{$now}}to build dynamic URLs and payloads. - Items: n8n processes arrays as "items." Many nodes output multiple items that you can loop through.
Keep Credentials separate from nodes, and never hardcode secrets. It makes your workflows secure and portable.
2. The Core: HTTP Request Node (Call Any REST API)
- Add an HTTP Request node.
- Choose Method: GET, POST, PUT, PATCH, DELETE.
- URL: Paste the endpoint (e.g.,
https://api.example.com/v1/resources). - Authentication: pick None (for public), API Key, Basic Auth, or OAuth2.
- Add Query Parameters (e.g.,
?page=1&limit=50) and Headers (e.g.,Content-Type: application/json, Authorization: Bearer _). - For POST/PUT/PATCH, choose JSON and add a body like:
{ "name": "Sample", "status": "active" } - Set Response to JSON (most APIs return JSON).
3. Authentication Patterns (API Key, Basic, OAuth2)
API Key (Header or Query)
- In Credentials, create "API Key" or use "HTTP Header Auth."
- Common header names:
Authorization: Bearer , x-api-key: .
Basic Auth
- Use Username/Password credentials.
- Typical for older or internal APIs.
OAuth2 (for Google, GitHub, HubSpot, etc.)
- Create an OAuth2 credential in n8n with:
- Client ID and Client Secret
- Auth URL and Token URL
- Scopes
- Grant Type: usually Authorization Code
- In your provider console, set Redirect URL to the one n8n shows.
- In the HTTP Request node, select the OAuth2 credential; n8n handles token refresh automatically.
4. Real Examples You Can Copy
A. GET with Query + Header (API Key)
Use this for public APIs or services with header tokens.
URL: https://api.weatherapi.com/v1/current.json?q={{$json.city}}
- Query:
key={{$credentials.weatherApiKey}} - Transform the output: Use a Set
node: city = {{$json.location.name}} tempC = {{$json.current.temp_c}} condition = {{$json.current.condition.text}}
B. POST JSON (Create a Record)
URL: https://api.example-crm.com/v2/contacts
Method: POST
Headers: Content-Type: application/json, Authorization: Bearer {{$credentials.crmToken}}
JSON Body:
{
"first_name": "{{$json.firstName}}",
"last_name": "{{$json.lastName}}",
"email": "{{$json.email}}",
"tags": ["n8n", "inbound"]
}
C. GraphQL with n8n
URL: https://api.github.com/graphql
Method: POST
Headers: Authorization: Bearer {{$credentials.githubToken}}, Content-Type: application/json
JSON Body:
{
"query": "query ($login: String!) { user(login: $login) { name bio repositories(first: 5) { nodes { name stargazerCount } } } }",
"variables": { "login": "{{$json.githubUser}}" }
}
Parse data.user.repositories.nodes downstream.
5. Pagination (Page/Limit, Cursor, Next Link)
APIs paginate to protect performance. Three common patterns:
Page & Limit
- Example:
?page={{$json.page}}&limit=100. - Use a Loop (e.g., Split In Batches or a While pattern) to increment the
pageuntil the response length < limit.
Cursor / Next Token
- Response returns a
next_cursor. - Store it with a Set node:
cursor = {{$json.meta.next_cursor}}.
Loop while cursor exists:
https://api.example.com/v1/items?cursor={{$json.cursor}}
Link Header / Next URL
- Some APIs give a
nextURL in the headers or body. - Read it and call the next page until the
nextis null.
6. Rate Limits, Retries & Backoff
Stay friendly to APIs:
- In HTTP Request Options:
- Retry on Fail: enable; set Max Attempts (e.g., 3–5)
- Retry Delay: 500–2000 ms (or exponential backoff using expressions)
- Timeout: reasonable (e.g., 30–60s)
- Insert a Wait node between pages if the API says "X requests per second."
- Handle HTTP 429/5xx with an IF node → Wait → retry branch.
Backoff expression sketch:
{{$json.attempt? Math.min(30000, 1000 * 2 ** $json.attempt) : 1000}}
Increment attempt per loop.
7. Transform & Map Data (Clean JSON Before Saving)
Use Set, Item Lists, and Function nodes to reshape data:
- Pick fields with Set: choose only what you need.
- Rename fields:
customerEmail = {{$json.email}}. - Flatten arrays with Item Lists.
Function node (lightweight JS) for tricky transforms:
// Example: map API items to a clean schema
return items.map(item => {
const i = item.json;
return { json: {
id: i.id,
name: i.name?.trim(),
price: Number(i.price || 0),
inStock: i.qty > 0
}};
});
8. Triggering Flows: Webhook vs Schedule
Webhook → API
- Add a Webhook node (method: POST).
- Receive JSON from a form/app, then call the target API via HTTP Request.
- Great for near-real-time integrations (e.g., "on order created, push to ERP").
Cron (Schedule) → API
- Use Cron to run every X minutes/hours/day.
- Ideal for polling APIs (sync contacts nightly, fetch yesterday's orders, etc.).
9. Connect to Secured/Internal APIs
- If your API is internal, deploy n8n within the same network/VPC or via VPN.
- Use Basic Auth or JWT. Put base URLs in Environment variables or Credentials to keep workflows portable.
- For self-signed HTTPS, enable Ignore SSL Issues only in non-prod (and fix certs ASAP).
10. Testing & Troubleshooting Checklist
- Test with sample data first (start small).
- Check Execution Data (left panel) to see the exact request/response.
- Validate status codes: 2xx OK, 4xx client issues (auth, params), 5xx server issues.
- Verify Content-Type and Accept headers (JSON vs form).
- Ensure scopes in OAuth2 match your endpoints.
- If getting CORS errors in browser embeds, run the call server-side with n8n (it already is).
- For pagination bugs, log page counts and stop when response length < limit or next cursor is empty.
11. Putting It Together: A Reusable Pattern
Here's a clean pattern for a robust sync:
- Cron (every hour)
- Set:
page = 1,limit = 100,attempt = 0 - HTTP Request (GET with page/limit)
- IF (status not 200) → Wait (backoff) → retry (increment
attempt) - Set: normalize fields
- Merge (Append) all items from each page
- IF (
items.length === limit) → incrementpage→ loop - Destination: Database/API/Sheet/ERP (another HTTP Request or DB node)
- Notify on errors (Slack/Email)
This approach works for CRM → ERP, Shop → Inventory, Helpdesk → BI, and more.
12. GraphQL Quick Notes (Connect "Any" GraphQL API)
- Always POST to the GraphQL endpoint.
- Body must include
queryand (optional)variables. - Use fragments for large queries; paginate via arguments (
first,aftercursors). - Parse results under
data.*.
13. Security & Governance
- Store secrets only in Credentials.
- Restrict who can view credentials in n8n.
- Use per-environment credentials (dev/stage/prod).
- Log only non-sensitive fields; mask tokens in execution logs.
Final Tips for Production-Ready n8n API Integrations
- Start with a manual run using sample data.
- Add guards: IF nodes for missing fields, invalid IDs, or empty arrays.
- Centralize error handling (Merge error branches → Slack/Email node).
- Version your workflows; export JSON regularly.
- Document credentials and scopes in your repo's runbook.