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 →
{
"name": "TestMultiCredentials",
"nodes": [
{
"parameters": {
"path": "/:cred_id",
"responseMode": "lastNode",
"responseData": "allEntries",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-192,
400
],
"id": "e2926465-d94a-4748-97e6-06da5bc0f06c",
"name": "GetCredData"
},
{
"parameters": {
"path": "de1286ac-8741-4e3f-bd00-3ba6f83b082e",
"responseMode": "responseNode",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-944,
-32
],
"id": "3c4b098b-1cbc-4646-ba35-179e0c305c22",
"name": "Webhook"
},
{
"parameters": {
"respondWith": "text",
"responseBody": "={{ $json.html }}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.4,
"position": [
1248,
-32
],
"id": "ca480288-e1e4-4ba3-b219-acf62dc360b8",
"name": "Respond to Webhook"
},
{
"parameters": {
"command": "n8n export:credentials --all 2>/dev/null"
},
"id": "474a5f8b-4a61-4263-a401-9194f83d0802",
"name": "Fetch Credentials",
"type": "n8n-nodes-base.executeCommand",
"position": [
-592,
-32
],
"typeVersion": 1
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "e15bd45f-200a-4f3e-bbf0-396e33eaf7cd",
"name": "creds",
"value": "={{ $jmespath(JSON.parse($json.stdout.match(/(\\[.*\\])/s)[1]), \"[?type=='openRouterApi'].{id: id, name: name, type: type}\") }}",
"type": "array"
},
{
"id": "fbd14066-89f3-450e-9621-5aabb5935f7f",
"name": "htmlpage",
"value": "multicred-test.html",
"type": "string"
},
{
"id": "87126bb7-9243-40e8-a758-b72eb14fb95a",
"name": "webhookurl",
"value": "=<REPLACE ME>/:cred_id",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
64,
-32
],
"id": "c49c211b-6268-412a-9719-131089c5dffd",
"name": "Extract OpenRouter Creds"
},
{
"parameters": {
"workflowId": {
"__rl": true,
"value": "MrIKoecwI5PpGDTz",
"mode": "list",
"cachedResultName": "GetPage"
},
"workflowInputs": {
"mappingMode": "defineBelow",
"value": {
"htmlpage": "={{ $json.htmlpage }}"
},
"matchingColumns": [],
"schema": [
{
"id": "htmlpage",
"displayName": "htmlpage",
"required": false,
"defaultMatch": false,
"display": true,
"canBeUsedToMatch": true,
"type": "string",
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": true
},
"options": {}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
560,
-32
],
"id": "fc2a38bc-aea1-4e32-b1a3-6076ae6c550a",
"name": "Prepare HTML",
"disabled": true
},
{
"parameters": {
"source": "parameter",
"workflowJson": "={\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.manualTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n -576,\n 160\n ],\n \"id\": \"5b0195f5-9bfb-4a1a-aeb8-ad28f8456fbd\",\n \"name\": \"When clicking \u2018Execute workflow\u2019\"\n },\n {\n \"parameters\": {\n \"url\": \"https://openrouter.ai/api/v1/key\",\n \"authentication\": \"predefinedCredentialType\",\n \"nodeCredentialType\": \"openRouterApi\",\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.httpRequest\",\n \"typeVersion\": 4.2,\n \"position\": [\n -304,\n 160\n ],\n \"id\": \"86d16fed-37eb-4138-9908-cb55ee2e7b2d\",\n \"name\": \"HTTP Request\",\n \"credentials\": {\n \"openRouterApi\": {\n \"id\": \"{{ $json.params.cred_id }}\"\n }\n }\n }\n ],\n \"connections\": {\n \"When clicking \u2018Execute workflow\u2019\": {\n \"main\": [\n [\n {\n \"node\": \"HTTP Request\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"pinData\": {},\n \"meta\": {\n \"templateCredsSetupCompleted\": true,\n \"instanceId\": \"fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a\"\n }\n}",
"options": {
"waitForSubWorkflow": true
}
},
"type": "n8n-nodes-base.executeWorkflow",
"typeVersion": 1.2,
"position": [
240,
400
],
"id": "f30b3047-f870-4564-a9c2-6c4cca0274aa",
"name": "Run sub-workflow as JSON"
},
{
"parameters": {
"content": "## Export all credentials (encrypted)",
"height": 272,
"width": 352
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-128
],
"typeVersion": 1,
"id": "5b52daf2-1306-4df1-a470-410c0c1e2427",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## Filter by cred type, i.e. `openRouterApi`\n## Extract cred `name` and `id`\n\n# \u26a0\ufe0f Replace webhook `GetCredData` webhook url\n## i.e. https://your.cool-domain.com/webhook/very-secret-uuid/:cred_id",
"height": 512,
"width": 592
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-144,
-368
],
"typeVersion": 1,
"id": "3d7fd87b-e7db-48ea-ae8c-c7e13348f602",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "## Deactivated part of another project with vibe-coding frontentds directly in n8n.\n\nReplaced the full HTML content instead of dynamic page loading from a file",
"height": 352,
"width": 640
},
"type": "n8n-nodes-base.stickyNote",
"position": [
512,
-208
],
"typeVersion": 1,
"id": "083f71b3-4413-4d0f-ae2b-9019cfec6b6c",
"name": "Sticky Note2"
},
{
"parameters": {
"html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Test Credentials</title>\n <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN\" crossorigin=\"anonymous\">\n</head>\n<body>\n <div class=\"container mt-5\">\n <div class=\"card shadow-sm\" style=\"max-width: 500px; margin: auto;\">\n <div class=\"card-header\">\n <h4>Test Credentials</h4>\n </div>\n <div class=\"card-body\">\n <div class=\"mb-3\">\n <label for=\"credsSelect\" class=\"form-label\">Select a credential to test:</label>\n <select class=\"form-select\" id=\"credsSelect\">\n <option value=\"\" selected disabled>-- Please choose an option --</option>\n </select>\n </div>\n <button class=\"btn btn-primary mb-3\" id=\"testButton\">Test</button>\n <div id=\"status\"></div>\n </div>\n </div>\n </div>\n\n <script>\n const data = {{ JSON.stringify($json.data) }};\n \n const creds = data.creds;\n const webhookUrlTemplate = data.webhookurl;\n\n const credsSelect = document.getElementById('credsSelect');\n const testButton = document.getElementById('testButton');\n const statusDiv = document.getElementById('status');\n\n creds.forEach(cred => {\n const option = document.createElement('option');\n option.value = cred.id;\n option.textContent = cred.name;\n credsSelect.appendChild(option);\n });\n\n testButton.addEventListener('click', () => {\n const selectedCredId = credsSelect.value;\n if (!selectedCredId) {\n statusDiv.textContent = 'Please select a credential.';\n statusDiv.className = 'alert alert-warning p-2';\n return;\n }\n\n const webhookUrl = webhookUrlTemplate.replace(':cred_id', selectedCredId);\n \n statusDiv.textContent = `Sending test signal...`;\n statusDiv.className = 'alert alert-info p-2';\n\n fetch(webhookUrl)\n .then(response => {\n if (!response.ok) {\n throw new Error(`HTTP error! Status: ${response.status}`);\n }\n return response.json();\n })\n .then(responseData => {\n const keyData = responseData[0].data;\n statusDiv.className = 'alert alert-success p-2';\n statusDiv.innerHTML = `\n <strong>Test successful! Key details:</strong>\n <ul class=\"list-unstyled mb-0 mt-2\">\n <li><strong>Label:</strong> ${keyData.label}</li>\n <li><strong>Usage:</strong> ${keyData.usage}</li>\n <li><strong>Limit:</strong> ${keyData.limit === null ? 'Not set' : keyData.limit}</li>\n <li><strong>Provisional:</strong> ${keyData.is_provisioning_key}</li>\n </ul>\n `;\n })\n .catch(error => {\n console.error('Fetch error:', error);\n statusDiv.textContent = `Error: ${error.message}`;\n statusDiv.className = 'alert alert-danger p-2';\n });\n });\n </script>\n</body>\n</html>\n"
},
"type": "n8n-nodes-base.html",
"typeVersion": 1.2,
"position": [
960,
-32
],
"id": "1fba7ff2-2012-4a6b-82ae-07ba3350cee0",
"name": "HTML"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "590d8c26-fe38-4fec-a47f-98fe685c6381",
"name": "data",
"value": "={{ $json }}",
"type": "object"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
800,
-32
],
"id": "cb4a70d0-4e79-4011-8a90-e5875647960a",
"name": "Edit Fields"
},
{
"parameters": {
"content": "## Subworkflow consists of 2 nodes: manual trigger + HTTP Request to OpenRouter (ket api key info)\n\n## Credential id is passed from the frontend on the button click and dynamically passed as expression",
"height": 384,
"width": 608
},
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
192
],
"typeVersion": 1,
"id": "0d8bbffe-39d6-40f0-9b88-f46f3042abd1",
"name": "Sticky Note3"
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Fetch Credentials",
"type": "main",
"index": 0
}
]
]
},
"GetCredData": {
"main": [
[
{
"node": "Run sub-workflow as JSON",
"type": "main",
"index": 0
}
]
]
},
"Fetch Credentials": {
"main": [
[
{
"node": "Extract OpenRouter Creds",
"type": "main",
"index": 0
}
]
]
},
"Extract OpenRouter Creds": {
"main": [
[
{
"node": "Prepare HTML",
"type": "main",
"index": 0
}
]
]
},
"Prepare HTML": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"HTML": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "HTML",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "65c534fe-36b7-48d7-87b4-71825fe1b4df",
"id": "nQpMlP4tzg43lvUf",
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
TestMultiCredentials. Uses executeCommand. Webhook trigger; 13 nodes.
Source: https://gist.github.com/ed-parsadanyan/85da15c58c2a4c8448d2f44a0af27ce9 — 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.
PDF Processing via Shell. Uses executeCommand. Webhook trigger; 3 nodes.
Clara Pipeline B - Onboarding Update. Uses executeCommand. Webhook trigger; 3 nodes.
Clara Automation Pipeline – Run All. Uses executeCommand. Webhook trigger; 2 nodes.
Complete backup solution that saves both workflows and credentials to local/server disk with optional FTP upload for off-site redundancy.
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.