The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"name": "Airtable",
"type": "n8n-nodes-base.airtable",
"position": [
1650,
300
],
"parameters": {
"table": "Pokemon",
"operation": "list",
"additionalOptions": {}
},
"credentials": {
"airtableApi": "<your credential>"
},
"typeVersion": 1
},
{
"name": "Redis",
"type": "n8n-nodes-base.redis",
"position": [
600,
600
],
"parameters": {
"key": "={{$json[\"apiKey\"]}}",
"ttl": 3600,
"expire": true,
"operation": "incr"
},
"credentials": {
"redis": "<your credential>"
},
"typeVersion": 1
},
{
"name": "Redis1",
"type": "n8n-nodes-base.redis",
"position": [
1200,
450
],
"parameters": {
"key": "={{$json[\"apiKey\"]}}",
"operation": "incr"
},
"credentials": {
"redis": "<your credential>"
},
"typeVersion": 1
},
{
"name": "Set1",
"type": "n8n-nodes-base.set",
"position": [
1600,
550
],
"parameters": {
"values": {
"string": [
{
"name": "message",
"value": "You exceeded your limit"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Webhook1",
"type": "n8n-nodes-base.webhook",
"position": [
200,
600
],
"parameters": {
"path": "a3167ed7-98d2-422c-bfe2-e3ba599d19f1",
"options": {},
"responseMode": "lastNode",
"authentication": "headerAuth"
},
"credentials": {
"httpHeaderAuth": "<your credential>"
},
"typeVersion": 1
},
{
"name": "Function",
"type": "n8n-nodes-base.function",
"position": [
1900,
300
],
"parameters": {
"functionCode": " const limit = `Limit consumed: `+ $node['Redis1'].json[$node[\"Set2\"].json[\"apiKey\"]];\n return [\n {\n json: {\n message:limit,\n body: items.map(item => {\n const name= item.json.fields.name\n const url= item.json.fields.url\n return {name,url}\n })\n }\n }\n]\n"
},
"typeVersion": 1
},
{
"name": "Set",
"type": "n8n-nodes-base.set",
"position": [
400,
600
],
"parameters": {
"values": {
"string": [
{
"name": "apiKey",
"value": "={{$json[\"headers\"][\"x-api-key\"] +'-'+ new Date().getHours() +'-'+ new Date().getMinutes()}}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Set2",
"type": "n8n-nodes-base.set",
"position": [
1000,
450
],
"parameters": {
"values": {
"string": [
{
"name": "apiKey",
"value": "={{$node['Webhook1'].json[\"headers\"][\"x-api-key\"] +'-'+ new Date().getHours()}}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Set3",
"type": "n8n-nodes-base.set",
"position": [
1000,
700
],
"parameters": {
"values": {
"string": [
{
"name": "message",
"value": "You exceeded your limit"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"name": "Per hour",
"type": "n8n-nodes-base.if",
"position": [
1400,
450
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{$json[$node[\"Set2\"].json[\"apiKey\"]]}}",
"value2": 60
}
],
"string": []
}
},
"typeVersion": 1
},
{
"name": "Per minute",
"type": "n8n-nodes-base.if",
"position": [
800,
600
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{$json[$node[\"Set\"].json[\"apiKey\"]]}}",
"value2": 10,
"operation": "smallerEqual"
}
]
}
},
"typeVersion": 1
}
],
"connections": {
"Set": {
"main": [
[
{
"node": "Redis",
"type": "main",
"index": 0
}
]
]
},
"Set2": {
"main": [
[
{
"node": "Redis1",
"type": "main",
"index": 0
}
]
]
},
"Redis": {
"main": [
[
{
"node": "Per minute",
"type": "main",
"index": 0
}
]
]
},
"Redis1": {
"main": [
[
{
"node": "Per hour",
"type": "main",
"index": 0
}
]
]
},
"Airtable": {
"main": [
[
{
"node": "Function",
"type": "main",
"index": 0
}
]
]
},
"Per hour": {
"main": [
[
{
"node": "Airtable",
"type": "main",
"index": 0
}
],
[
{
"node": "Set1",
"type": "main",
"index": 0
}
]
]
},
"Webhook1": {
"main": [
[
{
"node": "Set",
"type": "main",
"index": 0
}
]
]
},
"Per minute": {
"main": [
[
{
"node": "Set2",
"type": "main",
"index": 0
}
],
[
{
"node": "Set3",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
airtableApihttpHeaderAuthredis
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow enables you to enforce rate limiting on your low-code API endpoints, preventing overload and ensuring fair usage by tracking request volumes in real time. It's ideal for developers or teams building scalable automations with tools like Airtable, where you need to cap API calls without complex custom coding. The key step involves the webhook trigger receiving incoming requests, followed by Redis operations to check and update counters, seamlessly integrating with Airtable to log or validate data.
Use this when your API handles variable traffic from users or integrations, such as syncing data to Airtable, to avoid hitting external service limits or server strain. Avoid it for low-traffic scenarios where built-in throttling suffices, or if you require advanced analytics beyond basic counters. Common variations include adding email alerts via another node for threshold breaches, or adapting for different storage like PostgreSQL instead of Redis.
About this workflow
Use Redis To Rate Limit Your Low Code Api. Uses airtable, redis. Webhook trigger; 11 nodes.
Source: https://github.com/Zie619/n8n-workflows — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Webhook Code. Uses itemLists, respondToWebhook, stickyNote, googleCalendar. Webhook trigger; 92 nodes.
TEMPLATE - Multi Methods API Endpoint. Uses respondToWebhook, stickyNote, airtable. Webhook trigger; 18 nodes.
Webhook Respondtowebhook. Uses respondToWebhook, executeWorkflow, airtable, crypto. Webhook trigger; 16 nodes.
Amazon keywords. Uses airtable, httpRequest, splitOut, stickyNote. Webhook trigger; 12 nodes.
Luma AI - Webhook Response v1 - AK. Uses executionData, stickyNote, airtable. Webhook trigger; 8 nodes.