6.3 — Building Custom API Connectors in n8n
Building Custom API Connectors in n8n
n8n has 400+ built-in integrations. But what about JazzCash? Daraz Seller Center? Foodpanda's merchant API? Pakistani SaaS tools? Local government portals? When there's no built-in node, you build your own connector using the HTTP Request node. This lesson teaches you to connect n8n to ANY API — even ones with zero documentation.
The HTTP Request Node — Your Universal Connector
Any API in the world:
┌────────────────────────────┐
│ HTTP Request Node │
│ │
│ Method: GET/POST/PUT/DELETE│
│ URL: https://api.service.com/endpoint
│ Headers: Authorization, Content-Type
│ Body: JSON payload │
│ Authentication: API Key / OAuth / Bearer
│ │
│ → Returns JSON response │
└────────────────────────────┘
If a service has an API, you can connect n8n to it.
No built-in node required.
Anatomy of an API Call
The 5 Parts of Every API Request
| Part | What It Is | Example |
|---|---|---|
| Method | What action to perform | GET (read), POST (create), PUT (update), DELETE (remove) |
| URL | Where to send the request | https://api.example.com/v1/orders |
| Headers | Metadata about the request | Authorization: Bearer sk-abc123, Content-Type: application/json |
| Query Parameters | Filters added to URL | ?status=active&limit=50&page=2 |
| Body | Data you're sending | {"name": "Ahmed", "email": "ahmed@example.com"} |
Reading API Documentation
Every API has documentation. Here's how to read it fast:
SPEED-READ API DOCS (10 minutes)
1. Find "Authentication" section first
→ API Key? Bearer Token? OAuth? Basic Auth?
→ Where does the key go? Header? Query param?
2. Find the endpoint you need
→ Usually organized by resource: /orders, /customers, /products
→ Look for the HTTP method: GET /orders = list orders
3. Check required parameters
→ Which fields are required vs. optional?
→ What format? (string, integer, ISO date)
4. Look at the response example
→ What JSON structure comes back?
→ Where is the data you need? (often nested: response.data.items)
5. Check rate limits
→ How many calls per minute/hour?
→ What happens if you exceed? (429 error)
Building Custom Connectors — Step by Step
Connector 1: JazzCash Payment Verification
JazzCash has no n8n node. Build one:
USE CASE: Verify a JazzCash payment when a webhook hits
[Webhook: /verify-jazzcash-payment]
│
▼
[HTTP Request Node]
Method: POST
URL: https://sandbox.jazzcash.com.pk/ApplicationAPI/API/2.0/Purchase/DoMWalletTransaction
Headers:
Content-Type: application/json
Body (JSON):
{
"pp_Language": "EN",
"pp_MerchantID": "{{$env.JAZZCASH_MERCHANT_ID}}",
"pp_Password": "{{$env.JAZZCASH_PASSWORD}}",
"pp_TxnRefNo": "{{$json.transaction_ref}}",
"pp_Amount": "{{$json.amount}}",
"pp_TxnDateTime": "{{$now.format('YYYYMMDDHHmmss')}}",
"pp_SecureHash": "{{$json.computed_hash}}"
}
│
▼
[IF Node: Response code === "000" (success)]
│
├── YES → [Google Sheets: Log verified payment]
│ [Gmail: Send receipt to customer]
│
└── NO → [Gmail: Alert — payment verification failed]
[Google Sheets: Log failed attempt]
Connector 2: Daraz Seller Center — Order Sync
Daraz has a REST API but no n8n node:
[Schedule Trigger: Every 15 minutes]
│
▼
[HTTP Request: Get new orders]
Method: GET
URL: https://api.daraz.pk/rest/orders/get
Headers:
Authorization: Bearer {{$env.DARAZ_ACCESS_TOKEN}}
Query Parameters:
created_after: {{$now.minus(15, 'minutes').toISO()}}
status: pending
limit: 50
│
▼
[Split In Batches: Process each order]
│
▼
[Google Sheets: Append order row]
│
▼
[WATI: Send WhatsApp to customer]
│
▼
[Slack: Notify fulfillment team]
Connector 3: OpenAI / Gemini API (Custom AI Calls)
[Webhook: /ai-process]
│
▼
[HTTP Request: Call Gemini API]
Method: POST
URL: https://generativelanguage.googleapis.com/v1/models/gemini-2.5-flash:generateContent
Headers:
Content-Type: application/json
x-goog-api-key: {{$env.GEMINI_API_KEY}}
Body:
{
"contents": [{
"parts": [{
"text": "Summarize this customer feedback in 2 sentences: {{$json.feedback}}"
}]
}]
}
│
▼
[Set Node: Extract AI response]
summary = {{$json.candidates[0].content.parts[0].text}}
│
▼
[Google Sheets: Save feedback + AI summary]
Handling Authentication Patterns
Pattern 1: API Key in Header
HTTP Request Node:
Authentication: Generic Credential Type
Generic Auth Type: Header Auth
Header Auth:
Name: X-API-Key (or Authorization)
Value: your-api-key-here
OR use n8n Credentials:
Go to Credentials → Add → Header Auth
This stores the key securely and reuses across workflows
Pattern 2: Bearer Token
HTTP Request Node:
Authentication: Generic Credential Type
Generic Auth Type: Header Auth
Header:
Name: Authorization
Value: Bearer your-token-here
Pattern 3: OAuth 2.0 (For Google, Facebook, etc.)
n8n Credentials:
1. Go to Credentials → Add → OAuth2 API
2. Enter:
- Client ID: (from Google/Facebook developer console)
- Client Secret: (from developer console)
- Authorization URL: https://accounts.google.com/o/oauth2/auth
- Token URL: https://oauth2.googleapis.com/token
- Scope: https://www.googleapis.com/auth/spreadsheets
3. Click "Connect" → authorize in browser
4. Token auto-refreshes — n8n handles this
Pattern 4: HMAC Signature (JazzCash, some payment APIs)
// Function Node: Generate HMAC signature
const crypto = require('crypto');
const secret = $env.JAZZCASH_INTEGRITY_SALT;
const dataString = [
$json.pp_Amount,
$json.pp_DateTime,
$json.pp_MerchantID,
$json.pp_TxnRefNo
].sort().join('&');
const hmac = crypto.createHmac('sha256', secret);
hmac.update(dataString);
const hash = hmac.digest('hex');
return [{ json: { ...$json, pp_SecureHash: hash } }];
Pagination — Getting All Results
Most APIs return results in pages. Here's how to get everything:
Manual Pagination with Loop
[Set Node: Initialize]
page = 1
all_results = []
│
▼
[Loop: While has_more === true]
│
├──▶ [HTTP Request: GET /api/items?page={{page}}&limit=100]
│ │
│ ▼
│ [Merge: Add results to all_results]
│ │
│ ▼
│ [IF: response.length === 100]
│ │
│ ├── YES → page = page + 1 → [Loop back]
│ └── NO → has_more = false → [Exit loop]
│
▼
[Continue with all_results]
Cursor-Based Pagination
Some APIs use cursors instead of page numbers:
[HTTP Request: GET /api/items?cursor={{cursor}}&limit=100]
→ Response includes: { data: [...], next_cursor: "abc123" }
→ Use next_cursor for the next request
→ When next_cursor is null/empty → you've got everything
Error Handling for API Calls
Common HTTP Status Codes
| Code | Meaning | What to Do |
|---|---|---|
| 200 | Success | Process the response |
| 201 | Created | Resource was created successfully |
| 400 | Bad Request | Check your payload format |
| 401 | Unauthorized | API key is wrong or expired |
| 403 | Forbidden | You don't have permission |
| 404 | Not Found | Wrong URL or resource doesn't exist |
| 429 | Rate Limited | Wait and retry (see next lesson) |
| 500 | Server Error | Not your fault — retry later |
Retry Pattern for Flaky APIs
HTTP Request Node Settings:
→ On Error: Continue (don't stop workflow)
→ Retry On Fail: Yes
→ Max Retries: 3
→ Wait Between Retries: 2000ms (2 seconds)
This handles temporary failures (network blips, 500 errors)
without crashing your entire workflow.
Practice Lab
Task 1: Build a Weather API Connector Connect n8n to OpenWeatherMap (free API key). Create a workflow that fetches the current weather for Karachi, Lahore, and Islamabad every morning and posts a summary to a Google Sheet.
Task 2: AI-Powered Email Classifier Build a webhook that receives email text, sends it to Gemini API for classification (support / sales / spam), and routes it to different Google Sheets based on the classification.
Task 3: Multi-Page Data Fetch Connect to any paginated API (GitHub repos, or a mock API). Build a loop that fetches all pages and combines results into a single output. Handle the case where the API returns an error on page 3.
Pakistan Case Study
Meet Nadia — runs a small e-commerce operation on Daraz from Islamabad.
Her problem: Daraz has no n8n integration. She was manually checking the seller dashboard 6 times a day, copying order data to spreadsheets, and WhatsApp-messaging each customer confirmation by hand. 2-3 hours daily of repetitive work.
Her custom connector solution:
Built 3 workflows using HTTP Request nodes:
- Order Sync: Schedule Trigger (every 15 min) → Daraz API GET /orders → Google Sheets + WATI WhatsApp confirmation
- Inventory Alert: Schedule Trigger (daily 9 AM) → Daraz API GET /products → IF stock < 5 → Slack alert
- Review Monitor: Schedule Trigger (every 6 hours) → Daraz API GET /reviews → IF rating < 3 → Email alert for response
Challenges she faced:
- Daraz OAuth token expires every 7 days → built auto-refresh workflow
- API rate limit: 1,000 calls/hour → added delays between batch calls
- Occasional 500 errors from Daraz → added retry (3 attempts, 5-second wait)
Results:
- Manual Daraz work: 2-3 hours/day → 10 minutes/day (spot-checking)
- Customer WhatsApp confirmation: 1-4 hours delay → instant
- Missed low-stock alerts: 2-3/week → 0
- Negative review response time: 2-3 days → same day
- Time saved: ~60 hours/month
- Revenue impact: PKR 45,000/month (from fewer stockouts + faster customer response)
Key Takeaways
- The HTTP Request node connects n8n to ANY API — no built-in node needed
- Every API call has 5 parts: method, URL, headers, query params, body
- Speed-read API docs: find auth first, then endpoints, then required fields
- Pakistani services (JazzCash, Daraz, WATI) all work through custom HTTP connectors
- Handle authentication properly: API keys, Bearer tokens, OAuth 2.0, HMAC signatures
- Always implement pagination for list endpoints — don't assume one page is everything
- Add retry logic for flaky APIs (3 retries, 2-second wait)
- Store API credentials in n8n's Credential Manager, not hardcoded in workflows
Next lesson: Error handling patterns — making your workflows bulletproof with retry, fallback, and alert systems.
Lesson Summary
Quiz: Building Custom API Connectors in n8n
4 questions to test your understanding. Score 60% or higher to pass.