Integration Architecture and Data Flow

FreeAgent and Odoo 18 integration employs a hub-and-spoke architecture where Odoo acts as the central data hub. The design uses Odoo’s web engine to create scheduled actions that poll FreeAgent’s REST API at configurable intervals. This approach gives you full control over synchronization timing and prevents API rate limit issues that plague webhook-based implementations. The architecture maintains Odoo as the system of record for operational data while treating FreeAgent as the specialized accounting endpoint.

Odoo 18’s new external API service handles all outbound connections to FreeAgent. You configure this service with your FreeAgent subdomain and authentication tokens. The service manages connection pooling and implements automatic retry logic for temporary network failures. Each data synchronization job runs as a separate queue worker within Odoo’s job queue system. This design prevents long-running sync operations from blocking other Odoo functions.

Data flows from FreeAgent to Odoo follow a strict dependency hierarchy. The system first imports contacts, then products and services, followed by invoices and payments. This order ensures all foreign key relationships resolve correctly during the import process. Outbound flows from Odoo to FreeAgent prioritize invoice creation followed by payment allocation. The bidirectional sync uses timestamp-based change detection to identify records that require updates.

The core integration module consists of three primary components. The FreeAgent connector class handles all API interactions and transforms FreeAgent’s JSON responses into Odoo-compatible data structures. The mapping engine converts field formats between systems, such as transforming FreeAgent’s decimal-based tax rates to Odoo’s percentage format. The synchronization scheduler manages execution timing and maintains the last successful sync timestamp for incremental updates.

You implement conflict resolution rules at the field level to handle data mismatches. The system gives priority to FreeAgent for accounting-related fields like payment status and invoice amounts. Odoo maintains control over product descriptions and customer contact information. This balanced approach respects each system’s domain authority while maintaining data consistency across platforms.

Step-by-Step Configuration

FreeAgent API Application Setup

Begin by creating a dedicated API application in your FreeAgent account. Navigate to the “My Apps” section under your account settings and select “Create New App.” Provide a descriptive name like “Odoo 18 Integration” and set the redirect URI to your Odoo instance’s base URL followed by “/freeagent/auth.” FreeAgent displays your client ID and client secret after application creation. Store these credentials securely—you will need them for Odoo configuration.

FreeAgent requires explicit user consent for API access. Implement the OAuth 2.0 authorization code flow in your Odoo module. Create a controller that redirects users to FreeAgent’s authorization endpoint with your client ID and requested scopes. The authorization URL follows this pattern: https://[your-subdomain].freeagent.com/oauth/authorize?response_type=code&client_id=[client-id]&redirect_uri=[redirect-uri]&scope=[scopes]. Request full access scopes for contacts, invoices, and banking to ensure complete integration functionality.

Odoo 18 Custom Module Development

Create a new Odoo module using the standard module structure. Define your module’s manifest file with dependencies on Odoo’s accounting, contacts, and web modules. The manifest should declare ‘web’ and ‘account’ as dependencies to access Odoo’s API framework and financial functions. Create models for storing FreeAgent connection parameters and synchronization status. Use Odoo’s encrypted fields for storing OAuth tokens to maintain security.

Implement the core FreeAgent connector class that handles API communication. This class must manage OAuth token refresh cycles and format API requests with proper headers. Here’s the basic class structure:

class FreeAgentConnector:
    def __init__(self, base_url, client_id, client_secret):
        self.base_url = base_url
        self.client_id = client_id
        self.client_secret = client_secret
        self.access_token = None
        
    def refresh_token(self):
        # Implementation for OAuth token refresh
        pass
        
    def get_invoices(self, since_date=None):
        # Implementation for fetching invoices
        pass

Authentication Configuration

Build the OAuth callback handler in your Odoo module. Create a controller that captures the authorization code from FreeAgent’s redirect and exchanges it for access and refresh tokens. The token exchange requires a POST request to FreeAgent’s token endpoint with your client credentials. Store the received tokens in Odoo’s encrypted fields along with the expiration timestamp. Implement automatic token refresh that triggers when the access token approaches expiry.

Configure Odoo’s scheduled actions to handle regular data synchronization. Create three separate scheduled jobs with different frequencies—contact sync every 6 hours, invoice sync every 2 hours, and payment sync every hour. This staggered approach distributes API load and ensures financial data remains current. Set up logging to track sync job execution and capture any errors for troubleshooting.

