Last updated 9 October 2026View as Markdown
Inside against outside IR35
POST /v1/ir35-compare Needs a keyThe same contract income inside IR35 through an umbrella and outside IR35 through your own limited company, with the difference in take-home.
Request
A JSON body. Fields not listed here are rejected.
| Field | Type | Description |
|---|---|---|
region required | string | Where they live: england, scotland, wales or northern_ireland. One of england, scotland, wales, northern_ireland. |
income required | object | Contract income: a day rate per day, or an amount a year, month or week. |
income.amount required in income | number | Pounds and pence. Allowed: 0 or more, under 100,000,000. |
income.per required in income | string | The period the amount is for. One of year, month, four_weeks, two_weeks, week, day, hour. |
margin required | object | The umbrella's margin, for the umbrella side. |
margin.amount required in margin | number | Pounds and pence. Allowed: 0 or more, under 100,000,000. |
margin.per required in margin | string | The period the amount is for. One of year, month, four_weeks, two_weeks, week, day, hour. |
tax_year optional | string | The tax year, such as 2026-27. The latest when not given. Default "2026-27". |
pay_frequency optional | string | How often they are paid: monthly (when not given), four_weekly, two_weekly or weekly. Each period runs through payroll. One of monthly, four_weekly, two_weekly, weekly. Default "monthly". |
working_pattern optional | object | Days and hours a week and weeks a year, for amounts per day or hour: 5 days, 37.5 hours and 52 weeks when not given. |
working_pattern.days_per_week optional | number | Days worked a week: 5 when not given. Allowed: more than 0, up to 7. Default 5. |
working_pattern.hours_per_week optional | number | Hours worked a week: 37.5 when not given. Allowed: more than 0, up to 168. Default 37.5. |
working_pattern.weeks_per_year optional | number | Weeks paid a year: 52 when not given. Allowed: 1 to 53. Default 52. |
expenses optional | object | Business costs a limited company pays from the income (accountant, insurance, equipment). |
expenses.amount required in expenses | number | Pounds and pence. Allowed: 0 or more, under 100,000,000. |
expenses.per required in expenses | string | The period the amount is for. One of year, month, four_weeks, two_weeks, week, day, hour. |
student_loans optional | array of string | Each loan they repay: plan_1, plan_2, plan_4, plan_5, postgraduate. One of plan_1, plan_2, plan_4, plan_5, postgraduate. Default []. |
apprenticeship_levy optional | boolean | Counts the Apprenticeship Levy in the umbrella's costs (0.5% of pay, for an umbrella whose pay bill is over £3 million). True when not given. Default true. |
Example
cURL
curl https://api.checktakehomepay.co.uk/v1/ir35-compare \
-H "Authorization: Bearer $CHECKTAKEHOMEPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"region": "england",
"income": {
"amount": 500,
"per": "day"
},
"margin": {
"amount": 25,
"per": "week"
},
"expenses": {
"amount": 3000,
"per": "year"
}
}'Node.js
const response = await fetch('https://api.checktakehomepay.co.uk/v1/ir35-compare', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CHECKTAKEHOMEPAY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"region": "england",
"income": {
"amount": 500,
"per": "day"
},
"margin": {
"amount": 25,
"per": "week"
},
"expenses": {
"amount": 3000,
"per": "year"
}
}),
});
const result = await response.json();Python
import os
import requests
response = requests.post(
"https://api.checktakehomepay.co.uk/v1/ir35-compare",
headers={"Authorization": f"Bearer {os.environ['CHECKTAKEHOMEPAY_API_KEY']}"},
json={
"region": "england",
"income": {"amount": 500, "per": "day"},
"margin": {"amount": 25, "per": "week"},
"expenses": {"amount": 3000, "per": "year"},
},
)
result = response.json()Response
200, with the result and what produced it: tax_year, engine, hmrc_test_data, assumptions and sources. This is the example's real response. Every field's type is in the OpenAPI document.
200 OK
{
"tax_year": "2026-27",
"engine": "2026-27.1",
"hmrc_test_data": "rest of UK and Welsh tax v1.0, Scottish tax v1.1, NI v1.0, directors NI v1.0, student loans v1.0",
"income": 130000,
"inside_ir35": {
"route": "umbrella",
"salary": 112078.45,
"within_budget": true,
"take_home": 73151.25
},
"outside_ir35": {
"route": "limited_company",
"salary": 12570,
"dividends": 87021.59,
"corporation_tax": 26272.91,
"take_home": 77960.34
},
"difference": 4809.09,
"assumptions": [
"Inside IR35 is through an umbrella company; outside IR35 is through your own limited company with no other employees (so no Employment Allowance), a salary from the usual choices and the rest of the profit as dividends.",
"Only what applies to both routes is asked for, so the difference is for the same income. Inside IR35 through your own company (the deemed payment) is not modelled.",
"Corporation tax is for a 12-month accounting period with no associated companies, with marginal relief between the limits.",
"Employment Allowance (employment_allowance) is not available to a company whose only employee paid above the secondary threshold is a director: the caller checks it applies.",
"The director's NI is on the annual earnings period, category A. Income tax is on the year's salary and dividends together, as Self Assessment settles it."
],
"sources": [
"https://www.gov.uk/corporation-tax-rates",
"https://www.gov.uk/guidance/corporation-tax-marginal-relief",
"https://www.gov.uk/tax-on-dividends",
"https://www.gov.uk/government/publications/payroll-technical-specifications-national-insurance",
"https://www.gov.uk/guidance/rates-and-thresholds-for-employers-2026-to-2027",
"https://www.thepensionsregulator.gov.uk/en/business-advisers/automatic-enrolment-guide-for-business-advisers/minimum-contribution-increases-planned-by-law-phasing",
"https://www.gov.uk/government/publications/payroll-technical-specifications-income-tax"
]
}Errors
- 400
INVALID_INPUT: the message names each field that is wrong. - 401
UNAUTHENTICATED(no key) orINVALID_KEY(a key we don’t know, or a revoked one).
Every code, and how to handle them: Errors.