HMRC API client library

The United Kingdom tax authority (HMRC) provides a set of RESTful APIs for managing tax affairs. These APIs can be used to view tax accounts, submit tax returns, confirm receipt of payments, and so forth.

As of April 2019, use of these APIs is mandatory for Value Added Tax (VAT). There is no longer any way for most taxpayers to submit VAT returns via the HMRC web site.

A VAT return submitted via the VAT API is essentially a JSON representation of the HTML form previously used on the HMRC web site (which itself was simply a transcription of the old paper VAT100 form). For example:

  "periodKey": "A001",
  "vatDueSales": 105.50,
  "vatDueAcquisitions": -100.45,
  "totalVatDue": 5.05,
  "vatReclaimedCurrPeriod": 105.15,
  "netVatDue": 100.10,
  "totalValueSalesExVAT": 300,
  "totalValuePurchasesExVAT": 300,
  "totalValueGoodsSuppliedExVAT": 3000,
  "totalAcquisitionsExVAT": 3000,
  "finalised": true

This JSON representation is submitted via HTTP POST to the VAT submission endpoint at{vrn}/returns. Other endpoints allow for retrieving the list of open and fulfilled VAT returns, for retrieving the details of an already-submitted VAT return, and for viewing payments received by HMRC.

The hmrc module can be used to interact with the HMRC APIs in a Pythonic way. For example:

>>> from datetime import date
>>> import webbrowser
>>> from hmrc.auth import HmrcSession
>>> from hmrc.api.vat import VatClient, VatObligationStatus

>>> session = HmrcSession(client_id, client_secret=client_secret)
>>> vat = VatClient(session, vrn='195036945')

>>> session.fetch_token(code=input("Enter OAuth2 authorization code:"))
Enter OAuth2 authorization code:

>>> start = date(2018, 1, 1)
>>> end = date(2018, 12, 31)
>>> obligations = vat.obligations(from_=start, to=end)
>>> print(obligations)
VatObligations(obligations=[VatObligation(start=..., ...), ...])

>>> fulfilled = [x for x in obligations.obligations
...              if x.status == VatObligationStatus.FULFILLED]

>>> print(vat.retrieve(period_key=fulfilled[0].period_key))

Indices and tables