Data Model Mapping Configuration

Define the field mapping dictionaries in your module’s configuration. Create Python dictionaries that map FreeAgent field names to Odoo field names for each data type. Include transformation functions for data format conversions. Here’s an example for contact mapping:

CONTACT_MAPPING = {
    'first_name': 'name',
    'last_name': lambda x: x.get('last_name', ''),
    'email': 'email',
    'address1': 'street',
    'town': 'city',
    'region': 'state_id',
    'postcode': 'zip',
    'country': 'country_id'
}

Implement custom methods for handling complex transformations like country code conversion and currency mapping. Create lookup tables for FreeAgent to Odoo ID mapping to maintain cross-system references. These mappings enable the system to update existing records rather than creating duplicates during synchronization.

Synchronization Job Configuration

Create scheduled actions in Odoo’s technical settings for each sync type. Configure the invoice sync job to run every 2 hours during business hours and every 6 hours overnight. Set the contact sync to run four times daily and payment sync to run hourly. Assign appropriate priorities to ensure payment processing receives immediate attention while contact updates run as background tasks.

Test your configuration with a small data subset before full implementation. Create a test mode in your sync jobs that processes only records from the last 24 hours. Verify data accuracy by comparing record counts and field values between systems. Once testing completes, activate the full synchronization schedule and monitor performance for the first 48 hours.

Data Mapping and Transformation

Contact and Company Mapping

FreeAgent contact records require significant transformation to match Odoo’s partner model. FreeAgent stores individual names in separate ‘first_name’ and ‘last_name’ fields, while Odoo uses a single ‘name’ field for display purposes. Your mapping logic must concatenate these fields with proper handling for missing components. Business contacts present additional complexity—FreeAgent’s ‘organisation_name’ maps to Odoo’s ‘commercial_company_name’ with fallback logic for sole proprietors.

Address data transformation demands careful field-by-field mapping. FreeAgent’s address structure differs from Odoo’s multi-line street approach. Map ‘address1’ to ‘street’ and combine ‘address2’ with ‘address3’ for ‘street2’. Country mapping requires ISO code conversion since FreeAgent uses full country names while Odoo stores ISO codes. Implement a lookup table that handles common name variations and maintains consistency across sync cycles.

Contact type classification follows different tax treatment rules in each system. FreeAgent’s contact categories don’t align perfectly with Odoo’s customer/supplier flags. Map FreeAgent’s ‘is_customer’ and ‘is_supplier’ to Odoo’s corresponding boolean fields, but add logic to handle contacts that serve both roles. Set Odoo’s ‘company_type’ field based on whether the contact has an organization name or represents an individual.

Product and Service Mapping

FreeAgent treats all sale items as categories—either products or services. Odoo maintains a more detailed product taxonomy with configurable types. Map FreeAgent’s sale items to Odoo’s product template model, setting the product type based on the item’s nature. Use ‘service’ for time-based entries and ‘consu’ for physical products. This distinction affects inventory valuation and accounting entries in Odoo.

Pricing information requires currency-aware transformation. FreeAgent stores prices in the account’s base currency, while Odoo supports multi-currency pricing. Your mapping must apply the current exchange rate for non-base currency transactions. Implement a currency conversion service that fetches daily rates from Odoo’s currency module and applies them during product synchronization.

Invoice and Line Item Mapping

Invoice header mapping involves status conversion and date formatting. FreeAgent’s invoice states—draft, scheduled, sent, cancelled, paid—don’t match Odoo’s invoice status workflow. Create a state mapping table that translates FreeAgent statuses to appropriate Odoo states while preserving business logic. Date fields require timezone adjustment since FreeAgent stores dates in UTC while Odoo uses the company’s timezone.

Line item mapping demands careful tax handling. FreeAgent includes tax calculations within line amounts, while Odoo tracks pre-tax and tax amounts separately. Implement tax parsing logic that extracts the tax component based on the configured tax rate. This ensures accurate financial reporting and proper tax liability tracking in both systems.

Invoice payment status synchronization requires special attention. FreeAgent updates payment status immediately upon bank transaction import, while Odoo maintains separate payment records. Your mapping must create Odoo payment entries for paid FreeAgent invoices and reconcile them against the corresponding invoices. Handle partial payments by creating multiple payment records with appropriate allocations.

