---
title: Print and mail pricing calculator
description: Estimate how much it costs to print and mail a letter online. Upload a PDF for the exact page count, or enter page count and mailing options to see your total instantly.
seotitle: 'Print and mail cost calculator | PostalForm'
seo-description: 'Estimate how much it costs to print and mail a letter online. Upload a PDF or adjust pages, color, double-sided printing, USPS service level, and Certified Mail to see your total.'
group: resources
indexable: true
nav: true
schema: webpage
eyebrow: Pricing calculator
published: 2026-01-19T23:22:21-06:00
updated: 2026-03-30T00:00:00+00:00
path: /pricing-calculator
---
# Print and mail pricing calculator

Estimate how much it costs to print and mail a letter online. Upload a PDF for the exact page count, or enter page count and mailing options to see your total instantly.

## How the calculator works

- Start with the number of pages in your PDF.
- Choose black-and-white or color printing.
- Pick double-sided or single-sided printing.
- Select a USPS service level (First Class or Express) and optional Certified Mail.
- We show the estimated total, including printing, envelopes, and postage.

'''llm-only
# python
from decimal import Decimal, ROUND_CEILING, ROUND_HALF_UP


LOB_LIMITS = {
    False: 59,
    True: 118,
}

POSTGRID_LIMITS = {
    False: 199,
    True: 398,
}

CLICK2MAIL_LIMITS = {
    False: 99,
    True: 198,
}

STANDARD_BASE_FEE = Decimal("3.00")
STANDARD_BW_RATE = Decimal("0.20")
STANDARD_COLOR_RATE = Decimal("0.40")
STANDARD_OVER_6_SHEETS_FEE = Decimal("5.50")
STANDARD_TIER_ONE_THRESHOLD = Decimal("120")
STANDARD_TIER_TWO_THRESHOLD = Decimal("200")
STANDARD_TIER_ONE_FEE = Decimal("10.88")
STANDARD_TIER_TWO_FEE = Decimal("22.38")
STANDARD_CERTIFIED_FEE = Decimal("10.00")

CLICK2MAIL_POSTAGE = Decimal("11.95")
CLICK2MAIL_BW_BASE_PRODUCTION = Decimal("1.545")
CLICK2MAIL_BW_INCREMENTAL_PAGE_COST = Decimal("0.096")
CLICK2MAIL_COLOR_BASE_PRODUCTION = Decimal("1.987")
CLICK2MAIL_COLOR_INCREMENTAL_PAGE_COST = Decimal("0.408")
CLICK2MAIL_DUPLEX_DISCOUNT_PER_SHEET = Decimal("0.03")
CLICK2MAIL_ADDRESS_VERIFICATION_COST = Decimal("0.10")
CLICK2MAIL_STRIPE_FIXED_FEE = Decimal("0.30")
CLICK2MAIL_STRIPE_PERCENT_FEE = Decimal("0.03")
CLICK2MAIL_TARGET_PROFIT = Decimal("4.50")


def calculate_postalform_pricing(
    page_count: int,
    *,
    double_sided: bool = True,
    color: bool = False,
    mail_service: str = "first_class",
    certified: bool = False,
    signature_required: bool = False,
) -> dict:
    """
    Mirrors the PostalForm pricing calculator math for letter pricing.

    Inputs:
    - page_count: original PDF page count (not including the address page)
    - double_sided: True for duplex, False for single-sided
    - color: True for color print, False for black-and-white
    - mail_service: "first_class" (aka standard), "priority", or "express"
    - certified: Certified Mail add-on (only valid with first class)
    - signature_required: Adds signature confirmation for Express only
    """

    if page_count < 1:
        raise ValueError("page_count must be at least 1")

    normalized_service = (
        mail_service.strip().lower().replace("-", "_").replace(" ", "_")
    )
    if normalized_service in {"standard", "firstclass"}:
        normalized_service = "first_class"
    if normalized_service in {"priority", "expedited"}:
        normalized_service = "express"
    if normalized_service not in {"first_class", "express"}:
        raise ValueError('mail_service must be "first_class", "priority", or "express"')

    if certified and normalized_service != "first_class":
        raise ValueError(
            "Certified mail can't be combined with Express. "
            "Certified is only available with First Class."
        )

    if signature_required and normalized_service != "express":
        raise ValueError("Signature confirmation is only available with Express.")

    def money(value: Decimal) -> Decimal:
        return value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)

    def round_up_to_cent(value: Decimal) -> Decimal:
        return (value * Decimal("100")).to_integral_value(rounding=ROUND_CEILING) / Decimal(
            "100"
        )

    if normalized_service == "express":
        max_pages = CLICK2MAIL_LIMITS[double_sided]
        if page_count > max_pages:
            if double_sided:
                raise ValueError("Express supports up to 198 double-sided PDF pages.")
            raise ValueError("Express supports up to 99 single-sided PDF pages.")

        billed_pages = page_count  # Express uses raw PDF pages with no inserted address page
        sheet_count = (billed_pages + 1) // 2 if double_sided else billed_pages
        production_base = (
            CLICK2MAIL_COLOR_BASE_PRODUCTION
            if color
            else CLICK2MAIL_BW_BASE_PRODUCTION
        )
        incremental_page_rate = (
            CLICK2MAIL_COLOR_INCREMENTAL_PAGE_COST
            if color
            else CLICK2MAIL_BW_INCREMENTAL_PAGE_COST
        )
        additional_page_count = max(0, billed_pages - 1)
        additional_page_cost = incremental_page_rate * Decimal(additional_page_count)
        duplex_discount = (
            CLICK2MAIL_DUPLEX_DISCOUNT_PER_SHEET * Decimal(billed_pages // 2)
            if double_sided
            else Decimal("0.00")
        )
        production_cost = money(
            production_base + additional_page_cost - duplex_discount
        )
        signature_provider_surcharge = (
            Decimal("3.95") if signature_required else Decimal("0.00")
        )
        provider_cost = money(
            CLICK2MAIL_POSTAGE + signature_provider_surcharge + production_cost
        )
        base_provider_cost = money(CLICK2MAIL_POSTAGE + production_cost)
        base_retail_price = money(
            round_up_to_cent(
                (
                    base_provider_cost
                    + CLICK2MAIL_ADDRESS_VERIFICATION_COST
                    + CLICK2MAIL_STRIPE_FIXED_FEE
                    + CLICK2MAIL_TARGET_PROFIT
                )
                / (Decimal("1.00") - CLICK2MAIL_STRIPE_PERCENT_FEE)
            )
        )
        formula_retail_price = money(
            round_up_to_cent(
                (
                    provider_cost
                    + CLICK2MAIL_ADDRESS_VERIFICATION_COST
                    + CLICK2MAIL_STRIPE_FIXED_FEE
                    + CLICK2MAIL_TARGET_PROFIT
                )
                / (Decimal("1.00") - CLICK2MAIL_STRIPE_PERCENT_FEE)
            )
        )
        signature_retail_surcharge = (
            Decimal("4.20") if signature_required else Decimal("0.00")
        )
        retail_price = money(
            max(
                formula_retail_price,
                base_retail_price + signature_retail_surcharge,
            )
        )

        return {
            "total_usd": float(retail_price),
            "page_count": page_count,
            "billable_pages": billed_pages,
            "sheet_count": sheet_count,
            "double_sided": double_sided,
            "color": color,
            "mail_service": normalized_service,
            "certified": certified,
            "signature_required": signature_required,
            "provider": "click2mail",
            "pricing_model": "click2mail_express",
            "breakdown_usd": {
                "postage": float(money(CLICK2MAIL_POSTAGE)),
                "signature_provider_surcharge": float(
                    money(signature_provider_surcharge)
                ),
                "signature_retail_surcharge": float(
                    money(signature_retail_surcharge)
                ),
                "production_base": float(money(production_base)),
                "additional_page_rate": float(money(incremental_page_rate)),
                "additional_page_count": additional_page_count,
                "additional_page_cost": float(money(additional_page_cost)),
                "duplex_discount": float(money(duplex_discount)),
                "production_cost": float(production_cost),
                "provider_cost": float(provider_cost),
                "address_verification_cost": float(
                    money(CLICK2MAIL_ADDRESS_VERIFICATION_COST)
                ),
                "stripe_fixed_fee": float(money(CLICK2MAIL_STRIPE_FIXED_FEE)),
                "stripe_percent_fee": float(CLICK2MAIL_STRIPE_PERCENT_FEE),
                "target_profit": float(money(CLICK2MAIL_TARGET_PROFIT)),
            },
        }

    max_pages = POSTGRID_LIMITS[double_sided]
    if page_count > max_pages:
        if double_sided:
            raise ValueError("First Class supports up to 398 double-sided PDF pages.")
        raise ValueError("First Class supports up to 199 single-sided PDF pages.")

    lob_eligible = page_count <= LOB_LIMITS[double_sided]
    if certified and not lob_eligible:
        raise ValueError(
            "Certified mail is only available for Lob-eligible First Class letters "
            "up to 59 single-sided or 118 double-sided document pages."
        )

    provider = "lob" if lob_eligible else "postgrid"
    billable_pages = page_count + 1  # insert_blank_page address placement
    sheet_count = (billable_pages + 1) // 2 if double_sided else billable_pages

    base_fee = STANDARD_BASE_FEE
    per_page_rate = STANDARD_COLOR_RATE if color else STANDARD_BW_RATE
    print_fee = per_page_rate * Decimal(billable_pages)

    threshold_multiplier = Decimal("1") if double_sided else Decimal("0.5")
    if Decimal(billable_pages) >= STANDARD_TIER_TWO_THRESHOLD * threshold_multiplier:
        tier_fee = STANDARD_TIER_TWO_FEE
    elif Decimal(billable_pages) >= STANDARD_TIER_ONE_THRESHOLD * threshold_multiplier:
        tier_fee = STANDARD_TIER_ONE_FEE
    elif Decimal(billable_pages) > Decimal("12") * threshold_multiplier:
        tier_fee = STANDARD_OVER_6_SHEETS_FEE
    else:
        tier_fee = Decimal("0.00")

    service_fee = Decimal("0.00")
    certified_fee = STANDARD_CERTIFIED_FEE if certified else Decimal("0.00")

    total = money(base_fee + print_fee + tier_fee + service_fee + certified_fee)

    return {
        "total_usd": float(total),
        "page_count": page_count,
        "billable_pages": billable_pages,
        "sheet_count": sheet_count,
        "double_sided": double_sided,
        "color": color,
        "mail_service": normalized_service,
        "certified": certified,
        "signature_required": False,
        "provider": provider,
        "pricing_model": "standard",
        "breakdown_usd": {
            "base_fee": float(money(base_fee)),
            "print_fee": float(money(print_fee)),
            "tier_fee": float(money(tier_fee)),
            "service_fee": float(money(service_fee)),
            "certified_fee": float(money(certified_fee)),
        },
    }

'''

## Postage cost calculator for real scenarios

The calculator is built on the same pricing rules used at checkout, so the estimate matches what you will see when you place an order.

## Express pricing notes

Express is fulfilled through Click2Mail-backed Priority Mail pricing. It uses raw PDF pages with no inserted address page and supports up to 99 single-sided or 198 double-sided pages. Signature confirmation is available for an extra $4.20 on the customer-facing price.

## Certified mail cost

Certified Mail is available with First Class only. Select Certified Mail in the calculator to see the added cost for tracking, then add electronic return receipt if you need signature evidence.

## Bulk pricing and high page counts

Each estimate is for a single letter. If you need bulk pricing or higher page counts, contact support so we can tailor a workflow.

## Related pricing resources

- See full [pricing details](/pricing).
- Review [delivery times](/delivery-times).

## Ready to send it?

Start with the calculator, then upload your PDF when you are ready.
[Start a letter](cta:/)
