# Azure Document Intelligence: Prebuilt Receipt Model

https://www.pexels.com/photo/person-using-a-computer-and-holding-a-credit-card-and-receipts-4968390/
https://www.pexels.com/photo/person-using-a-computer-and-holding-a-credit-card-and-receipts-4968390/

Introduction

The Azure Document Intelligence prebuilt receipt model extracts structured data from receipts without any model training. It identifies key information such as merchant name, transaction date, total amount, tax, and individual line items, which makes it straightforward to process and analyze receipt data.  This is a common need for businesses that automate expense tracking, accounting, and financial reporting. The prebuilt model saves time and reduces the errors that come with manual data entry. 

Under the hood, the service combines computer vision and machine learning to read the content of a receipt and return labeled fields. It handles a range of receipt formats, including printed and handwritten receipts, and adapts to different layouts and designs.

This post walks through using the prebuilt receipt model from Python: how to authenticate, send a file, and turn the raw response into a clean, typed data model. The full source code is available on GitHub: receipt-scanning

Prerequisites

To follow along, you need:

  • An Azure subscription with a Document Intelligence (or Azure AI Services) resource.
  • The resource endpoint, exposed through the AZURE_DOCUMENTINTELLIGENCE_ENDPOINT environment variable.
  • Python 3.13 or later.
  • The azure-ai-documentintelligence and azure-identity packages.

Python SDK

The Azure Document Intelligence Python SDK provides a convenient way to interact with the prebuilt receipt model. The SDK handles authentication, request formatting, and response parsing, so you can focus on the extracted data rather than the transport details.

Authentication uses DefaultAzureCredential, which works with your Azure CLI login during development and with managed identity in production. There are no API keys to manage

import os

from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.identity import DefaultAzureCredential


def _get_client() -> DocumentIntelligenceClient:
    endpoint = os.getenv("AZURE_DOCUMENTINTELLIGENCE_ENDPOINT")
    if not endpoint:
        raise ValueError(
            "AZURE_DOCUMENTINTELLIGENCE_ENDPOINT environment variable is not set."
        )

    return DocumentIntelligenceClient(
        endpoint=endpoint, credential=DefaultAzureCredential()
    )

Receipt Formats

Receipts serve many purposes, such as retail purchases, restaurant bills, and service invoices. The prebuilt receipt model handles a wide range of formats:
  • Printed receipts: the most common type, typically generated by point-of-sale   systems. They may include text, logos, and barcodes.
  • Handwritten receipts: common in small businesses or informal transactions. The   model recognizes and extracts information from handwritten text.
  • Digital receipts: generated electronically and delivered by email or mobile   apps. The model processes them as PDF or image files.

Scanning a Receipt

Scanning is a single call. Open the file in binary mode, submit it to the prebuilt-receipt model, and wait for the long-running operation to finish. The service can return more than one document per file, so the result is a list:
def scan_receipt(file_path) -> list[Receipt]:
    client = _get_client()

    with open(file_path, "rb") as f:
        poller = client.begin_analyze_document(
            "prebuilt-receipt",
            f,
            content_type="application/octet-stream",
        )

    result = poller.result()
    if not result.documents:
        return []

    return [
        receipt
        for document in result.documents
        if (receipt := _parse_field_value(document)) is not None
    ]

Working with the Extracted Fields

Each analyzed document exposes a fields dictionary. The values are typed: a currency field carries valueCurrency.amount, a number carries valueNumber, a date carries valueDate, and so on. One subtlety is that the SDK value objects behave like mappings but are not dict subclasses, so an isinstance(val, dict) check fails. Use hasattr(val, "get") instead when you need to reach into a nested value:
def _get_field_value(
    fields, field_name, prop_name="valueString", sub_prop_name=None
) -> float | None:
    field = fields.get(field_name)
    val = field.get(prop_name) if field else None

    if sub_prop_name and val is not None:
        val = val.get(sub_prop_name) if hasattr(val, "get") else None

    return round(val, 2) if isinstance(val, (int, float)) else None

Tax is a special case. Instead of a single field, the model returns a TaxDetails array, so the total tax is the sum of each entry's amount.

Modeling the Result

Raw fields are awkward to pass around, so the project maps them onto Pydantic models. This gives validation, type safety, and clean JSON serialization for free:
from pydantic import BaseModel

class ReceiptLineItem(BaseModel):
    description: str | None
    quantity: float | None
    unit_price: float | None
    price: float | None


class Receipt(BaseModel):
    receipt_type: str | None
    merchant: str | None
    merchant_address: str | None
    country: str | None
    transaction_date: str | None
    transaction_time: str | None
    subtotal: float | None
    total_tax: float | None
    total_amount: float | None
    line_items: list[ReceiptLineItem]

Running the Sample

The sample exposes a small command-line interface. Pass the receipt file with --file_name, and it prints the parsed result as JSON:
uv run python main.py --file_name groceries.jpg
uv run python main.py --file_name restaurant.pdf
The same code path works for .jpg, .png, and .pdf inputs because the content type is sent as application/octet-stream.

Demo

In the video below, we use the prebuilt receipt model to extract data from two receipts: one from a restaurant and one from a grocery store. The model extracts the merchant name, transaction date, total amount, and line items from both, which shows its versatility across different layouts.

video has no audio, and watch in full screen mode


Conclusion

The Azure Document Intelligence prebuilt receipt model is a practical tool for automating structured data extraction from receipts. With it, businesses can streamline expense tracking and accounting, reduce manual data-entry errors, and gain insight from receipt data more efficiently. The Python SDK keeps the integration small: authenticate with DefaultAzureCredential, submit a file, and map the typed fields onto your own models. Whether the input is a printed, handwritten, or digital receipt, the model helps you extract the information you need quickly and accurately.

Comments