This workflow follows the HTTP Request → Stopanderror recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "IYgbtNpyB4E6Jbxo",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "2. Refresh Pipedrive tokens",
"tags": [],
"nodes": [
{
"id": "2b66edcd-c71a-4dac-971f-deb1b09ef85b",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"position": [
1460,
-80
],
"parameters": {
"errorMessage": "Token refresh failed"
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "b48d6760-766e-4b39-be35-89de7dc3ab5e",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
60,
-300
],
"parameters": {
"color": 5,
"width": 872,
"height": 97,
"content": "## Step 2:\nCreate a workflow to refresh your access token when the access token requires a refresh."
},
"typeVersion": 1
},
{
"id": "6119eef3-9ffa-45a1-b238-412738e7529e",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
280,
-80
],
"parameters": {
"height": 211,
"content": "\n\n\n\n\n\n\n\nPost unique data to identify your row in Database and be able to fetch the existing access and refresh token"
},
"typeVersion": 1
},
{
"id": "2d76be21-95e1-4747-b761-126b133e8264",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
980,
-220
],
"parameters": {
"content": "## Get token from pipedrive"
},
"typeVersion": 1
},
{
"id": "9a44eb63-9d31-4b24-9171-1f9a828a5c52",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
100,
-740
],
"parameters": {
"color": 5,
"width": 995,
"height": 82,
"content": "## Step 1:\nSave Refresh token and Access token to DB when authenticated by user and installed. "
},
"typeVersion": 1
},
{
"id": "f3247e6a-7c1c-4479-9f83-f3bc4146f254",
"name": "Insert",
"type": "n8n-nodes-base.supabase",
"position": [
1600,
-660
],
"parameters": {
"tableId": "App_tok",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "ref_token",
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"refresh_token\"] }}"
},
{
"fieldId": "acc_token",
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"access_token\"] }}"
},
{
"fieldId": "Platform",
"fieldValue": "Pipedrive"
},
{
"fieldId": "created_at",
"fieldValue": "={{$now.toUTC().toString()}}"
},
{
"fieldId": "updated_at",
"fieldValue": "={{$now.toUTC().toString()}}"
}
]
}
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "f7ad45d0-7055-45f4-9971-031ffebfdbda",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
500,
-640
],
"parameters": {
"content": "You can also use SET NODE + tobase64 function as done in step 2"
},
"typeVersion": 1
},
{
"id": "e14e2dac-e84b-475f-a01b-14bb723eedc8",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
100,
200
],
"parameters": {
"color": 5,
"width": 1644,
"height": 80,
"content": "## Step 3:\nMake an actual API call. In this example, we are using search person API. Please refer to Pipedrive API documentation for your specific use case. "
},
"typeVersion": 1
},
{
"id": "b450c928-e0e4-4f49-829e-03b61828d4d9",
"name": "Get Pipedrive Token",
"type": "n8n-nodes-base.supabase",
"position": [
600,
660
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "Platform",
"keyValue": "Pipedrive"
},
{
"keyName": "AppId",
"keyValue": "57db0bab2932f657"
}
]
},
"tableId": "App_tok",
"operation": "get"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "f92a957a-d0ef-4037-8657-74e7fe74fe6d",
"name": "Get contact from Pipedrive",
"type": "n8n-nodes-base.httpRequest",
"position": [
900,
660
],
"parameters": {
"url": "=https://priyajain-sandbox.pipedrive.com/api/v2/persons/search?fields=email&term={{ $node[\"Receive request\"].json[\"body\"][\"person\"][\"email\"] }}",
"options": {
"response": {
"response": {
"fullResponse": true
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Authorization",
"value": "=Bearer {{ $node[\"Get Pipedrive Token\"].json[\"acc_token\"] }}"
}
]
}
},
"typeVersion": 4,
"continueOnFail": true,
"alwaysOutputData": false
},
{
"id": "bff21156-3da0-4cf3-b3de-c24d8abe7577",
"name": "Access Token Invalid",
"type": "n8n-nodes-base.if",
"position": [
1160,
700
],
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json[\"error\"][\"message\"].includes(\"Invalid token: access token is invalid\") }}",
"value2": "={{ true }}"
}
]
},
"combineOperation": "any"
},
"typeVersion": 1
},
{
"id": "9fd832b1-2af9-48c2-9d57-86a9f34bdd78",
"name": "Success",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1440,
720
],
"parameters": {
"options": {
"responseCode": 200
},
"respondWith": "json",
"responseBody": "={{ $node[\"Get contact from Pipedrive\"].json[\"body\"][\"data\"][\"items\"][\"0\"][\"item\"][\"name\"] }}"
},
"typeVersion": 1
},
{
"id": "daf33b32-ff7b-4d7e-8fd0-d54dfaddf405",
"name": "Refresh Access Token",
"type": "n8n-nodes-base.httpRequest",
"position": [
1360,
320
],
"parameters": {
"url": "http://localhost:5678/webhook/937a8843-a28a-400a-b473-bdc598366fa0",
"method": "POST",
"options": {},
"jsonBody": "{\n\n \"appId\":\"57db0bab2932f657\"\n\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "6759a890-6c2a-4bb1-aae9-9b8723b9e143",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
580,
420
],
"parameters": {
"width": 668,
"content": "## Loop back to fecth the refreshed Access Token\n### Note:\nYou can add further conditions and use Switch statemen tinstead of IF to validate API response based on your use case."
},
"typeVersion": 1
},
{
"id": "d975ce9f-2ef2-46b1-9d30-4f6e06e19b7e",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
120,
-960
],
"parameters": {
"width": 1413,
"content": "## 1. This workflow helps you create your own Oauth 2.0 token refresh system. It helps you have better control of your oauth 2.0 auth process.\n## 2. I am using Pipedrive API here. However, you can re-use this for other similar applications. "
},
"typeVersion": 1
},
{
"id": "40d59a94-563d-459c-91d0-4206c2a19704",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
180,
580
],
"parameters": {
"height": 248,
"content": "A 3rd partyapplication posting the request to the webhook"
},
"typeVersion": 1
},
{
"id": "03945766-570c-47db-82c6-2c973e45106d",
"name": "convert clientId and secret to base64",
"type": "n8n-nodes-base.code",
"position": [
560,
-560
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nconst client_id = \"57db0bab2932f657\";\nconst client_secret = \"edfaba095e9e7ddefe2e960ce2e98345230a016d\";\n\n// Combine client_id and client_secret with a colon\nconst combinedString = client_id+\":\"+client_secret;\n\n// Encode the combined string in Base64\nconst encodedString = Buffer.from(combinedString).toString('base64');\n\n// Create the Authorization header value\nconst authorizationHeader = `Basic ${encodedString}`;\n\nreturn {\"authheader\":authorizationHeader};"
},
"typeVersion": 2
},
{
"id": "8ca6eb93-6994-4536-b61e-d884c8515929",
"name": "Generate Refresh Token from authcode",
"type": "n8n-nodes-base.httpRequest",
"maxTries": 2,
"position": [
820,
-560
],
"parameters": {
"url": "https://oauth.pipedrive.com/oauth/token",
"method": "POST",
"options": {
"response": {
"response": {
"fullResponse": true
}
}
},
"sendBody": true,
"contentType": "form-urlencoded",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "grant_type",
"value": "authorization_code"
},
{
"name": "code",
"value": "={{$node[\"catch Auth code\"].json[\"query\"][\"code\"]}}"
},
{
"name": "redirect_uri",
"value": "={{ $node[\"catch Auth code\"].json[\"webhookUrl\"] }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "={{$node[\"convert clientId and secret to base64\"].json[\"authheader\"]}}"
}
]
}
},
"retryOnFail": false,
"typeVersion": 4,
"alwaysOutputData": false
},
{
"id": "9c1b22e1-fd50-4c70-91cf-f4ea8cc7d3ac",
"name": "Look for the related record in Supabase",
"type": "n8n-nodes-base.supabase",
"position": [
1060,
-540
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "Platform",
"keyValue": "Pipedrive"
}
]
},
"tableId": "App_tok",
"operation": "get"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "53602a58-d47a-4133-b9ec-4ea421a75eea",
"name": "IF rec not found",
"type": "n8n-nodes-base.if",
"position": [
1260,
-540
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{ $json.values().length }}",
"operation": "equal"
}
]
}
},
"typeVersion": 1
},
{
"id": "38e5d91c-1bea-4f7a-8336-98748005d02e",
"name": "Update tokns in the record",
"type": "n8n-nodes-base.supabase",
"position": [
1600,
-460
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "Platform",
"keyValue": "Pipedrive",
"condition": "eq"
}
]
},
"tableId": "App_tok",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "acc_token",
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"access_token\"] }}"
},
{
"fieldId": "ref_token",
"fieldValue": "={{ $node[\"Generate Refresh Token from authcode\"].json[\"body\"][\"refresh_token\"] }}"
},
{
"fieldId": "updated_at",
"fieldValue": "={{$now.toUTC().toString()}}"
}
]
},
"matchType": "allFilters",
"operation": "update"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "43a2613d-7793-48c9-8934-57d9b713f5fe",
"name": "Supabase- look for the record",
"type": "n8n-nodes-base.supabase",
"position": [
600,
-140
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "Platform",
"keyValue": "Pipedrive"
},
{
"keyName": "AppId",
"keyValue": "={{ $node[\"Webhook\"].json[\"body\"][\"appId\"] }}"
}
]
},
"tableId": "App_tok",
"operation": "get"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "366bd343-419c-4a77-b2ce-e6124a6cc291",
"name": "combine client id and secret",
"type": "n8n-nodes-base.set",
"position": [
840,
-140
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "4330b857-6184-4ad8-82dc-a8b806ab8077",
"name": "authheader",
"type": "string",
"value": "57db0bab2932f657:edfaba095e9e7ddefe2e960ce2e98345230a016d"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "156acb8f-3a23-40ec-b011-9db8bfa6d98b",
"name": "Get Pipedrive acess token",
"type": "n8n-nodes-base.httpRequest",
"position": [
1060,
-140
],
"parameters": {
"url": "https://oauth.pipedrive.com/oauth/token",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "grant_type",
"value": "refresh_token"
},
{
"name": "refresh_token",
"value": "={{ $node[\"Supabase- look for the record\"].json[\"ref_token\"] }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Basic {{ $json[\"authheader\"].base64Encode() }}"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "3e20309e-6d50-444c-b9e1-cf6d6982e546",
"name": "IF success",
"type": "n8n-nodes-base.if",
"position": [
1240,
-140
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ Object.keys($input.first().json)[0]}}",
"value2": "access_token"
}
]
}
},
"typeVersion": 1
},
{
"id": "1e991aa7-9888-404d-8f80-bb6ce0a3b777",
"name": "Update thr row with new access token",
"type": "n8n-nodes-base.supabase",
"position": [
1420,
-280
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "Platform",
"keyValue": "Pipedrive",
"condition": "eq"
}
]
},
"tableId": "App_tok",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "acc_token",
"fieldValue": "={{ $node[\"Get Pipedrive acess token\"].json[\"access_token\"] }}"
},
{
"fieldId": "ref_token",
"fieldValue": "={{ $node[\"Get Pipedrive acess token\"].json[\"refresh_token\"] }}"
}
]
},
"matchType": "allFilters",
"operation": "update"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "d0989bad-9176-44a2-86ce-db07a5e8a34c",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
340,
-140
],
"parameters": {
"path": "937a8843-a28a-400a-b473-bdc598366fa0",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode",
"authentication": "basicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "108a2ea1-de2a-4df3-9d9f-0ce1b27a52e9",
"name": "Receive request",
"type": "n8n-nodes-base.webhook",
"position": [
280,
680
],
"parameters": {
"path": "47704458-bfa6-4d95-adf1-97fc78e35d8a",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode",
"authentication": "basicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "f983cfd1-52db-4839-88af-6386ec7c7256",
"name": "catch Auth code",
"type": "n8n-nodes-base.webhook",
"position": [
300,
-560
],
"parameters": {
"path": "aae545fb-a69d-4e20-91ce-65f105d0ea2f",
"options": {}
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1",
"saveManualExecutions": true
},
"versionId": "54499ed8-4677-400a-9e03-d0d84f8a97b5",
"connections": {
"Webhook": {
"main": [
[
{
"node": "Supabase- look for the record",
"type": "main",
"index": 0
}
]
]
},
"IF success": {
"main": [
[
{
"node": "Update thr row with new access token",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
]
]
},
"Receive request": {
"main": [
[
{
"node": "Get Pipedrive Token",
"type": "main",
"index": 0
}
]
]
},
"catch Auth code": {
"main": [
[
{
"node": "convert clientId and secret to base64",
"type": "main",
"index": 0
}
]
]
},
"IF rec not found": {
"main": [
[
{
"node": "Insert",
"type": "main",
"index": 0
}
],
[
{
"node": "Update tokns in the record",
"type": "main",
"index": 0
}
]
]
},
"Get Pipedrive Token": {
"main": [
[
{
"node": "Get contact from Pipedrive",
"type": "main",
"index": 0
}
]
]
},
"Access Token Invalid": {
"main": [
[
{
"node": "Refresh Access Token",
"type": "main",
"index": 0
}
],
[
{
"node": "Success",
"type": "main",
"index": 0
}
]
]
},
"Refresh Access Token": {
"main": [
[
{
"node": "Get Pipedrive Token",
"type": "main",
"index": 0
}
]
]
},
"Get Pipedrive acess token": {
"main": [
[
{
"node": "IF success",
"type": "main",
"index": 0
}
]
]
},
"Get contact from Pipedrive": {
"main": [
[
{
"node": "Access Token Invalid",
"type": "main",
"index": 0
}
]
]
},
"combine client id and secret": {
"main": [
[
{
"node": "Get Pipedrive acess token",
"type": "main",
"index": 0
}
]
]
},
"Supabase- look for the record": {
"main": [
[
{
"node": "combine client id and secret",
"type": "main",
"index": 0
}
]
]
},
"Generate Refresh Token from authcode": {
"main": [
[
{
"node": "Look for the related record in Supabase",
"type": "main",
"index": 0
}
]
]
},
"convert clientId and secret to base64": {
"main": [
[
{
"node": "Generate Refresh Token from authcode",
"type": "main",
"index": 0
}
]
]
},
"Look for the related record in Supabase": {
"main": [
[
{
"node": "IF rec not found",
"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.
httpBasicAuthsupabaseApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow ensures seamless access to Pipedrive data by automatically refreshing expired authentication tokens, preventing disruptions in your sales automation pipelines. It's ideal for teams relying on Pipedrive for CRM operations who need reliable API connectivity without manual intervention. The key step involves an HTTP request to Pipedrive's endpoint to fetch new tokens, which are then securely stored in Supabase for future use, maintaining uninterrupted data flow across your integrations.
Use this workflow when building scheduled automations or webhooks that interact frequently with Pipedrive, such as lead syncing or reporting, to avoid token expiry errors. Avoid it for one-off tasks or if your setup uses OAuth flows handled directly by Pipedrive apps. Common variations include adding email notifications on refresh failures or integrating with other CRMs like HubSpot for multi-platform token management.
About this workflow
2. Refresh Pipedrive tokens. Uses stopAndError, stickyNote, supabase, httpRequest. Webhook trigger; 29 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.
This workflow provides an OAuth 2.0 auth token refresh process for better control. Developers can utilize it as an alternative to n8n's built-in OAuth flow to achieve improved control and visibility.
This solution enables you to manage all your Notion and Todoist tasks from different workspaces as well as your calendar events in a single place. This is 2 way sync with partial support for recurring
Notion to Clockify Sync Template. Uses scheduleTrigger, clockify, compareDatasets, stopAndError. Webhook trigger; 68 nodes.
This workflow synchronizes three entities from Notion to Clockify, allowing tracked time to be linked to client-related projects or tasks.
Ai Assistant Workflow. Uses supabase, httpRequest, emailSend. Webhook trigger; 14 nodes.