Payment and Bank Transaction Mapping

Payment mapping connects FreeAgent’s bank transaction records with Odoo’s account.move entries. FreeAgent groups multiple invoice payments within single bank transactions, while Odoo creates individual payment records. Implement payment allocation logic that matches FreeAgent’s payment distribution across invoices. This ensures your accounts receivable balance matches between systems.

Bank account synchronization maintains consistency for payment reconciliation. Map FreeAgent’s bank accounts to Odoo’s journal entries based on account name and last four digits of account number. Create missing bank journals in Odoo when new accounts appear in FreeAgent. This proactive approach ensures all financial transactions have proper destination accounts.

Error Handling and Resilience

API Rate Limit Management

FreeAgent imposes strict API rate limits—60 requests per minute for most endpoints. Your integration must implement intelligent request throttling to avoid hitting these limits. Track request counts within rolling 60-second windows and introduce automatic delays when approaching the limit. Implement exponential backoff for retry attempts, starting with 2-second delays and doubling after each failure.

Handle 429 Too Many Requests responses with graceful degradation. When the API returns rate limit errors, pause synchronization for 5 minutes before resuming. Log these events as warnings rather than errors to distinguish them from genuine failures. Design your sync jobs to resume from the last successful record rather than restarting from the beginning after rate limit interruptions.

Data Validation Errors

Field validation failures represent the most common integration errors. FreeAgent accepts some data formats that Odoo rejects, such as extremely long email addresses or special characters in names. Implement pre-sync validation that checks data against Odoo’s field constraints before attempting record creation. Truncate overlong fields and sanitize special characters based on each field’s requirements.

Duplicate record detection prevents data corruption during synchronization. Create fuzzy matching logic for contacts and products that identifies potential duplicates before import. Compare names, email addresses, and other identifying fields to flag possible matches. Present these potential duplicates to administrators for manual resolution rather than automatically merging records.

Network and Authentication Failures

Handle temporary network outages with retry mechanisms. Implement a circuit breaker pattern that detects consecutive connection failures and temporarily disables sync jobs during extended outages. Log these events with appropriate severity levels and notify administrators of service interruptions. Store failed sync attempts in a queue for reprocessing once connectivity restores.

Authentication token expiration requires automated recovery. Monitor token expiry timestamps and attempt automatic refresh before token expiration. Handle refresh failures by triggering re-authentication workflows that guide users through the OAuth consent process. Design your system to continue operating with stale data during authentication issues rather than failing completely.

Data Corruption Recovery

Implement data reconciliation procedures for resolving synchronization conflicts. Create automated checks that compare record counts and totals between systems at the end of each sync cycle. Flag discrepancies exceeding configured thresholds for manual review. Build repair tools that can reset synchronization timestamps and reprocess specific date ranges to correct data inconsistencies.

Maintain comprehensive audit trails of all synchronization activities. Log every record creation, update, and deletion with timestamps and user context. These logs enable precise identification of when data corruption occurred and simplify restoration from backups. Create data repair scripts that can reverse specific sync operations while preserving legitimate changes.

Testing and Validation

Test Environment Configuration

Establish isolated testing environments for both FreeAgent and Odoo. Create a FreeAgent sandbox account using their developer program—this provides full API access without affecting live financial data. Set up a dedicated Odoo 18 test instance with sample data that mirrors your production environment. This isolation lets you test integration behavior without risking business data corruption.

Prepare comprehensive test datasets that cover all integration scenarios. Create test contacts with varying attributes—individuals, companies, international addresses, and special characters in names. Build product catalogs with different tax treatments and pricing models. Generate invoice test cases that include partial payments, overdue amounts, and credit notes. This diversity ensures your integration handles edge cases.

Synchronization Validation Procedures

Implement automated validation checks that run after each synchronization cycle. Create validators that compare record counts for each data type between systems. Develop field-level checksums that verify data integrity by calculating hash values for critical fields across matched records. These automated checks catch synchronization issues before they affect business operations.

Validate financial data accuracy with amount reconciliation procedures. Create test reports that sum invoice totals, payment amounts, and tax calculations across both systems. The totals should match within acceptable rounding differences. Implement currency conversion validation for multi-currency transactions by verifying exchange rate applications match between systems.

Performance Benchmarking

