syntropic Get a free key

Gross-to-Net Salary Calculator documentation

Overview

The Gross-to-Net Salary Calculator computes net pay, every employee deduction and every employer contribution from a gross salary, using each country's official payroll algorithm. It also works backwards (net → gross) and runs up to 8 scenarios side by side.

Coverage today:

  • Germany, tax years 2025 and 2026. Wage tax (Lohnsteuer) from our own implementation of the BMF Programmablaufplan (PAP): tax classes I–VI, child allowances, the factor procedure for class IV, an annual tax allowance from the tax card and age relief. Solidarity surcharge, church tax (8 % in Bayern and Baden-Württemberg, 9 % elsewhere), health insurance with the fund's add-on rate, long-term care with the childless surcharge, the child discounts and the Saxony split, pension and unemployment insurance with the contribution ceilings, and the employer's shares plus the insolvency levy.
  • United Kingdom, tax years 2025-26 and 2026-27. PAYE income tax for any tax code (L, K, BR, D0–D3, NT, 0T, week 1/month 1, and the cumulative basis with pay and tax to date), Scottish (S) and Welsh (C) rates, and Class 1 National Insurance for categories A, B, C, H, J, M, V and Z, including the employer's NICs.
  • Planned, not available yet: Austria, Switzerland, the Netherlands and the United States (federal + FICA). GET /countries lists them with "status": "planned".

What you get on top of a single net figure:

  • Every deduction and contribution is its own line with payer (employee or employer), rate, base, the rule applied in words and the official source.
  • employer_cost (gross plus employer contributions), deduction_rate and the figures scaled to a year (annual).
  • profile echoes the profile as applied, including defaults the API filled in, and notes lists every assumption and what is not included.

How accurate is it? The German wage-tax engine matches 320 of 320 labelled cases generated from the BMF's own wage-tax calculator interface (160 per year: wage tax, solidarity surcharge, church-tax base, one-off payments). The UK engine matches all 336 PAYE rows and all 896 National Insurance rows of HMRC's software developers payroll test data for 2025-26 and 2026-27. That is 1,552 of 1,552 official cases to the cent. German social insurance has no official test oracle, so it is covered by hand-checked unit tests. The current numbers are shown on https://syntropicapi.com/apis/salary-net.

What it is not. Results are estimates for offers, budgeting and comparisons, not a payroll run and not tax advice. Special cases that the API does not model are rejected with a clear 400 error instead of being approximated: German Minijob/Midijob pay (up to 2,000 EUR per month), private health insurance (PKV) and employees above the statutory retirement age; for the UK, student loans and pensions are not deducted (the response says so in notes).

Base URL: https://syntropicapi.com/v1/salary-net. OpenAPI spec: https://syntropicapi.com/openapi/salary-net.json.

Amounts are in EUR for Germany and GBP for the UK. The API does not convert currencies.

Authentication

API key (syntropicapi.com). Buy credits at https://syntropicapi.com/pricing and send the key in the X-API-Key header (Authorization: Bearer <key> also works). Each successful call costs 1 credit, including a /compare call with 8 scenarios. Failed calls (4xx/5xx) are not charged. Successful responses carry an X-Credits-Remaining header.

curl -s "https://syntropicapi.com/v1/salary-net/countries" -H "X-API-Key: $SYNTROPIC_API_KEY"

RapidAPI. Subscribe to the API on RapidAPI and call it with your RapidAPI key (X-RapidAPI-Key and X-RapidAPI-Host headers, as shown in the RapidAPI code snippets). Your RapidAPI plan sets the quota. You don't need a syntropicapi.com key.

MCP (AI agents). The same five operations are MCP tools at https://syntropicapi.com/mcp/salary-net/mcp (Streamable HTTP). Send your syntropicapi.com key in the X-API-Key header. Each tool call costs 1 credit. Listing the tools is free. The tools are calculate_net_salary, calculate_gross_salary, compare_net_salaries, get_payroll_parameters and list_salary_countries, and their arguments are the same as the REST bodies and parameters below. For example, with Claude Code:

