This workflow follows the GitHub → HTTP Request 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": "k22TSNIZXHaQ9rGr",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Clockify Backup Template",
"tags": [
{
"id": "RKga6I6NviNI12bx",
"name": "template",
"createdAt": "2024-09-19T19:09:21.997Z",
"updatedAt": "2024-09-19T19:09:21.997Z"
}
],
"nodes": [
{
"id": "24115363-9a03-4f8a-aa6e-2a9d4247f035",
"name": "Extract from File",
"type": "n8n-nodes-base.extractFromFile",
"position": [
660,
400
],
"parameters": {
"options": {},
"operation": "fromJson"
},
"typeVersion": 1
},
{
"id": "11aa4b51-98f9-4df8-b2d2-6757fe686894",
"name": "Compare Datasets",
"type": "n8n-nodes-base.compareDatasets",
"position": [
880,
280
],
"parameters": {
"options": {},
"mergeByFields": {
"values": [
{
"field1": "data",
"field2": "data"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "831ad368-6a46-4dd4-bb6c-8ea46200cdf0",
"name": "Stop and Error",
"type": "n8n-nodes-base.stopAndError",
"position": [
880,
700
],
"parameters": {
"errorMessage": "={{ $json.error }}"
},
"typeVersion": 1
},
{
"id": "2f838fc8-96bf-4111-aaba-743e0c88b688",
"name": "Globals",
"type": "n8n-nodes-base.set",
"position": [
-660,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "6bd5904d-0218-4075-a767-d4b659def9b0",
"name": "workspace_id",
"type": "string",
"value": "={{ $json.id }}"
},
{
"id": "63fa6231-6c5b-414f-b813-18f7dd5c33e9",
"name": "github_repo.owner",
"type": "string",
"value": ""
},
{
"id": "be2530d7-b2b5-41c5-af19-ab8d27f18e2e",
"name": "github_repo.name",
"type": "string",
"value": ""
}
]
}
},
"typeVersion": 3.4
},
{
"id": "bea9590e-355e-410a-bc4b-ae777efb9f15",
"name": "Set month indexes",
"type": "n8n-nodes-base.set",
"position": [
-440,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ad278249-5320-4ffa-8d75-e47194c83e58",
"name": "monthIndex",
"type": "array",
"value": "=[0, 1, 2]"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f541d535-80d9-439d-8543-9c3cb156a5ff",
"name": "Split Out indexes",
"type": "n8n-nodes-base.splitOut",
"position": [
-220,
480
],
"parameters": {
"options": {},
"fieldToSplitOut": "monthIndex"
},
"typeVersion": 1
},
{
"id": "76c74727-d338-4a61-9bf2-e97893721995",
"name": "Set intervals",
"type": "n8n-nodes-base.set",
"position": [
0,
480
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7f5ff2ee-b93c-4121-b3dc-ce592513db88",
"name": "reportName",
"type": "string",
"value": "=detailed_report_{{ $now.minus($json.monthIndex, 'month').format('yyyy-MM') }}"
},
{
"id": "ea571bdb-8f51-4852-9fda-55ff1a929d1f",
"name": "startDate",
"type": "string",
"value": "={{ $now.minus($json.monthIndex, 'month').startOf('month').format('yyyy-MM-dd') }}"
},
{
"id": "e88726c4-1eb8-4f29-9805-7b0a5ee484a4",
"name": "endDate",
"type": "string",
"value": "={{ $now.minus($json.monthIndex, 'month').endOf('month').format('yyyy-MM-dd') }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6d5e917e-68ac-4dbd-98be-4c8ad97fa54a",
"name": "Skip empty reports",
"type": "n8n-nodes-base.filter",
"position": [
880,
500
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "f6c69f9b-9e78-4a1e-af33-a1197f35e970",
"operator": {
"type": "array",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{ $json.timeentries }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.2
},
{
"id": "60c7a408-74d3-4c6c-ac78-1ed1071e873e",
"name": "Get first workspace",
"type": "n8n-nodes-base.clockify",
"position": [
-880,
480
],
"parameters": {
"limit": 1,
"resource": "workspace"
},
"credentials": {
"clockifyApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "824bf2c6-9159-40ec-83f3-3f0b8d87c208",
"name": "Get detailed monthly report",
"type": "n8n-nodes-base.httpRequest",
"position": [
220,
480
],
"parameters": {
"url": "=https://reports.api.clockify.me/v1/workspaces/{{ $('Globals').item.json.workspace_id }}/reports/detailed",
"method": "POST",
"options": {},
"jsonBody": "={\n \"dateRangeStart\": \"{{ $json.startDate }}T00:00:00Z\",\n \"dateRangeEnd\": \"{{ $json.endDate }}T23:59:59.999Z\",\n \"detailedFilter\": {\n \"page\": 1,\n \"pageSize\": 50\n },\n \"exportType\": \"json\"\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "clockifyApi"
},
"credentials": {
"clockifyApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "f9323c68-c70f-4f22-ae18-916d5fc1b264",
"name": "Check if file exists in GitHub",
"type": "n8n-nodes-base.github",
"onError": "continueErrorOutput",
"position": [
440,
480
],
"parameters": {
"owner": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.owner }}"
},
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
"resource": "file",
"operation": "get",
"repository": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.name }}"
},
"additionalParameters": {}
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"retryOnFail": false,
"typeVersion": 1
},
{
"id": "41877a6a-ba5b-43bd-8ca3-f8402793685f",
"name": "Point to new data",
"type": "n8n-nodes-base.set",
"position": [
660,
200
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "00d2885f-451e-436e-8852-b9ad086d231b",
"name": "data",
"type": "array",
"value": "={{ $('Get detailed monthly report').item.json.timeentries }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "9f448921-5b9d-4937-a7d9-00a62b1fba99",
"name": "Check for 404 error message",
"type": "n8n-nodes-base.if",
"position": [
660,
600
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6b34c09d-0136-433c-856d-b29a0c3aac34",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.error }}",
"rightValue": "could not be found"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "900905ed-cff6-4ebb-b0da-67db9f02b301",
"name": "Update file in GitHub",
"type": "n8n-nodes-base.github",
"position": [
1100,
180
],
"parameters": {
"owner": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.owner }}"
},
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
"resource": "file",
"operation": "edit",
"repository": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.name }}"
},
"fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
"commitMessage": "Update report"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "b928cdb2-b21a-45ff-9bc6-9be483891c4c",
"name": "Create file in GitHub",
"type": "n8n-nodes-base.github",
"position": [
1100,
500
],
"parameters": {
"owner": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.owner }}"
},
"filePath": "=reports/{{ $('Set intervals').item.json.reportName }}",
"resource": "file",
"repository": {
"__rl": true,
"mode": "name",
"value": "={{ $('Globals').first().json.github_repo.name }}"
},
"fileContent": "={{ JSON.stringify($json.timeentries, null, 2) }}",
"commitMessage": "Create report"
},
"credentials": {
"githubApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "04a5b42d-ea1f-4b32-98b5-953e22b26819",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1100,
480
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 5
}
]
}
},
"typeVersion": 1.2
},
{
"id": "4728f389-df04-4f8d-a436-ac06508d28ba",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-720,
260
],
"parameters": {
"width": 220,
"height": 380,
"content": "## Set Globals\n- Define the repository owner (username / organization) and repository name\n- By default the fist available Clockify workspace ID is set. This can be overridden here."
},
"typeVersion": 1
},
{
"id": "2e31df0a-1e67-4a9a-8dc1-42360b4da978",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1160,
360
],
"parameters": {
"width": 220,
"height": 280,
"content": "## Set trigger\nBy default this workflow runs once a day."
},
"typeVersion": 1
},
{
"id": "696721c6-25fc-48f9-b0f5-53d1b6462183",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-500,
300
],
"parameters": {
"width": 220,
"height": 340,
"content": "## Set Scope (optional)\nBy default the last three moths are being backed up.\n_0 = current month, 1 = last month, etc._"
},
"typeVersion": 1
},
{
"id": "a0ebb845-7472-40ec-b2b5-abc2f118b0e1",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
160,
360
],
"parameters": {
"color": 7,
"width": 220,
"height": 280,
"content": "A detailed report is being retrieved for every month across all entries in the workspace."
},
"typeVersion": 1
},
{
"id": "feb9f194-4c9d-41c8-9b46-3759dcdae9d5",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
380,
100
],
"parameters": {
"color": 7,
"width": 920,
"height": 780,
"content": "The reports are created or updated in GitHub.\n**It is essential to back up previous months as well, as values like tags may still change over time.**"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "34ab93f2-a965-42ac-bd44-478c19a0f7d6",
"connections": {
"Globals": {
"main": [
[
{
"node": "Set month indexes",
"type": "main",
"index": 0
}
]
]
},
"Set intervals": {
"main": [
[
{
"node": "Get detailed monthly report",
"type": "main",
"index": 0
}
]
]
},
"Compare Datasets": {
"main": [
[
{
"node": "Update file in GitHub",
"type": "main",
"index": 0
}
],
[],
[]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get first workspace",
"type": "main",
"index": 0
}
]
]
},
"Extract from File": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 1
}
]
]
},
"Point to new data": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 0
}
]
]
},
"Set month indexes": {
"main": [
[
{
"node": "Split Out indexes",
"type": "main",
"index": 0
}
]
]
},
"Split Out indexes": {
"main": [
[
{
"node": "Set intervals",
"type": "main",
"index": 0
}
]
]
},
"Skip empty reports": {
"main": [
[
{
"node": "Create file in GitHub",
"type": "main",
"index": 0
}
]
]
},
"Get first workspace": {
"main": [
[
{
"node": "Globals",
"type": "main",
"index": 0
}
]
]
},
"Check for 404 error message": {
"main": [
[
{
"node": "Skip empty reports",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop and Error",
"type": "main",
"index": 0
}
]
]
},
"Get detailed monthly report": {
"main": [
[
{
"node": "Check if file exists in GitHub",
"type": "main",
"index": 0
}
]
]
},
"Check if file exists in GitHub": {
"main": [
[
{
"node": "Point to new data",
"type": "main",
"index": 0
},
{
"node": "Extract from File",
"type": "main",
"index": 0
}
],
[
{
"node": "Check for 404 error message",
"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.
clockifyApigithubApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
Regularly backing up your Clockify time-tracking data ensures you never lose valuable insights into your team's productivity and project hours, giving you peace of mind against data loss or service disruptions. This workflow is ideal for freelancers, small business owners, or project managers who rely on Clockify for accurate billing and reporting. It kicks off with a scheduled cron trigger to automatically extract and compare datasets from your previous backups, then pushes any updates to a secure GitHub repository via HTTP requests, safeguarding your records without manual effort.
Use this template when you need a reliable, automated way to archive monthly Clockify reports for compliance or historical analysis, especially if your usage involves recurring projects. Avoid it for one-off exports or if you prefer cloud storage over GitHub, as it focuses on version-controlled backups. Common variations include adjusting the cron schedule for daily runs or integrating with Google Drive instead of GitHub for simpler file handling.
About this workflow
Clockify Backup Template. Uses extractFromFile, compareDatasets, stopAndError, splitOut. Scheduled trigger; 21 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.
Code Schedule. Uses httpRequest, splitInBatches, noOp, notion. Scheduled trigger; 27 nodes.
Wait Splitout. Uses httpRequest, convertToFile, extractFromFile, splitOut. Scheduled trigger; 19 nodes.
Ads Machine — Daily Ad Poller. Uses airtable, httpRequest. Scheduled trigger; 13 nodes.
Splitout Filter. Uses splitOut, stickyNote, httpRequest, scheduleTrigger. Scheduled trigger; 8 nodes.
Splitout Schedule. Uses httpRequest, splitOut, markdown, scheduleTrigger. Scheduled trigger; 8 nodes.