Free, no API key, no rate-limited tiers — the same math ten of TaxLane's eleven calculators use, as a JSON API. (Payroll is the one exception — its CSV-upload flow is inherently a batch of calculations, not this API's one-request-one-calculation contract.)
Calculates PAYE tax exactly the way the PAYE calculator does. Only grossAnnualIncome is required — every other field defaults to 0.
curl -X POST https://api.taxlane.ng/v1/paye \
-H "content-type: application/json" \
-d '{"grossAnnualIncome": 6000000, "annualRentPaid": 1200000}'| Field | Details |
|---|---|
grossAnnualIncome | Type numberRequired YesDefault — |
secondaryAnnualIncome | Type numberRequired NoDefault 0 |
annualRentPaid | Type numberRequired NoDefault 0 |
terminationBenefit | Type numberRequired NoDefault 0 |
pensionContribution | Type numberRequired NoDefault 0 |
nhfContribution | Type numberRequired NoDefault 0 |
nhisContribution | Type numberRequired NoDefault 0 |
lifeAssurancePremiumContribution | Type numberRequired NoDefault 0 |
The full PAYE result: taxableIncome, payeTax, annualTax, monthlyTax, a reliefs breakdown, and a bandBreakdown array showing how much tax fell in each band.
{
"taxableIncome": 6000000,
"payeTax": 870000,
"annualTax": 870000,
"monthlyTax": 72500,
"reliefs": {
"rentRelief": 0,
"pensionRelief": 0,
"nhfRelief": 0,
"nhisRelief": 0,
"lifeAssurancePremiumRelief": 0,
"minimumWageExempt": false,
"taxableTerminationBenefit": 0
},
"bandBreakdown": [
{ "from": 800000, "to": 3000000, "rate": 0.15, "taxInBand": 330000 },
{ "from": 3000000, "to": 6000000, "rate": 0.18, "taxInBand": 540000 }
]
}Calculates PAYE for a whole payroll run in one request — an array of up to 1,000 employees, each the same shape /v1/paye takes. results[i] is exactly what /v1/paye would have returned for employees[i], in the same order — there is no employee identifier field, so correlate by index. An invalid item 400s the whole batch, prefixed employees[i]. so you can find the failing row; there is no partial-success mode.
curl -X POST https://api.taxlane.ng/v1/payroll/batch \
-H "content-type: application/json" \
-d '{"employees": [{"grossAnnualIncome": 6000000}, {"grossAnnualIncome": 900000, "annualRentPaid": 400000}]}'| Field | Details |
|---|---|
employees | Type PayeInput[] (1–1000 items)Required YesDefault — |
results: an array of PAYE results, one per employee, in request order.
{
"results": [
{
"taxableIncome": 6000000,
"payeTax": 870000,
"annualTax": 870000,
"monthlyTax": 72500,
"reliefs": {
"rentRelief": 0,
"pensionRelief": 0,
"nhfRelief": 0,
"nhisRelief": 0,
"lifeAssurancePremiumRelief": 0,
"minimumWageExempt": false,
"taxableTerminationBenefit": 0
},
"bandBreakdown": [
{ "from": 800000, "to": 3000000, "rate": 0.15, "taxInBand": 330000 },
{ "from": 3000000, "to": 6000000, "rate": 0.18, "taxInBand": 540000 }
]
},
{
"taxableIncome": 820000,
"payeTax": 3000,
"annualTax": 3000,
"monthlyTax": 250,
"reliefs": {
"rentRelief": 80000,
"pensionRelief": 0,
"nhfRelief": 0,
"nhisRelief": 0,
"lifeAssurancePremiumRelief": 0,
"minimumWageExempt": false,
"taxableTerminationBenefit": 0
},
"bandBreakdown": [
{ "from": 800000, "to": 820000, "rate": 0.15, "taxInBand": 3000 }
]
}
]
}Calculates VAT exactly the way the VAT calculator does, at the standard 7.5% rate.
curl -X POST https://api.taxlane.ng/v1/vat \
-H "content-type: application/json" \
-d '{"amount": 100000, "mode": "exclusive"}'| Field | Details |
|---|---|
amount | Type numberRequired YesDefault — |
mode | Type "exclusive" | "inclusive"Required YesDefault — |
zeroRated | Type booleanRequired NoDefault false |
net, vat, and gross amounts.
{
"net": 100000,
"vat": 7500,
"gross": 107500
}Calculates Presumptive Tax exactly the way the Presumptive Tax calculator does. turnover is the only field.
curl -X POST https://api.taxlane.ng/v1/presumptive \
-H "content-type: application/json" \
-d '{"turnover": 20000000}'| Field | Details |
|---|---|
turnover | Type numberRequired YesDefault — |
turnover, taxOwed, belowFloor, monthlySetAside, and turnoverToFloor.
{
"turnover": 20000000,
"taxOwed": 200000,
"belowFloor": false,
"monthlySetAside": 16666.666666666668,
"turnoverToFloor": 0
}Calculates Direct Assessment tax exactly the way the Direct Assessment calculator does. turnover and allowableExpenses are required; capital allowance fields default to no capital expenditure.
curl -X POST https://api.taxlane.ng/v1/direct-assessment \
-H "content-type: application/json" \
-d '{"turnover": 10000000, "allowableExpenses": 3000000, "qualifyingCapitalExpenditure": 1000000, "capitalAllowanceAssetClass": "plantAgriculturalEquipmentFurniture"}'| Field | Details |
|---|---|
turnover | Type numberRequired YesDefault — |
allowableExpenses | Type numberRequired YesDefault — |
qualifyingCapitalExpenditure | Type numberRequired NoDefault 0 |
capitalAllowanceAssetClass | Type "buildingAgriculturalMastIntangibleHeavyTransport" | "plantAgriculturalEquipmentFurniture" | "motorVehicleSoftware"Required NoDefault "buildingAgriculturalMastIntangibleHeavyTransport" |
turnover, allowableExpenses, capitalAllowance, taxableProfit, taxOwed, and effectiveRate.
{
"turnover": 10000000,
"allowableExpenses": 3000000,
"capitalAllowance": 200000,
"taxableProfit": 6800000,
"taxOwed": 1014000,
"effectiveRate": 0.14911764705882352
}Calculates Companies Income Tax exactly the way the CIT calculator does. Eligibility fields (turnover, fixedAssets, isProfessionalServices) are always required and always returned under eligibility. standardRate is included only when taxableProfit is sent; developmentLevy is included only when assessableProfit is sent — the three are independently computed, not a single pipeline.
curl -X POST https://api.taxlane.ng/v1/cit \
-H "content-type: application/json" \
-d '{"turnover": 30000000, "fixedAssets": 100000000, "isProfessionalServices": false, "taxableProfit": 5000000, "assessableProfit": 8000000}'| Field | Details |
|---|---|
turnover | Type numberRequired YesDefault — |
fixedAssets | Type numberRequired YesDefault — |
isProfessionalServices | Type booleanRequired YesDefault — |
taxableProfit | Type numberRequired NoDefault omitted → standardRate omitted from response |
assessableProfit | Type numberRequired NoDefault omitted → developmentLevy omitted from response |
eligibility always; standardRate and developmentLevy only when their triggering field was sent.
{
"eligibility": {
"turnover": 30000000,
"fixedAssets": 100000000,
"isProfessionalServices": false,
"turnoverEligible": true,
"fixedAssetsEligible": true,
"eligible": true,
"rate": 0
},
"standardRate": { "taxableProfit": 5000000, "annualTax": 1500000 },
"developmentLevy": { "assessableProfit": 8000000, "developmentLevy": 320000 }
}Calculates Withholding Tax exactly the way the WHT calculator does. Set mode to "gross" if amount is the invoice figure, or "net" if amount is the figure the payee should receive after withholding.
curl -X POST https://api.taxlane.ng/v1/wht \
-H "content-type: application/json" \
-d '{"transactionType": "professionalFees", "amount": 1000000, "mode": "gross"}'| Field | Details |
|---|---|
transactionType | Type "professionalFees" | "technicalServices" | "rent" | "generalContracts" | "dividends" | "interest" | "royalties"Required YesDefault — |
amount | Type numberRequired YesDefault — |
mode | Type "gross" | "net"Required YesDefault — |
transactionType, mode, amount, rate, gross, withheld, and net.
{
"transactionType": "professionalFees",
"mode": "gross",
"amount": 1000000,
"rate": 0.05,
"gross": 1000000,
"withheld": 50000,
"net": 950000
}Calculates total employer cost exactly the way the Employer Cost calculator does. Only annualBasicSalary is required — every allowance defaults to 0.
curl -X POST https://api.taxlane.ng/v1/employer-cost \
-H "content-type: application/json" \
-d '{"annualBasicSalary": 6000000, "annualHousingAllowance": 1000000, "annualTransportAllowance": 500000}'| Field | Details |
|---|---|
annualBasicSalary | Type numberRequired YesDefault — |
annualHousingAllowance | Type numberRequired NoDefault 0 |
annualTransportAllowance | Type numberRequired NoDefault 0 |
annualOtherAllowances | Type numberRequired NoDefault 0 |
annualRentPaid | Type numberRequired NoDefault 0 |
annualGrossPay, pensionablePay, the four statutory employer contributions, totalStatutoryEmployerCost, and a nested employeePaye object — the same shape /v1/paye returns, informational only.
{
"annualGrossPay": 7500000,
"pensionablePay": 7500000,
"employerPensionContribution": 750000,
"employerNhisContribution": 600000,
"employerNsitfContribution": 75000,
"employerItfContribution": 75000,
"totalStatutoryEmployerCost": 9000000,
"employeePaye": {
"taxableIncome": 6600000,
"payeTax": 978000,
"annualTax": 978000,
"monthlyTax": 81500,
"reliefs": {
"rentRelief": 0,
"pensionRelief": 600000,
"nhfRelief": 0,
"nhisRelief": 300000,
"lifeAssurancePremiumRelief": 0,
"minimumWageExempt": false,
"taxableTerminationBenefit": 0
},
"bandBreakdown": [
{ "from": 800000, "to": 3000000, "rate": 0.15, "taxInBand": 330000 },
{ "from": 3000000, "to": 6600000, "rate": 0.18, "taxInBand": 648000 }
]
}
}Calculates Capital Gains Tax exactly the way the CGT calculator does. digitalAssetCategory is required when assetType is "digital-asset", and ignored otherwise — every other conditional field is optional and only applies to its matching assetType/taxpayerType.
curl -X POST https://api.taxlane.ng/v1/cgt \
-H "content-type: application/json" \
-d '{"taxpayerType": "individual", "assetType": "property", "disposalProceeds": 50000000, "costBase": 30000000}'| Field | Details |
|---|---|
taxpayerType | Type "individual" | "company"Required YesDefault — |
assetType | Type "property" | "shares" | "digital-asset" | "other"Required YesDefault — |
disposalProceeds | Type numberRequired YesDefault — |
costBase | Type numberRequired YesDefault — |
isPrincipalPrivateResidence | Type booleanRequired NoDefault false (property only) |
isFullyReinvestedInNigerianShares | Type booleanRequired NoDefault false (shares only) |
isRegulatedSecuritiesLendingTransfer | Type booleanRequired NoDefault false (shares only) |
digitalAssetCategory | Type "crypto" | "stablecoin" | "security-token" | "utility-token" | "nft" | "sovereign-digital-currency"Required NoDefault required when assetType is "digital-asset", ignored otherwise |
otherAnnualTaxableIncome | Type numberRequired NoDefault 0 (individual only) |
isSmallCompany | Type booleanRequired NoDefault false (company only) |
chargeableGain, exempt, exemptReason (only when exempt), cgtLiability, and vaWithholdingEstimate (digital assets only, categories with a 1% disposal withholding).
{
"chargeableGain": 20000000,
"exempt": false,
"cgtLiability": 3630000
}Calculates Stamp Duty exactly the way the Stamp Duty calculator does.
curl -X POST https://api.taxlane.ng/v1/stamp-duty \
-H "content-type: application/json" \
-d '{"instrumentType": "tenancy", "amount": 12000000}'| Field | Details |
|---|---|
instrumentType | Type "tenancy" | "propertyConveyance" | "shareCapital" | "loanCapital" | "marketableSecurities" | "electronicTransfer" | "other"Required YesDefault — |
amount | Type numberRequired YesDefault — |
instrumentType, amount, rate (null for the two fixed-fee instrument types), duty, and exempt.
{
"instrumentType": "tenancy",
"amount": 12000000,
"rate": 0.0078,
"duty": 93600,
"exempt": false
}Calculates import duty and landed cost exactly the way the Import Duty calculator does. Pass freight and insurance as 0 (their default) if you already have a combined CIF value in fob.
curl -X POST https://api.taxlane.ng/v1/import-duty \
-H "content-type: application/json" \
-d '{"fob": 5000000, "freight": 300000, "insurance": 100000, "band": "20"}'| Field | Details |
|---|---|
fob | Type numberRequired YesDefault — |
freight | Type numberRequired NoDefault 0 |
insurance | Type numberRequired NoDefault 0 |
band | Type "0" | "5" | "10" | "20" | "35"Required YesDefault — |
customDutyRatePercent | Type numberRequired NoDefault omitted → band rate applies |
fob, freight, insurance, cif, band, dutyRate, duty, surcharge, etls, fcs, vat, and totalLandedCost.
{
"fob": 5000000,
"freight": 300000,
"insurance": 100000,
"cif": 5400000,
"band": "20",
"dutyRate": 0.2,
"duty": 1080000,
"surcharge": 75600,
"etls": 27000,
"fcs": 200000,
"vat": 508695,
"totalLandedCost": 7291295
}Projects RSA pension balances exactly the way the Pension (RSA) Contribution calculator does. Only annualBasicSalary is required — every other field defaults to the value the calculator itself starts with.
curl -X POST https://api.taxlane.ng/v1/pension-contribution \
-H "content-type: application/json" \
-d '{"annualBasicSalary": 3000000, "yearsToProject": 10}'| Field | Details |
|---|---|
annualBasicSalary | Type numberRequired YesDefault — |
annualHousingAllowance | Type numberRequired NoDefault 0 |
annualTransportAllowance | Type numberRequired NoDefault 0 |
voluntaryContribution | Type numberRequired NoDefault 0 |
currentRsaBalance | Type numberRequired NoDefault 0 |
yearsToProject | Type numberRequired NoDefault 10 (clamped to 50) |
assumedAnnualGrowthRate | Type numberRequired NoDefault 0.07 |
pensionablePay, employeeContribution, employerContribution, voluntaryContribution, totalAnnualContribution, and projection (an array of { year, balance }, one entry per year from 0 to yearsToProject).
{
"pensionablePay": 3000000,
"employeeContribution": 240000,
"employerContribution": 300000,
"voluntaryContribution": 0,
"totalAnnualContribution": 540000,
"projection": [
{ "year": 0, "balance": 0 },
{ "year": 1, "balance": 577800 },
{ "year": 2, "balance": 1196046 },
{ "year": 3, "balance": 1857569 },
{ "year": 4, "balance": 2565399 },
{ "year": 5, "balance": 3322777 },
{ "year": 6, "balance": 4133171 },
{ "year": 7, "balance": 5000293 },
{ "year": 8, "balance": 5928114 },
{ "year": 9, "balance": 6920882 },
{ "year": 10, "balance": 7983144 }
]
}Calculates National Housing Fund contributions exactly the way the NHF Contribution calculator does.
curl -X POST https://api.taxlane.ng/v1/nhf-contribution \
-H "content-type: application/json" \
-d '{"annualBasicSalary": 3000000}'| Field | Details |
|---|---|
annualBasicSalary | Type numberRequired YesDefault — |
annualBasicSalary, annualNhfContribution, and monthlyNhfContribution.
{
"annualBasicSalary": 3000000,
"annualNhfContribution": 75000,
"monthlyNhfContribution": 6250
}A missing or non-numeric required field returns 400 with an error message — every endpoint uses this same shape, with a field-specific message. This is the real body /v1/paye returns for a request missing grossAnnualIncome:
{
"error": "grossAnnualIncome is required and must be a number"
}An unknown route returns 404. Its message key (not error) isn't inconsistent by accident — it's API Gateway's own default reject body for a route that was never registered, returned before the request ever reaches our code.
{
"message": "Not Found"
}Exceeding the shared rate limit returns 429 with the same message shape as the 404 above, plus the Retry-After header described under Limits below.
{
"message": "Too Many Requests"
}Negative numbers are not rejected — they're clamped internally, matching the calculator UI's own behavior for the same input.
No API key required, no daily cap. Requests are limited to 50 per second (100 burst) at the shared Gateway level to keep the service available for everyone. Every response carries X-RateLimit-Limit/X-RateLimit-Remaining/X-RateLimit-Reset headers (plus Retry-After on a 429) so you can see how close you are to that ceiling and back off proactively — except for the narrow slice of requests Gateway rejects before ever reaching our code, which stay header-less (a platform limitation, not something we can add headers to).
For guidance only — not tax advice.
Run a WordPress site? The free TaxLane Nigeria Tax Calculators plugin drops any TaxLane calculator onto a page or post with one shortcode — no API key, no code.
TaxLane Nigeria Tax Calculators
Install via Plugins → Add New → Upload Plugin in your WordPress admin, activate it, then add [taxlane_calculator type="paye"] (or any calculator id listed on the plugin's own settings page) to any page or post.
Prefer a machine-readable spec? Download the OpenAPI document — importable directly into Postman, Insomnia, or Swagger UI via "Import → Link".