claude mcp add --transport http salary-net https://syntropicapi.com/mcp/salary-net/mcp --header "X-API-Key: $SYNTROPIC_API_KEY"

x402 pay-per-call is not enabled on this deployment at the moment (https://syntropicapi.com/health reports "x402": false). Use an API key, RapidAPI or MCP.

Request body: scenario and profiles

POST /net, POST /gross and each entry of POST /compare share these fields:

Field Type Required Description
country string yes DE or UK (GB is accepted as UK)
year integer no Tax year, default 2026. UK: the year the tax year starts in (2026 = 2026-27). Supported: DE 2025, 2026; UK 2025, 2026
period string no Pay period of the amount, default month. DE: year, month, week, day. UK: year, month, week, fortnight, four_weeks
gross number /net, /compare Gross pay for the period, > 0 and up to 10,000,000
net number /gross Target net pay for the period, > 0 and up to 5,000,000
de object no German profile (only with country: DE). Omit for the defaults below
uk object no UK profile (only with country: UK). Omit for the defaults below

Sending the other country's profile is a 400 error ("The uk profile is not used for DE; send a de profile instead."). Unknown fields are rejected.

German profile (de)

Field Type Default Description
tax_class integer 1–6 1 Steuerklasse: I single, II single parent, III/V married split, IV married, VI second job
state string NW Bundesland of the workplace: BW, BY, BE, BB, HB, HH, HE, MV, NI, NW, RP, SL, SN, ST, SH, TH. Sets the church-tax rate; SN applies the Saxony care-insurance split
church boolean false Member of a church that levies church tax
children integer 0–20 0 Children under 25: care-insurance discounts from the 2nd child and, by default, the child allowances
child_allowances number 0–20 children Kinderfreibeträge on the tax card in 0.5 steps (0.5 per child when the parents split them)
parent boolean children > 0 Has ever had a child, so no childless surcharge in care insurance
birth_year integer none Childless surcharge only from age 23, age relief from 65; 67 and older is rejected
health_insurance string statutory Only statutory is supported; private returns 400
health_insurance_addon_rate number 0–10 official average (2.9 % in 2026) The health fund's Zusatzbeitrag in %, e.g. 2.5
factor number 0–1 none Faktorverfahren factor for tax class IV, three decimals (e.g. 0.912)
annual_tax_allowance number 0 Tax allowance (Freibetrag) on the tax card, EUR per year

UK profile (uk)

Field Type Default Description
region string england england, northern-ireland, scotland or wales: where the employee lives for income tax
tax_code string 1257L with the region's prefix PAYE tax code, e.g. 1257L, S1257L, C1257L, K475, BR, D0, NT, 0T, 1257L M1
ni_category string A NI category letter: A standard, B reduced, C over State Pension age, H apprentice under 25, J deferred, M under 21, V veteran, Z under 21 deferred
period_number integer 1–52 none Tax week or month number for the cumulative basis. Omit for a stand-alone (week 1/month 1) period
previous_pay number none Taxable pay in this tax year before this period (cumulative basis)
previous_tax number none Tax deducted in this tax year before this period (cumulative basis)

Response fields (/net and /gross): country, year, tax_year (2026 or 2026-27), period, currency, gross, net, employee_deductions, employer_contributions, employer_cost, deduction_rate (employee deductions in % of gross), annual (gross, net, employer_cost × periods per year), lines, profile, notes, sources (name, url, license) and disclaimer.

Each entry in lines has key (income_tax, solidarity_surcharge, church_tax, health_insurance, care_insurance, pension_insurance, unemployment_insurance, insolvency_levy, national_insurance), label, amount, payer, rate (in %, where a single rate applies), base, rule and source. A contribution that both sides pay appears twice, once per payer. On the UK cumulative basis amount can be negative (a tax refund).

For annual, a year has 12 months, 52 weeks, 26 fortnights, 13 four-week periods or 360 days.

Endpoints

POST /net

Gross → net for one pay period, with every deduction, the employer cost and the sources.

Example: Germany 2026, 4,500 EUR per month, tax class I, Bavaria, church member

curl -s -X POST "https://syntropicapi.com/v1/salary-net/net" -H "X-API-Key: $SYNTROPIC_API_KEY" -H "Content-Type: application/json" -d '{"country": "DE", "year": 2026, "gross": 4500, "period": "month", "de": {"tax_class": 1, "state": "BY", "church": true}}'

Response (trimmed: source shortened, the employer's pension and unemployment lines and the sources list left out):

{
  "country": "DE",
  "year": 2026,
  "tax_year": "2026",
  "period": "month",
  "currency": "EUR",
  "gross": 4500.0,
  "net": 2819.08,
  "employee_deductions": 1680.92,
  "employer_contributions": 958.5,
  "employer_cost": 5458.5,
  "deduction_rate": 37.35,
  "annual": {"gross": 54000.0, "net": 33828.96, "employer_cost": 65502.0},
  "lines": [
    {"key": "income_tax", "label": "Lohnsteuer (wage tax)", "amount": 650.16, "payer": "employee", "rate": null, "base": null, "rule": "PAP 2026: tax class 1, 0 child allowances, pay period month", "source": "BMF: Programmablaufplan für die maschinelle Berechnung der Lohnsteuer 2026 (BMF-Schreiben)"},
    {"key": "solidarity_surcharge", "label": "Solidaritätszuschlag", "amount": 0.0, "payer": "employee", "rate": null, "base": null, "rule": "PAP: 5.5 % of the wage tax with child allowances, zero below the exemption limit and phased in above it", "source": "BMF: Programmablaufplan … 2026"},
    {"key": "church_tax", "label": "Kirchensteuer", "amount": 52.01, "payer": "employee", "rate": 8.0, "base": 650.16, "rule": "8 % (Bayern) of the church-tax base 650.16 EUR (wage tax with child allowances, PAP output BK)", "source": "Kirchensteuergesetze der Länder: 8 % in Bayern and Baden-Württemberg, 9 % in the other Länder"},
    {"key": "health_insurance", "label": "Krankenversicherung (health)", "amount": 393.75, "payer": "employee", "rate": 8.75, "base": 4500.0, "rule": "14.6 % general rate + 2.9 % add-on, split equally", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "health_insurance", "label": "Krankenversicherung (health)", "amount": 393.75, "payer": "employer", "rate": 8.75, "base": 4500.0, "rule": "14.6 % general rate + 2.9 % add-on, split equally", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "care_insurance", "label": "Pflegeversicherung (long-term care)", "amount": 108.0, "payer": "employee", "rate": 2.4, "base": 4500.0, "rule": "3.6 % total; +0.6 % childless surcharge paid by the employee (age 23+, no children)", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "care_insurance", "label": "Pflegeversicherung (long-term care)", "amount": 81.0, "payer": "employer", "rate": 1.8, "base": 4500.0, "rule": "3.6 % total; +0.6 % childless surcharge paid by the employee (age 23+, no children)", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "pension_insurance", "label": "Rentenversicherung (pension)", "amount": 418.5, "payer": "employee", "rate": 9.3, "base": 4500.0, "rule": "18.6 %, split equally", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "unemployment_insurance", "label": "Arbeitslosenversicherung (unemployment)", "amount": 58.5, "payer": "employee", "rate": 1.3, "base": 4500.0, "rule": "2.6 %, split equally", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "insolvency_levy", "label": "Insolvenzgeldumlage (insolvency levy)", "amount": 6.75, "payer": "employer", "rate": 0.15, "base": 4500.0, "rule": "Employer-only levy on pay up to the pension ceiling", "source": "SGB V § 241/§ 242 (health), SGB XI § 55 (care), SGB VI § 158 (pension), SGB III § 341 (unemployment)"}
  ],
  "profile": {"tax_class": 1, "state": "BY", "church": true, "children": 0, "child_allowances": 0.0, "parent": false, "childless_surcharge": true, "health_insurance_addon_rate": 2.9, "birth_year": null, "factor": null, "annual_tax_allowance": 0},
  "notes": [
    "Health insurance add-on rate (Zusatzbeitrag) not given; used the official average of 2.9 % for 2026. Each fund sets its own rate.",
    "Employer cost excludes the fund-specific U1/U2 levies and statutory accident insurance (BG), which depend on the employer's health fund and industry."
  ],
  "sources": ["…"],
  "disclaimer": "Estimate for offers, budgeting and comparisons, not a payroll run and not tax advice. Computed with the official algorithms and the rates cited on each line; individual circumstances (other income, benefits in kind, pensions, fund-specific levies) can change the result."
}

Example: UK 2026-27, 55,000 GBP per year, Scottish taxpayer

No tax code given, so the API uses S1257L and says so in notes.

curl -s -X POST "https://syntropicapi.com/v1/salary-net/net" -H "X-API-Key: $SYNTROPIC_API_KEY" -H "Content-Type: application/json" -d '{"country": "UK", "year": 2026, "gross": 55000, "period": "year", "uk": {"region": "scotland"}}'

Response (trimmed: sources left out):

{
  "country": "UK",
  "year": 2026,
  "tax_year": "2026-27",
  "period": "year",
  "currency": "GBP",
  "gross": 55000.0,
  "net": 40811.13,
  "employee_deductions": 14188.87,
  "employer_contributions": 7500.0,
  "employer_cost": 62500.0,
  "deduction_rate": 25.8,
  "annual": {"gross": 55000.0, "net": 40811.13, "employer_cost": 62500.0},
  "lines": [
    {"key": "income_tax", "label": "Income tax (PAYE)", "amount": 11078.27, "payer": "employee", "rate": null, "base": 42421.0, "rule": "Tax code S1257L, scotland rates, week1/month1 basis; taxable pay to date 42,421 GBP", "source": "Scottish income tax rates and bands (Scottish Rate Resolution)"},
    {"key": "national_insurance", "label": "National Insurance (Class 1 employee)", "amount": 3110.6, "payer": "employee", "rate": null, "base": 55000.0, "rule": "Category A (Standard rate): 8 % between PT 12570 and UEL 50270 GBP per year, 2 % above", "source": "HMRC: Class 1 National Insurance thresholds, rates and category letters"},
    {"key": "national_insurance", "label": "National Insurance (Class 1 employer)", "amount": 7500.0, "payer": "employer", "rate": 15.0, "base": 55000.0, "rule": "15 % above the secondary threshold 5000 GBP per year", "source": "HMRC: Class 1 National Insurance thresholds, rates and category letters"}
  ],
  "profile": {"region": "scotland", "tax_code": "S1257L", "ni_category": "A", "basis": "week1/month1", "period_number": null, "tax_to_date": null},
  "notes": [
    "No tax code given; used the standard personal allowance code S1257L (personal allowance 12,570 GBP).",
    "Annual figures: tax on the annual basis, NICs with the annual earnings-period thresholds.",
    "Not included: pension auto-enrolment, salary sacrifice, student and postgraduate loans, and the Apprenticeship Levy (only for pay bills above 3 million GBP)."
  ],
  "sources": ["…"],
  "disclaimer": "Estimate for offers, budgeting and comparisons, not a payroll run and not tax advice. …"
}

Example: UK cumulative basis (month 6 with pay and tax to date)

Pass period_number, previous_pay and previous_tax to get the tax that PAYE deducts in that month, as payroll software does. Here the pay to date was high, so month 6 catches up.

curl -s -X POST "https://syntropicapi.com/v1/salary-net/net" -H "X-API-Key: $SYNTROPIC_API_KEY" -H "Content-Type: application/json" -d '{"country": "UK", "year": 2026, "gross": 4000, "period": "month", "uk": {"tax_code": "1257L", "period_number": 6, "previous_pay": 20000, "previous_tax": 2400}}'

Response (trimmed):

{
  "tax_year": "2026-27",
  "period": "month",
  "gross": 4000.0,
  "net": 2621.84,
  "employee_deductions": 1378.16,
  "employer_cost": 4537.45,
  "lines": [
    {"key": "income_tax", "label": "Income tax (PAYE)", "amount": 1142.0, "payer": "employee", "base": 17710.0, "rule": "Tax code 1257L, rest-of-uk rates, cumulative basis, period 6; taxable pay to date 17,710 GBP"},
    {"key": "national_insurance", "label": "National Insurance (Class 1 employee)", "amount": 236.16, "payer": "employee", "rule": "Category A (Standard rate): 8 % between PT 1048 and UEL 4189 GBP per month, 2 % above"},
    {"key": "national_insurance", "label": "National Insurance (Class 1 employer)", "amount": 537.45, "payer": "employer", "rate": 15.0, "rule": "15 % above the secondary threshold 417 GBP per month"}
  ],
  "profile": {"region": "england", "tax_code": "1257L", "ni_category": "A", "basis": "cumulative", "period_number": 6, "tax_to_date": 3542.0}
}

POST /gross

Net → gross: finds the smallest gross pay, to the cent, whose net pay reaches net, by bisection over the same engine as /net. The response has all /net fields for that gross pay plus target_net and difference (net - target_net, 0 when the target is reachable to the cent). Body: the scenario fields above with net instead of gross.

If the target needs a German gross in the Minijob/Midijob range (up to 2,000 EUR per month), the API returns 400 unsupported_profile.

Example: 3,000 EUR net per month in Hesse, tax class III, two children

curl -s -X POST "https://syntropicapi.com/v1/salary-net/gross" -H "X-API-Key: $SYNTROPIC_API_KEY" -H "Content-Type: application/json" -d '{"country": "DE", "year": 2026, "net": 3000, "period": "month", "de": {"tax_class": 3, "children": 2, "state": "HE"}}'

Response (trimmed: employer lines, notes and sources left out):

{
  "country": "DE",
  "tax_year": "2026",
  "period": "month",
  "currency": "EUR",
  "gross": 4077.33,
  "net": 3000.0,
  "employee_deductions": 1077.33,
  "employer_contributions": 868.46,
  "employer_cost": 4945.79,
  "deduction_rate": 26.42,
  "annual": {"gross": 48927.96, "net": 36000.0, "employer_cost": 59349.48},
  "lines": [
    {"key": "income_tax", "label": "Lohnsteuer (wage tax)", "amount": 225.16, "payer": "employee", "rule": "PAP 2026: tax class 3, 2 child allowances, pay period month"},
    {"key": "solidarity_surcharge", "label": "Solidaritätszuschlag", "amount": 0.0, "payer": "employee"},
    {"key": "health_insurance", "label": "Krankenversicherung (health)", "amount": 356.77, "payer": "employee", "rate": 8.75, "base": 4077.33},
    {"key": "care_insurance", "label": "Pflegeversicherung (long-term care)", "amount": 63.2, "payer": "employee", "rate": 1.55, "base": 4077.33, "rule": "3.6 % total; -0.25 % employee discount for 2 children under 25 (0.25 % from the 2nd to the 5th child)"},
    {"key": "pension_insurance", "label": "Rentenversicherung (pension)", "amount": 379.19, "payer": "employee", "rate": 9.3, "base": 4077.33},
    {"key": "unemployment_insurance", "label": "Arbeitslosenversicherung (unemployment)", "amount": 53.01, "payer": "employee", "rate": 1.3, "base": 4077.33}
  ],
  "profile": {"tax_class": 3, "state": "HE", "church": false, "children": 2, "child_allowances": 2.0, "parent": true, "childless_surcharge": false, "health_insurance_addon_rate": 2.9},
  "target_net": 3000.0,
  "difference": 0.0
}

POST /compare

Runs 1 to 8 gross-to-net scenarios (countries, years, profiles) and returns them side by side. One call costs 1 credit, whatever the number of scenarios. Amounts stay in each country's currency (no FX conversion); deduction_rate compares directly.

Field Type Required Description
scenarios array yes 1–8 objects with the /net body fields (country, year, gross, period, de or uk)

Each row has label, country, tax_year, currency, period, gross, net, employee_deductions, employer_cost, deduction_rate, annual_net, income_tax (income or wage tax plus solidarity surcharge and church tax) and social_contributions (employee social insurance or National Insurance). If one scenario is invalid, the whole call returns 400 with the scenario number, e.g. "scenario 2: …".

Example: 60,000 EUR in Germany (2026 and 2025) against 52,000 GBP in the UK

curl -s -X POST "https://syntropicapi.com/v1/salary-net/compare" -H "X-API-Key: $SYNTROPIC_API_KEY" -H "Content-Type: application/json" -d '{"scenarios": [{"country": "DE", "year": 2026, "gross": 60000, "period": "year"}, {"country": "UK", "year": 2026, "gross": 52000, "period": "year"}, {"country": "DE", "year": 2025, "gross": 60000, "period": "year"}]}'
{
  "rows": [
    {"label": "DE 2026, tax class 1", "country": "DE", "tax_year": "2026", "currency": "EUR", "period": "year", "gross": 60000.0, "net": 37561.0, "employee_deductions": 22439.0, "employer_cost": 72780.0, "deduction_rate": 37.4, "annual_net": 37561.0, "income_tax": 9389.0, "social_contributions": 13050.0},
    {"label": "UK 2026-27, 1257L", "country": "UK", "tax_year": "2026-27", "currency": "GBP", "period": "year", "gross": 52000.0, "net": 40721.0, "employee_deductions": 11279.0, "employer_cost": 59050.0, "deduction_rate": 21.69, "annual_net": 40721.0, "income_tax": 8228.4, "social_contributions": 3050.6},
    {"label": "DE 2025, tax class 1", "country": "DE", "tax_year": "2025", "currency": "EUR", "period": "year", "gross": 60000.0, "net": 37509.0, "employee_deductions": 22491.0, "employer_cost": 72660.0, "deduction_rate": 37.49, "annual_net": 37509.0, "income_tax": 9561.0, "social_contributions": 12930.0}
  ],
  "notes": ["Amounts are in each country's currency; convert with your own FX rate before comparing absolute values. deduction_rate compares directly."],
  "disclaimer": "Estimate for offers, budgeting and comparisons, not a payroll run and not tax advice. …"
}

GET /parameters

The allowances, tax bands, contribution rates and ceilings the engine uses for one country and tax year, each with its official source.

Parameter Type Required Description
country string yes DE or UK (GB is accepted)
year integer no Tax year, default 2026 (UK: start year, 2026 = 2026-27)

Each entry in parameters has key, label, value, unit and source.

curl -s "https://syntropicapi.com/v1/salary-net/parameters?country=DE&year=2026" -H "X-API-Key: $SYNTROPIC_API_KEY"

Response (trimmed: 8 of 21 parameters shown, source shortened):

{
  "country": "DE",
  "year": 2026,
  "tax_year": "2026",
  "currency": "EUR",
  "parameters": [
    {"key": "basic_allowance", "label": "Grundfreibetrag (basic tax-free allowance)", "value": 12348.0, "unit": "EUR/year", "source": "BMF: Programmablaufplan für die maschinelle Berechnung der Lohnsteuer 2026 (BMF-Schreiben)"},
    {"key": "child_allowance", "label": "Kinderfreibetrag incl. BEA per child (both parents)", "value": 9756.0, "unit": "EUR/year", "source": "BMF: Programmablaufplan … 2026"},
    {"key": "solidarity_exemption", "label": "Solidarity surcharge exemption limit (single; doubled in class III)", "value": 20350.0, "unit": "EUR tax/year", "source": "BMF: Programmablaufplan … 2026"},
    {"key": "bbg_kv_pv", "label": "Contribution ceiling health and care insurance", "value": 69750.0, "unit": "EUR/year", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "bbg_rv_av", "label": "Contribution ceiling pension and unemployment insurance", "value": 101400.0, "unit": "EUR/year", "source": "Sozialversicherungs-Rechengrößenverordnung 2026"},
    {"key": "kv_addon_average", "label": "Average health insurance add-on rate (durchschnittlicher Zusatzbeitrag)", "value": 2.9, "unit": "%", "source": "SGB V § 241/§ 242 (health), …"},
    {"key": "pv_childless", "label": "Care insurance childless surcharge (employee)", "value": 0.6, "unit": "%", "source": "SGB V § 241/§ 242 (health), …"},
    {"key": "midijob_upper_month", "label": "Upper limit of the transition zone (Midijob)", "value": 2000.0, "unit": "EUR/month", "source": "SGB V § 241/§ 242 (health), …"}
  ]
}

For the UK (country=UK&year=2026) the list holds the personal allowance (12,570 GBP), the income tax bands for the rest of the UK, Wales and Scotland (e.g. "scotland: 42 % on taxable pay 31,093–62,430"), the NI lower earnings limit, primary and secondary thresholds and upper earnings limit per week, month and year, and the employee (8 %, 2 % above the UEL, 1.85 % for category B) and employer (15 %) NI rates.

GET /countries

Coverage: which countries and tax years are available, which pay periods and profile fields each accepts, the official test data each engine is checked against, and which countries are planned. No parameters.

curl -s "https://syntropicapi.com/v1/salary-net/countries" -H "X-API-Key: $SYNTROPIC_API_KEY"

Response (trimmed: two of the four planned countries shown):

{
  "countries": [
    {"country": "DE", "name": "Germany", "status": "available", "currency": "EUR", "years": [2025, 2026], "periods": ["year", "month", "week", "day"], "profile_fields": ["tax_class", "state", "church", "children", "child_allowances", "parent", "birth_year", "health_insurance", "health_insurance_addon_rate", "factor", "annual_tax_allowance"], "conformance": "BMF wage-tax calculator interface (labelled cases for the PAP of each year)"},
    {"country": "UK", "name": "United Kingdom", "status": "available", "currency": "GBP", "years": [2025, 2026], "periods": ["year", "month", "week", "fortnight", "four_weeks"], "profile_fields": ["region", "tax_code", "ni_category", "period_number", "previous_pay", "previous_tax"], "conformance": "HMRC software developers payroll test data (PAYE and Class 1 NICs), every row"},
    {"country": "AT", "name": "Austria", "status": "planned", "currency": "EUR", "years": [], "periods": [], "profile_fields": [], "conformance": "BMF Brutto-Netto-Rechner cases"},
    {"country": "US", "name": "United States (federal + FICA)", "status": "planned", "currency": "USD", "years": [], "periods": [], "profile_fields": [], "conformance": "IRS Publication 15-T worked examples"}
  ]
}

Errors and limits

Errors are JSON with a detail field. Failed calls are not charged.

Status When Example detail
400 Tax year not covered {"error": "unsupported_year", "message": "DE 2024 is not supported; available years: 2025, 2026"}
400 German Midijob/Minijob pay {"error": "unsupported_profile", "message": "Gross pay of about 1500.00 EUR per month falls into the Midijob (Übergangsbereich) range (up to 2000 EUR/month), which has special contribution rules this API does not support yet. Supported: more than 2000 EUR per month."}
400 Private health insurance {"error": "unsupported_profile", "message": "Private health insurance (PKV) is not supported yet; only statutory health insurance."}
400 Above retirement age (DE) {"error": "unsupported_profile", "message": "employees above the statutory retirement age have special social-insurance rules that this API does not support yet"}
400 Invalid UK tax code {"error": "invalid_input", "message": "tax code 'XYZ' is not a valid PAYE code (examples: 1257L, S1257L, C1257L, K475, BR, D0, NT, 0T, 1257L W1)"}
400 Period not used in that country {"error": "invalid_input", "message": "period must be year, month, week, fortnight or four_weeks for UK"}
400 Wrong profile for the country {"error": "invalid_input", "message": "The uk profile is not used for DE; send a de profile instead."}
401 No key sent {"error": "missing_api_key", "message": "Send your key in the X-API-Key header.", "buy_credits": "https://syntropicapi.com/pricing", "pay_per_call_x402": null}
401 Unknown key {"error": "invalid_api_key"}
402 Not enough credits {"error": "insufficient_credits", "top_up": "https://syntropicapi.com/pricing"}
422 Schema validation (unknown country, missing field, value out of range, unknown field) [{"type": "literal_error", "loc": ["body", "country"], "msg": "Input should be 'DE', 'UK' or 'GB'"}]

Limits:

  • gross up to 10,000,000 and net up to 5,000,000 per period.
  • /compare: 1–8 scenarios per call.
  • DE: gross pay above 2,000 EUR per month (or the equivalent for other periods), statutory health insurance, employees below the statutory retirement age.
  • UK: period_number up to the number of periods in the year (12 for monthly pay, 52 for weekly pay). Student loans, postgraduate loans, pensions, salary sacrifice and the Apprenticeship Levy are not deducted.
  • Employer cost for DE excludes the U1/U2 levies and statutory accident insurance (they depend on the employer's health fund and industry).
  • Quotas: a syntropicapi.com key is limited by its credits. On RapidAPI, your plan's quota applies.

Data sources, freshness and update policy

Country Source License
DE BMF: Programmablaufplan für die maschinelle Berechnung der Lohnsteuer 2025 and 2026 (https://www.bmf-steuerrechner.de/interface/pseudocodes.xhtml). We implemented the algorithm ourselves; no BMF file is redistributed Official work (§ 5 UrhG)
DE Sozialversicherungs-Rechengrößenverordnung 2025 and 2026 (contribution ceilings, Minijob and Midijob limits) and the official average health-insurance add-on rate Official legal text (§ 5 UrhG)
DE SGB V § 241/§ 242, SGB XI § 55, SGB VI § 158, SGB III § 341 (contribution rates); Kirchensteuergesetze der Länder (church-tax rates) Official legal text (§ 5 UrhG)
UK HMRC: PAYE tax table routines (exact percentage method) and rates and thresholds for employers; Scottish Rate Resolution; Class 1 National Insurance thresholds, rates and category letters Open Government Licence v3.0

Ground truth for the published accuracy numbers:

  • Germany: labelled cases from the BMF's wage-tax calculator interface, which the BMF provides for program testing. They were generated offline; the interface is never called at runtime.
  • UK: every row of HMRC's software developers payroll test data (PAYE and NICs), run through POST /net exactly as a customer would call it.

The rules and rates are built into the API, so responses are fast and deterministic and never depend on a third-party service. Every line names its source, and GET /parameters shows every value in use.

Update policy: each tax year is added as a new version and older years stay callable, so you can compare years and recalculate back pay. Germany changes every January (the BMF publishes the next year's PAP each autumn), the UK every April (HMRC publishes new test data before the tax year starts). New years are checked against the official test data before release, and the accuracy numbers on the API page are updated with them. Changes during a year (for example a new PAP mid-year) are applied when they are published.

Changelog

Every change to this API is listed in its public, signed and timestamped dev log: https://syntropicapi.com/apis/salary-net/devlog

Try it in the playground →