Skip to main content

taxlane

Official Python SDK for TaxLane's free Developer API — PAYE, VAT, Withholding Tax, Companies Income Tax, Capital Gains Tax, and 5 more Nigeria tax calculators, as typed function calls instead of hand-written urllib/curl.

  • Zero runtime dependencies — stdlib urllib.request, no requests.
  • snake_case keyword arguments, hand-mapped from the same field list taxlane.ng/developers documents, so a call can never drift from the live API's request shape.
  • No API key, no account, no rate-limit tiers to configure — the API itself has none.

Every function returns the parsed JSON response as a plain dict, not a generated type — see Response shape below for why.

Install

pip install taxlane

If this package hasn't been published to the public PyPI registry yet (see Distribution below), install it straight from GitHub instead:

pip install git+https://github.com/quineworks/tax-lane#subdirectory=sdk-python

Quickstart

from taxlane import calculate_paye

result = calculate_paye(gross_annual_income=6_000_000, annual_rent_paid=1_200_000)
# {'taxableIncome': 5760000, 'payeTax': 826800, 'annualTax': 826800, 'monthlyTax': 68900,
#  'reliefs': {...}, 'bandBreakdown': [...]}

Every function raises TaxLaneApiError (with .message and .status) on a non-200 response, and accepts an optional trailing base_url keyword to point at a local/staging API instead of the production default:

from taxlane import calculate_paye, TaxLaneApiError

try:
    calculate_paye(gross_annual_income='not a number', base_url='http://localhost:3000')
except TaxLaneApiError as err:
    print(err.status, err.message)  # 400 "grossAnnualIncome is required and must be a number"

Endpoints

calculate_paye

from taxlane import calculate_paye

calculate_paye(gross_annual_income=6_000_000, annual_rent_paid=1_200_000)
# {
#   "taxableIncome": 5760000,
#   "payeTax": 826800,
#   "annualTax": 826800,
#   "monthlyTax": 68900,
#   "reliefs": { "rentRelief": 240000, "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": 5760000, "rate": 0.18, "taxInBand": 496800 }
#   ]
# }

Only gross_annual_income is required — every other field defaults to 0.

calculate_payroll_batch

from taxlane import calculate_payroll_batch

calculate_payroll_batch([
    {"grossAnnualIncome": 6_000_000},
    {"grossAnnualIncome": 900_000, "annualRentPaid": 400_000},
])
# { "results": [ { "taxableIncome": 6000000, ... }, { "taxableIncome": 820000, ... } ] }

Calculates PAYE for up to 1,000 employees in one request — results[i] is exactly what calculate_paye(**employees[i]) would return, in the same order. An invalid item raises with an employees[i].-prefixed message; there's no partial-success mode.

calculate_vat

from taxlane import calculate_vat

calculate_vat(amount=100_000, mode="exclusive")
# { "net": 100000, "vat": 7500, "gross": 107500 }

calculate_presumptive

from taxlane import calculate_presumptive

calculate_presumptive(turnover=20_000_000)
# { "turnover": 20000000, "taxOwed": 200000, "belowFloor": false, "monthlySetAside": 16666.666666666668, "turnoverToFloor": 0 }

calculate_direct_assessment

from taxlane import calculate_direct_assessment

calculate_direct_assessment(
    turnover=10_000_000,
    allowable_expenses=3_000_000,
    qualifying_capital_expenditure=1_000_000,
    capital_allowance_asset_class="plantAgriculturalEquipmentFurniture",
)
# { "turnover": 10000000, "allowableExpenses": 3000000, "capitalAllowance": 200000, "taxableProfit": 6800000, "taxOwed": 1014000, "effectiveRate": 0.14911764705882352 }

calculate_cit

from taxlane import calculate_cit

calculate_cit(
    turnover=30_000_000,
    fixed_assets=100_000_000,
    is_professional_services=False,
    taxable_profit=5_000_000,
    assessable_profit=8_000_000,
)
# {
#   "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 }
# }

eligibility is always returned. standardRate is included only when taxable_profit is sent; developmentLevy is included only when assessable_profit is sent — the three are independently computed.

calculate_wht

from taxlane import calculate_wht

