FreeAgent is one of the most popular accounting platforms in the United Kingdom. It serves freelancers and small businesses with invoicing, expense tracking, Self Assessment tax returns, payroll, and MTD-compatible VAT filing. NatWest Group acquired the company in 2018, and it remains a common integration target for software that touches UK financial data.
This guide covers what you need to know to integrate with the FreeAgent API, from authentication and available endpoints to rate limits, pagination, and the specific challenges that make this integration more involved than the documentation suggests. If you want to skip the complexity of building a direct integration, Apideck's FreeAgent connector handles authentication, token refresh, and data normalization through a unified Accounting API.
What FreeAgent covers
FreeAgent targets a specific segment of the UK market: self-employed professionals, freelancers, and small limited companies. The platform handles:
- Invoicing and estimates
- Expense claims and receipt capture
- Bank account connections and reconciliation
- Self Assessment tax return filing
- VAT returns with Making Tax Digital compliance
- Payroll for small teams
- Project and time tracking
- Multi-currency support
The platform's tight focus on UK tax requirements makes it essential for software serving British freelancers and small businesses. If your customers use FreeAgent, they expect their data to flow into your application without manual exports.
API overview
FreeAgent offers two separate API products, and this distinction matters for how you architect your integration.
The Company API is for direct FreeAgent users: freelancers and small businesses managing their own accounting. This is the standard integration path for most applications.
The Accountancy Practice API is for accounting firms and bookkeepers who manage multiple client accounts through FreeAgent's Practice Dashboard. This requires a separate app registration, a different OAuth flow, and client-specific subdomains in request headers.
For a SaaS product that serves both direct business users and accounting firms, this means building and maintaining two distinct integration paths.
Both APIs are REST-based and support JSON and XML responses. The base URLs are:
- Production:
https://api.freeagent.com/v2 - Sandbox:
https://api.sandbox.freeagent.com/v2
The sandbox environment lets you test your integration without affecting live data. FreeAgent provides temporary sandbox accounts through their developer portal for this purpose.
Authentication
FreeAgent uses OAuth 2.0 with the authorization code flow. To get started:
- Create an account at the FreeAgent Developer Dashboard
- Register a new application to receive your OAuth Client ID and Client Secret
- Specify which access level your application requires (more on this below)
The authorization endpoint is:
https://api.freeagent.com/v2/approve_app
The token endpoint is:
https://api.freeagent.com/v2/token_endpoint
A basic token exchange looks like this:
curl -X POST https://api.freeagent.com/v2/token_endpoint \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "grant_type=authorization_code" \
-d "code=AUTH_CODE" \
-d "redirect_uri=YOUR_REDIRECT_URI"
Access tokens expire after one hour. Refresh tokens are long-lived (approximately 20 years according to the API response), so you can maintain persistent access without requiring users to re-authenticate.
Access levels
FreeAgent uses a numeric access level system (0 through 8) that controls which resources your app can read or write. When you register your application, you need to specify the access level you require. Each API resource has a minimum required level, and requesting a higher level than necessary will likely slow down your app approval.
Review the documentation to determine the minimum access level that covers your use case. If you only need to read invoices and contacts, you don't need the same permissions as an app that manages payroll.
Key endpoints
The Company API covers the core accounting resources you'd expect:
/v2/contactsfor customers and suppliers/v2/invoicesfor sales invoices/v2/billsfor purchase invoices/v2/expensesfor expense claims/v2/bank_accountsfor connected bank accounts/v2/bank_transactionsfor bank transaction data/v2/projectsfor project management/v2/tasksfor time tracking/v2/usersfor user accounts/v2/companyfor company settings/v2/categoriesfor expense categories/v2/tax_ratesfor VAT rates/v2/journal_entriesfor manual journal entries/v2/payroll_profilesand/v2/payslipsfor payroll data
The API supports standard CRUD operations on most resources. Each endpoint is documented in the FreeAgent API documentation.
Rate limits
FreeAgent enforces the following rate limits:
- 120 requests per minute per user
- 3,600 requests per hour per user
- 15 token refreshes per minute per user
These limits reset at the start of every hour or minute. For Accountancy Practice API users, rate limits apply per client subdomain rather than to the practice as a whole.
When you hit a rate limit, the API returns a 429 response with a Retry-After header indicating how long to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
The 120 requests per minute limit is generous for most use cases. However, the 15 token refreshes per minute limit creates a specific bottleneck for multi-tenant applications. If you're running a SaaS product with many customers and you trigger concurrent token refreshes during a scheduled sync, you can exhaust this limit before pulling any actual data. You'll need to implement token refresh queuing or stagger sync schedules across your customer base.
FreeAgent provides a testing header X-RateLimit-Test that artificially lowers the sandbox rate limit to 5 requests per minute, letting you verify your backoff strategy before hitting production limits.
Pagination
API requests that return multiple items are paginated with a default of 25 items per page and a maximum of 100 items per page.
GET https://api.freeagent.com/v2/invoices?page=2&per_page=50
Pagination metadata comes in headers rather than the response body:
- The
Linkheader contains URLs forprev,next,first, andlastpages - The
X-Total-Countheader contains the total number of items
The 25-item default is lower than most accounting APIs. If you're syncing large datasets, you'll want to set per_page=100 and implement proper pagination handling to avoid missing records.
Working with contacts
Creating a contact requires minimal data:
curl -X POST https://api.freeagent.com/v2/contacts \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"contact": {
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"organisation_name": "Smith Consulting"
}
}'
A successful creation returns a 201 status with the created contact object, including the FreeAgent URL identifier you'll need for subsequent operations.
Integration challenges
Beyond the two-API-product architecture and rate limits, several characteristics make FreeAgent integrations more complex than they initially appear.
No webhooks. The standard FreeAgent API doesn't support webhooks for real-time notifications. You'll need to poll for changes, which means designing an efficient sync strategy that respects rate limits while keeping data reasonably current. This is a meaningful limitation for applications that need near-real-time data.
UK-specific data models. FreeAgent's data structures reflect UK accounting conventions and tax requirements. VAT handling, Self Assessment categories, and MTD-specific fields may not map cleanly to more generic accounting schemas. If you're building a multi-country application, you'll need transformation logic specific to FreeAgent's UK-centric model.
Documentation in context. While the API documentation is available through the developer portal, some details only become clear through trial and error. Error messages are generally helpful, but the sandbox environment is essential for understanding how the API actually behaves before you deploy to production.
Scaling beyond FreeAgent
FreeAgent covers the UK freelancer and small business market well, but most B2B applications need to integrate with multiple accounting platforms. Your UK customers use FreeAgent, your US customers use QuickBooks, your Dutch customers use SnelStart, and your Australian customers use Xero.
Building and maintaining direct integrations to each platform means handling different authentication flows, different data models, different rate limits, and different error handling for every connector. Each integration requires its own development time and ongoing maintenance as APIs change.
A unified API gives you one integration point and one data schema across all of them. Instead of managing FreeAgent's token refresh limits, QuickBooks' OAuth flow, and Xero's pagination separately, you write against a single normalized Accounting API and let the platform handle the connector-specific complexity.
With Apideck, listing invoices from FreeAgent looks like this:
import { Apideck } from '@apideck/node'
const apideck = new Apideck({
apiKey: process.env.APIDECK_API_KEY,
appId: process.env.APIDECK_APP_ID,
consumerId: 'user-123'
})
const { data } = await apideck.accounting.invoicesAll({
serviceId: 'freeagent'
})
The same code structure works for QuickBooks, Sage, Xero, and every other accounting connector in the platform.
Create a free Apideck account to get started.
Ready to get started?
Scale your integration strategy and deliver the integrations your customers need in record time.