Establish performance baselines for each synchronization type. Measure execution time for contact syncs (typically 100-200 records per minute), invoice syncs (50-100 records per minute), and payment syncs (20-50 records per minute). Monitor memory usage during synchronization to identify potential resource exhaustion issues. These benchmarks help detect performance degradation over time.

Test synchronization behavior under load conditions. Gradually increase sync volume to identify breaking points where performance degrades significantly. Monitor API response times from FreeAgent during high-volume syncs to detect when you approach rate limits. Use this data to optimize your sync scheduling and batch sizes for production deployment.

Error Scenario Testing

Simulate network failures and API outages to verify error handling robustness. Temporarily disconnect network access during synchronization to test recovery mechanisms. Modify API responses to return error codes and verify your integration handles them gracefully. These tests ensure your integration maintains data consistency even when external services become unreliable.

Test data conflict scenarios by modifying records in both systems simultaneously. Change contact information in FreeAgent while the sync is running to verify conflict resolution rules function correctly. Create invoice payments in Odoo while FreeAgent sync is processing to test payment allocation logic. These edge case tests validate your integration’s resilience in real-world conditions.

Security Considerations

Authentication Security

Implement secure token storage using Odoo 18’s encrypted fields feature. Never store OAuth tokens in plain text or in accessible configuration files. Configure token rotation policies that automatically refresh access tokens before expiration. Limit token scope to only the permissions your integration requires—avoid requesting full account access unless absolutely necessary.

Secure your OAuth implementation against common vulnerabilities. Validate state parameters in authorization callbacks to prevent CSRF attacks. Implement proper redirect URI validation to avoid open redirect vulnerabilities. Use PKCE (Proof Key for Code Exchange) if FreeAgent supports it to add additional security layer to the authorization flow.

Data Protection

Encrypt sensitive data both in transit and at rest. Use TLS 1.2 or higher for all API communications with FreeAgent. Enable Odoo’s database encryption features for storing financial data. Implement data anonymization procedures for test environments to prevent exposure of production financial information during development.

Apply principle of least privilege to integration access controls. Create dedicated FreeAgent user accounts with minimal permissions for the integration rather than using administrator credentials. Configure Odoo access rights so the integration module can only access necessary models and fields. This containment limits potential damage from security breaches.

Audit and Compliance

Maintain comprehensive audit trails of all data access and modification. Log every API call to FreeAgent with timestamps, user context, and affected records. Implement regular security reviews that examine these logs for suspicious patterns. Create alerts for unusual activities like unexpected large data exports or access from unfamiliar IP addresses.

Ensure your integration complies with financial data protection regulations. Implement data retention policies that automatically purge old synchronization logs while preserving required financial records. Create data export tools that can extract integration configuration for compliance audits. Document your security measures for regulatory review.

Performance Optimization

API Call Optimization

Reduce API calls through intelligent batching and caching strategies. FreeAgent’s API supports including related resources in single requests—use these include parameters to fetch contacts with their invoices in fewer calls. Implement response caching for relatively static data like tax rates and currency codes that change infrequently.

Optimize sync frequency based on data volatility patterns. Configure contact synchronization to run less frequently than payment syncs since customer data changes less often. Implement change detection mechanisms that only sync records modified since the last successful sync. This incremental approach dramatically reduces API consumption compared to full syncs each time.

Database Performance

Optimize database queries within your synchronization logic. Use Odoo’s read_group operations for bulk data retrieval instead of individual record searches. Implement selective field loading to fetch only necessary fields rather than complete records. Create database indexes on synchronization timestamp fields to speed up change detection queries.

Manage database transactions carefully during bulk operations. Process records in batches of 50-100 to prevent long database transactions that block other operations. Use Odoo’s delay_create and delay_write methods for non-critical updates that can process asynchronously. This approach maintains system responsiveness during large sync operations.

Memory Management

Implement efficient memory usage patterns in your sync jobs. Use generator expressions instead of lists for processing large record sets. This streams data through your integration rather than loading everything into memory simultaneously. Explicitly close database cursors and API connections after use to prevent resource leaks.

Monitor memory usage during synchronization and implement garbage collection triggers. Profile your integration to identify memory hotspots—typically record cache structures and field mapping dictionaries. Implement size limits on in-memory caches and disk-based swapping for exceptionally large datasets.