AutomationFlowsWeb Scraping › Backup Clockify to Github Based on Monthly Reports

Backup Clockify to Github Based on Monthly Reports

ByMario @octionic on n8n.io

This workflow creates a versioned backup of an entire Clockify workspace split up into monthly reports. This backup routine runs daily by default The Clockify reports API endpoint is used to get all data from the workspace based on time entries A report file is being retrieved…

Cron / scheduled trigger★★★★☆ complexity21 nodesStop And ErrorClockifyHTTP RequestGitHub
Web Scraping Trigger: Cron / scheduled Nodes: 21 Complexity: ★★★★☆ Added:
Backup Clockify to Github Based on Monthly Reports — n8n workflow card showing Stop And Error, Clockify, HTTP Request integration

This workflow corresponds to n8n.io template #3147 — we link there as the canonical source.

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 →

Download .json
{
  "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow creates a versioned backup of an entire Clockify workspace split up into monthly reports. This backup routine runs daily by default The Clockify reports API endpoint is used to get all data from the workspace based on time entries A report file is being retrieved…

Source: https://n8n.io/workflows/3147/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

[n8n] Advanced URL Parsing and Shortening Workflow - Switchy.io Integration. Uses splitInBatches, stickyNote, httpRequest, html. Event-driven trigger; 56 nodes.

HTTP Request, GitHub, Stop And Error +1
Web Scraping

[](https://youtu.be/c7yCZhmMjtI)

HTTP Request, GitHub, Stop And Error +1
Web Scraping

N8N-Workflow-Github-Manager. Uses github, httpRequest, n8n. Scheduled trigger; 38 nodes.

GitHub, HTTP Request, n8n
Web Scraping

This workflow provides everything you need to package and deploy multiple workflows from a single workflow you distribute.

n8n, Stop And Error, GitHub +1
Web Scraping

This workflow will gather data every minute from the GitHub (https://github.com), Docker (https://www.docker.com/), npm (https://www.npmjs.com/) and Product Hunt (https://www.producthunt.com/) website

HTTP Request, GitHub