Skip to main content

Package version Python versions License Ruff py.typed Coverage Status

Hero

A Python library for the Monzo Developer API.

📖 View Full Documentation

Features

  • 📦 Trusted PyPI publishing
  • 🌐 Full Monzo API coverage
  • 🔐 Simple OAuth2 authentication flow
  • 🔒 Type-safe with Pydantic models
  • ⚡ Async/await support with httpx
  • ✅ Well-tested and documented
  • ⚠️ Comprehensive error handling

Installation

uv add monzoh

Quick Start

  1. Create an OAuth2 client on the Monzo Developers Portal. Redirect URL must be http://localhost:8080/callback and Confidentiality must be Confidential.
  2. Run monzo-auth and complete the login flow.
  3. Authorise access on the Monzo app.

You can now use the API:

from monzoh import MonzoClient

client = MonzoClient() # Uses cached access token and handles refresh

account = client.accounts.list()[0]
balance = account.get_balance()
print(f"Balance: £{balance.balance}")

transactions = account.list_transactions(limit=10)
for transaction in transactions:
    if transaction.amount < -50:  # Transactions over £50
        transaction.annotate({"notes": "#large_expense"})

transactions[0].upload_attachment("image.jpg")

pots = account.list_pots()
for pot in pots:
    if pot.name == "Savings":
        pot.deposit(10.00)
        break

Asynchronous API

import asyncio
from monzoh import AsyncMonzoClient

async def main():
    async with AsyncMonzoClient() as client:
        account = (await client.accounts.list())[0]
        
        balance = await account.aget_balance()
        print(f"Balance: £{balance.balance}")
        
        transactions = await account.alist_transactions(limit=10)
        for transaction in transactions:
            if transaction.amount < -50:
                await transaction.aannotate({"notes": "#large_expense"})
        
        pots = await account.alist_pots()
        for pot in pots:
            if pot.name == "Savings":
                await pot.adeposit(10.00)
                break

asyncio.run(main())

Why not call the API directly?

It's much simpler with Monzoh! As an example, here's what uploading an attachment looks like, compared with using the API directly:

With monzoh

from monzoh import MonzoClient

client = MonzoClient()
account = client.accounts.list()[0]
transaction = account.list_transactions(limit=1)[0]
attachment = transaction.upload_attachment("receipt.jpg")

Without monzoh

import requests
from pathlib import Path

accounts_response = requests.get(
    "https://api.monzo.com/accounts",
    headers={"Authorization": f"Bearer {access_token}"}
)
account_id = accounts_response.json()["accounts"][0]["id"]

transactions_response = requests.get(
    "https://api.monzo.com/transactions",
    headers={"Authorization": f"Bearer {access_token}"},
    params={"account_id": account_id, "limit": 1}
)
transaction_id = transactions_response.json()["transactions"][0]["id"]

response = requests.post(
    "https://api.monzo.com/attachment/upload",
    headers={"Authorization": f"Bearer {access_token}"},
    data={
        "file_name": "receipt.jpg",
        "file_type": "image/jpeg",
        "content_length": str(len(Path("receipt.jpg").read_bytes()))
    }
)
upload_info = response.json()

file_data = Path("receipt.jpg").read_bytes()
requests.put(
    upload_info["upload_url"], 
    data=file_data,
    headers={
        "Content-Type": "image/jpeg",
        "Content-Length": str(len(file_data))
    }
)

requests.post(
    "https://api.monzo.com/attachment/register",
    headers={"Authorization": f"Bearer {access_token}"},
    data={
        "external_id": transaction_id,
        "file_url": upload_info["file_url"],
        "file_type": "image/jpeg"
    }
)

Release files for monzoh 1.2.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 monzoh 1.2.0
File Size Uploaded
monzoh-1.2.0.tar.gz 5.2 MB Details

Built distribution (wheel)

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

Total release size:5.2 MB

Release files / monzoh-1.2.0.tar.gz

Download URL monzoh-1.2.0.tar.gz
Size 5.2 MB
Tags Source
SHA-256 checksum
How to use checksums
0a38fc07428e15e395b7dbc92cb0ef4fb7de8bd57ae91bd93e4a9f179f033d7f
BLAKE2b-256 checksum
How to use checksums
0a9bcfd0c78c6f6dec744ab7b90073a7fc545909bd91c4fd39d448f48e03f996
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2025.

Transparency log

Release files / monzoh-1.2.0-py3-none-any.whl

Download URL monzoh-1.2.0-py3-none-any.whl
Size 51.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06675f040e86285e486b602d9a3ae342571c450676ba590c751b2923e3cfbbdb
BLAKE2b-256 checksum
How to use checksums
5e2c7ddaf8aa87587ae43fb293f5926f8f1ab4501a64e2bda6b6eed5774fe342
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.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