calculate_wht(transaction_type="professionalFees", amount=1_000_000, mode="gross")
# { "transactionType": "professionalFees", "mode": "gross", "amount": 1000000, "rate": 0.05, "gross": 1000000, "withheld": 50000, "net": 950000 }

calculate_employer_cost

from taxlane import calculate_employer_cost

calculate_employer_cost(
    annual_basic_salary=6_000_000,
    annual_housing_allowance=1_000_000,
    annual_transport_allowance=500_000,
)
# { "annualGrossPay": 7500000, "pensionablePay": 7500000, "employerPensionContribution": 750000, ..., "employeePaye": { ... } }

calculate_cgt

from taxlane import calculate_cgt

calculate_cgt(
    taxpayer_type="individual",
    asset_type="property",
    disposal_proceeds=50_000_000,
    cost_base=30_000_000,
)
# { "chargeableGain": 20000000, "exempt": false, "cgtLiability": 3630000 }

digital_asset_category is required when asset_type is "digital-asset", ignored otherwise.

calculate_stamp_duty

from taxlane import calculate_stamp_duty

calculate_stamp_duty(instrument_type="tenancy", amount=12_000_000)
# { "instrumentType": "tenancy", "amount": 12000000, "rate": 0.0078, "duty": 93600, "exempt": false }

calculate_import_duty

from taxlane import calculate_import_duty

calculate_import_duty(fob=5_000_000, freight=300_000, insurance=100_000, band="20")
# { "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 }

Response shape

Every function returns the parsed JSON response body as a plain dict, not a generated dataclass/TypedDict/pydantic model. The JS/TS SDK's fully-typed responses come free by importing the real TS type across a same-language package boundary — Python has no equivalent import, and hand-duplicating every response shape in a second, Python-only schema would be exactly the kind of extra place to maintain and drift from that SDK avoided in the first place. A plain dict is also the established pattern Paystack's (paystack-python) and Flutterwave's (rave-python) own Python SDKs use for response bodies. Ships py.typed (PEP 561 marker) so type checkers (mypy/pyright) still pick up every function's request signature in consuming projects — only the response is untyped.

Errors

A missing or non-numeric/non-boolean required field, or an invalid enum value, raises TaxLaneApiError with a .status of 400 and a .message describing the offending field. See the full field-by-field reference at taxlane.ng/developers or the OpenAPI spec.

Limits

No API key required, no daily cap. The underlying API is limited to 50 requests/second (100 burst) at the shared Gateway level to keep the service available for everyone — this SDK does no client-side retry/backoff, since there's no rate limit to work around on a per-caller basis.

Distribution

Published to the public PyPI registry as taxlane, when a fleet PyPI publisher account exists to publish it under. Until then, install directly from this repo's sdk-python/ subdirectory:

pip install git+https://github.com/quineworks/tax-lane#subdirectory=sdk-python

License

MIT — see the repo root LICENSE.

Metadata

Release files for taxlane 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for taxlane 0.1.0
File Size Uploaded Provenance Actions
taxlane-0.1.0.tar.gz 15.8 kB Without provenance Details for taxlane-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for taxlane 0.1.0
File Interpreter ABI Platform Actions
taxlane-0.1.0-py3-none-any.whl Python 3 none any Details for taxlane-0.1.0-py3-none-any.whl

Total release size: 31.3 kB

Release files / taxlane-0.1.0.tar.gz

Download URL taxlane-0.1.0.tar.gz
Size 15.8 kB
Tags Source
SHA-256 checksum
How to use checksums
bf06120743577f5c3a361debf2a84506ec6513fa6a91fffd389a8c6aff61b054
BLAKE2b-256 checksum
How to use checksums
a388757fc7ca83e8fde1959928ea539d104c6610dbbb3e3365c14f8a8a1d0425
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / taxlane-0.1.0-py3-none-any.whl

Download URL taxlane-0.1.0-py3-none-any.whl
Size 15.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6d880f25b2ba903c2dc9b0d07aa5d76f5e9c37c1acd6924f1a379ada79a83e15
BLAKE2b-256 checksum
How to use checksums
bf9bd817d531e3061497a15631b66fc1acb335a71a2aea72c664c68a6cc5fdbd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Security for taxlane 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page