Skip to main content

VAT Sense Python SDK

PyPI version

The official Python library for the VAT Sense REST API. Validate VAT/EORI numbers, look up VAT/GST rates, calculate prices, convert currencies, and generate VAT-compliant invoices.

Includes type definitions for all request params and response fields, and offers both synchronous and asynchronous clients powered by httpx.

Installation

pip install vatsense

Requires Python 3.9+.

Quick start

Create a client using your API key from the VAT Sense dashboard. The API uses HTTP Basic Auth with user as the username and your API key as the password.

from vat_sense import VatSense

client = VatSense(
    username="user",
    password="your_api_key",
)

You can also set the VAT_SENSE_USERNAME and VAT_SENSE_PASSWORD environment variables and the client will pick them up automatically.

Validate a VAT number

response = client.validate.check(vat_number="GB288305674")

if response.data.valid:
    print(response.data.company.company_name)     # "BRITISH BROADCASTING CORPORATION"
    print(response.data.company.company_address)
    print(response.data.company.country_code)      # "GB"

VAT validation works for the UK, EU, Australia, Norway, Switzerland, South Africa, and Brazil.

Validate an EORI number

response = client.validate.check(eori_number="GB123456789000")

if response.data.valid:
    print(response.data.company.company_name)

EORI validation is available for UK and EU numbers only.

Get a consultation number

If you need an official consultation number from VIES (EU) or HMRC (UK), provide your own VAT number as the requester:

response = client.validate.check(
    vat_number="FR12345678901",
    requester_vat_number="FR98765432101",
)

print(response.data.consultation_number)

Note: GB requester numbers only work for GB validations, and EU requester numbers only work for EU validations. Cross-region requests are not supported.

Find the VAT rate for a country

rate = client.rates.find(country_code="DE")

print(rate.data.country_name)       # "Germany"
print(rate.data.tax_rate.rate)      # 19.0
print(rate.data.tax_rate.class_)    # "standard"

Find a rate for a specific product type

rate = client.rates.find(country_code="DE", type="ebooks")

print(rate.data.tax_rate.rate)      # 7.0
print(rate.data.tax_rate.class_)    # "reduced"

Find a rate by IP address

Useful for determining the correct rate based on your customer's location:

rate = client.rates.find(ip_address="185.86.151.11")

print(rate.data.country_code)       # "GB"
print(rate.data.tax_rate.rate)      # 20.0

Calculate a VAT-inclusive price

result = client.rates.calculate_price(
    price="100.00",
    tax_type="excl",
    country_code="FR",
)

print(result.data.vat_price.price_incl_vat)  # Price including VAT
print(result.data.vat_price.price_excl_vat)  # Price excluding VAT
print(result.data.vat_price.vat_rate)        # VAT rate applied
print(result.data.vat_price.vat)             # VAT amount

List all VAT rates

rates = client.rates.list()

for rate in rates.data:
    print(f"{rate.country_code}: {rate.country_name}")

# Filter to EU countries only
eu_rates = client.rates.list(eu=True)

Async usage

An async client is also available:

import asyncio
from vat_sense import AsyncVatSense

client = AsyncVatSense(
    username="user",
    password="your_api_key",
)

async def main():
    response = await client.validate.check(vat_number="GB288305674")
    print(response.data.valid)

asyncio.run(main())

Handling errors

When the API returns an error, the library raises a typed exception:

from vat_sense import VatSense, APIConnectionError, APIStatusError, RateLimitError

client = VatSense(username="user", password="your_api_key")

try:
    response = client.validate.check(vat_number="GB288305674")
except APIConnectionError:
    # Network issue, could not reach the API
    print("Connection failed")
except RateLimitError:
    # 429: Too many requests (300/min general limit, 3/sec for UK validation)
    print("Rate limited, try again shortly")
except APIStatusError as e:
    # Covers all other HTTP errors
    print(e.status_code)
    print(e.message)

A 412 error means the upstream validation service (VIES, HMRC, etc.) is temporarily unavailable. These requests do not count against your usage quota.

Status Code Error Type
400 BadRequestError
401 AuthenticationError
404 NotFoundError
409 ConflictError
429 RateLimitError
>= 500 InternalServerError
N/A APIConnectionError

Retries

Failed requests are automatically retried up to 2 times with exponential backoff. This includes connection errors, timeouts, 429, and 5xx responses.

# Disable retries
client = VatSense(username="user", password="your_api_key", max_retries=0)

# Or configure per request
response = client.validate.check(vat_number="GB288305674", timeout=5.0)

Available services

Service Description
client.validate Validate VAT and EORI numbers
client.rates VAT/GST rate lookups, price calculations
client.countries Country data and province lookups
client.currency Exchange rates and currency conversion
client.invoice Create and manage VAT-compliant invoices
client.usage Check your API usage

Documentation

Full API documentation is available at vatsense.com/documentation.

Versioning

This package follows SemVer conventions. As the library is in initial development and has a major version of 0, APIs may change at any time.

Contributing

See the contributing documentation.

Metadata

Release files for vatsense 0.6.1

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

Source distribution (sdist)

Source distribution for vatsense 0.6.1
File Size Uploaded
vatsense-0.6.1.tar.gz 244.3 kB Details

Built distribution (wheel)

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

Total release size: 363.9 kB

Release files / vatsense-0.6.1.tar.gz

Download URL vatsense-0.6.1.tar.gz
Size 244.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6651994ad01573261e7991b959b56f0dc9aaf389f4f6760032f395a3aadc176d
BLAKE2b-256 checksum
How to use checksums
78c57f5ff523441dcabc6c75c9c02706edaba12acb87996e60712980d483e884
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / vatsense-0.6.1-py3-none-any.whl

Download URL vatsense-0.6.1-py3-none-any.whl
Size 119.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
32e0d7031181de812d13975eacb23e2015387b0a8f78eaebeb2389256fbf91f3
BLAKE2b-256 checksum
How to use checksums
459fea799d3a205ba7bd9f9a47e129acc9fce57e04e562ac0843d3c9597df294
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.6.1 This release

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.0

2 release files

0.1.0

2 release files

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