Automated Clockify Time Tracking to Xero Invoicing (n8n)

Streamline billing by automatically converting Clockify time entries into Xero Draft Invoices using n8n workflows.

Tools: ClockifyXero

Platform: n8n

Short Answer

A fully automated pipeline where stopped timers in Clockify trigger an n8n workflow that calculates billable totals and creates or updates a Draft Invoice in Xero. This ensures 100% accuracy in billing and provides real-time visibility into account receivables.

The Problem

Manual entry of billable hours from Clockify into Xero is tedious, prone to human error, and delays the invoicing cycle. Businesses often struggle with inconsistent data formats between time trackers and accounting software, leading to lost revenue from unbilled time.

The Outcome

A fully automated pipeline where stopped timers in Clockify trigger an n8n workflow that calculates billable totals and creates or updates a Draft Invoice in Xero. This ensures 100% accuracy in billing and provides real-time visibility into account receivables.

Step-by-Step Guide

1. **Create n8n Workflow**: Open your n8n instance and create a new workflow titled 'Clockify to Xero Invoicing'. 2. **Configure Clockify Trigger**: Add the 'Clockify Trigger' node. Set the 'Event' to 'Time Entry Created' or use a 'Webhook' node if self-hosting for instant triggers. Authenticate using your Clockify API Key. 3. **Identify Client**: Add a 'Xero' node with the action 'Get Contact'. Use an n8n expression `{{ $node["Clockify Trigger"].json["clientName"] }}` to find the matching contact in Xero. 4. **Filter Logic**: Add an 'IF' node after the trigger to ensure `billable` is `true`. Only continue if the entry is marked for billing. 5. **Time Transformation**: Clockify provides duration in seconds. Add an 'Edit Fields' (or Set) node. Use the expression `{{ $json.timeInterval.duration / 3600 }}` to convert seconds into decimal hours for Xero. 6. **Currency/Rate Mapping**: Use a 'Lookup Table' or 'Switch' node if you need to map specific Clockify Project IDs to Xero Service Account Codes (e.g., Project A -> Account 200). 7. **Configure Xero Action**: Add another 'Xero' node. Set 'Resource' to 'Invoice' and 'Operation' to 'Create'. Map the 'Contact ID' from Step 3 and the 'Quantity' from Step 5. 8. **Deduplication Check**: To prevent double-billing during updates, use the 'Execute Workflow' node or a 'Wait' node to batch entries, or store the Clockify Entry ID in a Xero 'Reference' field and check for its existence first. 9. **Error Handling**: Create a separate 'Error Trigger' node. Connect it to a 'Discord' or 'Slack' node to notify you if an invoice fail to generate due to a missing contact or expired OAuth token.

Data Mapping

| Clockify Field | n8n Expression / Transformation | Xero Field | Required | | :--- | :--- | :--- | :--- | | `clientName` | `{{ $json.clientName }}` | Contact Name / ID | Yes | | `timeInterval.duration` | `{{ $json.duration / 3600 }}` (Decimal Conversion) | Quantity (Hours) | Yes | | `description` | `{{ $json.description || 'No description' }}` | Line Item Description | Yes | | `billableAmount` | `{{ $json.hourlyRate.amount }}` | Unit Amount | No | | `id` | `{{ $json.id }}` | Reference / Internal Note | No | | `projectId` | `{{ $json.projectId === '123' ? '200' : '210' }}` | Account Code | Yes |

Gotchas & Failure Modes

• **Rate Limits**: Xero has a limit of 5,000 API calls per day. If syncing thousands of time entries, use the n8n 'Split in Batches' node to process entries in groups. • **Time Formatting**: Clockify returns ISO8601 durations; ensure you use n8n's `$luxon` library in expressions if complex date math is needed. • **OAuth Refresh**: If you are self-hosting n8n, ensure your environment variables for OAuth are correctly configured, or the Xero connection will expire every 30 minutes. • **Rounding Discrepancies**: Xero rounds to 2 decimal places. Ensure your n8n expression `{{ ($json.duration / 3600).toFixed(2) }}` matches your Xero rounding settings to avoid penny differences.

Verification Checklist

- [ ] **Clockify Webhook Active**: Triggered a test entry in Clockify and confirmed n8n received the JSON payload. - [ ] **Contact Match**: Verified the 'Xero Get Contact' node correctly identifies the client by name or email. - [ ] **Math Check**: Verified that a 90-minute entry in Clockify results in exactly '1.5' in the Xero invoice node. - [ ] **Draft Status**: Confirmed the invoice is created as 'Draft' in Xero (not 'Authorized') for final manual review. - [ ] **Error Path**: Manually broke the connection and confirmed the n8n 'Error Trigger' node fired an alert.

Ready to Automate?

Build this automation with n8n in minutes.