Automated AP: Dext Document Extraction to Sage Accounting (n8n)

Streamline accounts payable by syncing extracted Dext data into Sage via n8n's workflow engine.

Tools: DextSage

Platform: n8n

Short Answer

A fully automated pipeline where 'Published' items in Dext instantly create Purchase Invoices or Bills in Sage, complete with line-item detail, proper GL account mapping, and original document attachments for audit readiness.

The Problem

Manual entry of invoices and receipts from Dext into Sage Business Cloud or Intacct is time-consuming and prone to human error. Without automation, managing digital audit trails and paperless compliance becomes a bottleneck for accounting teams.

The Outcome

A fully automated pipeline where 'Published' items in Dext instantly create Purchase Invoices or Bills in Sage, complete with line-item detail, proper GL account mapping, and original document attachments for audit readiness.

Step-by-Step Guide

1. **Establish Webhook Trigger**: Create a 'Webhook Node' in n8n. Set the HTTP Method to POST. Copy the Test URL and paste it into your Dext Partner/Direct account under the Webhook settings for 'Item Published'. 2. **Configure Credentials**: For Dext, use a 'Header Auth' or 'Secret' node if using an API Key. For Sage, create an 'OAuth2 Credentials' object in n8n (using Client ID, Secret, and Auth/Token URLs specific to your Sage region). 3. **Data Polling/Fetching**: While the webhook initiates the flow, use an 'HTTP Request Node' to fetch the full JSON of the item from the Dext `/items` endpoint using the `item_id` from the webhook payload. 4. **Standardize Dates**: Use an 'Expression' in a Set Node or Code Node to format the Dext `date` field. Sage requires `YYYY-MM-DD`. Use: `{{ DateTime.fromISO($json.date).toISODate() }}`. 5. **Look up Sage Vendor**: Add an 'HTTP Request Node' to Sage's `/contacts` endpoint to find the vendor matching the Dext `supplier_name`. If not found, use an 'IF Node' to route to a 'Create Contact' node. 6. **Map Line Items**: Use the 'Code Node' or 'Item Lists' node to iterate through Dext's `line_items` array. Map Dext's `tax_amount` and `description` to the corresponding Sage JSON structure. 7. **Handle Attachments**: Use an 'HTTP Request Node' with the Dext `image_url`. In the node settings, change 'Response Format' to 'File'. This allows n8n to hold the binary data in memory for the next step. 8. **Post to Sage**: Use another 'HTTP Request Node' (POST) to the Sage `/purchase_invoices` endpoint. In the 'Body Parameters', reference the mapped expressions from previous steps. 9. **Attach PDF/Image**: Use the Sage `/attachments` endpoint. Pass the binary data from step 7. Ensure you link the `attachment_id` to the Invoice ID created in step 8. 10. **Error Handling**: Create an 'Error Trigger' workflow or use the 'On Error' settings on the Sage nodes to catch API rate limits (429) or validation errors (400), sending them to a 'Sticky Note' or Slack channel.

Data Mapping

| Dext Field | Sage Field | n8n Expression / Transformation | | :--- | :--- | :--- | | `supplier_name` | `contact_id` | Match via `HTTP Request` GET and `{{$json.id}}` | | `date` | `date` | `{{ DateTime.fromISO($node.Dext.json.date).toISODate() }}` | | `net_amount` | `net_amount` | `{{ $json.net_amount.toFloat() }}` | | `tax_amount` | `tax_amount` | `{{ $json.tax_amount.toFloat() }}` | | `reference` | `reference` | `{{ $json.reference || 'N/A' }}` | | `category` | `ledger_account_id` | Use a `Static Mapping Table` or `Switch Node` | | `image_url` | `attachment` | Manual binary fetch via HTTP Request node |

Gotchas & Failure Modes

- **Rate Limiting**: Sage APIs often limit requests per minute. Use the n8n 'Wait' node or 'Split in Batches' if publishing multiple items at once. - **Binary Memory**: If processing large PDF invoices, ensure your n8n instance has sufficient RAM, as binary data is handled in-memory by default. - **Tax Code Mismatches**: Sage is very strict about tax rates. Use an n8n 'Switch' node to map Dext tax labels (e.g., '20% VAT') to Sage Tax IDs (e.g., 'GB_VAT_REDUCED'). - **OAuth Token Expiry**: Ensure n8n is configured to automatically refresh the Sage OAuth token; otherwise, the workflow will fail after 60 minutes of inactivity.

Verification Checklist

- [ ] Webhook successfully receives `item_id` from Dext. - [ ] Date format verified as `YYYY-MM-DD` in the n8n execution log. - [ ] Sage Vendor lookup returns a valid UUID or ID string. - [ ] Attachment binary shows as a 'Binary' tab in the n8n node execution output. - [ ] Purchase Invoice appears in Sage as 'Draft' or 'Pending'. - [ ] Error handler triggers a notification if the Sage API returns a 400 'Balance Mismatch'.

Ready to Automate?

Build this automation with n8n in minutes.