uspsaddr

package module
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2025 License: BSD-2-Clause Imports: 10 Imported by: 0

README

USPS Address Validation Library

A Go library for validating and canonicalizing US addresses using the USPS Address Validation API.

Features

  • Simple, clean API - just pass an address string
  • Validates and standardizes addresses according to USPS standards
  • Returns canonicalized addresses with ZIP+4
  • Handles address parsing automatically
  • Provides detailed validation results including corrections and warnings
  • Does not expose internal USPS API types - uses custom types for better API stability

Installation

go get github.com/tadhunt/uspsaddr

Prerequisites

You need USPS API credentials to use this library:

  1. Register at https://developer.usps.com/
  2. Create an application to get:
    • Client ID
    • Client Secret

The library automatically handles OAuth2 token acquisition and refresh - you just provide the credentials!

Usage

Basic Example
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/tadhunt/uspsaddr"
)

func main() {
    // Create config with your USPS credentials
    config := uspsaddr.Config{
        ClientID:     os.Getenv("USPS_CLIENT_ID"),
        ClientSecret: os.Getenv("USPS_CLIENT_SECRET"),
    }

    // Create client - it will automatically handle OAuth2 tokens
    client, err := uspsaddr.NewClient(config)
    if err != nil {
        log.Fatal(err)
    }

    // Create an address to validate
    address := &uspsaddr.Address{
        StreetAddress: "123 Main St",
        City:          "Anytown",
        State:         "CA",
        ZIPCode:       "12345",
    }

    // Validate the address
    results, err := client.ValidateAddress(context.Background(), address)
    if err != nil {
        log.Fatal(err)
    }

    // Print the canonicalized address
    for _, result := range results {
        addr := result.Address
        fmt.Printf("Street: %s\n", addr.StreetAddress)
        fmt.Printf("City: %s\n", addr.City)
        fmt.Printf("State: %s\n", addr.State)
        fmt.Printf("ZIP: %s-%s\n", addr.ZIPCode, addr.ZIPPlus4)
    }
}
Address Input

Create an Address struct with the following fields:

  • StreetAddress (required) - Street address
  • State (required) - Two-letter state code
  • City (optional if ZIP provided) - City name
  • ZIPCode (optional) - 5-digit ZIP code
  • SecondaryAddress (optional) - Apartment, suite, etc.
  • Firm (optional) - Business name
  • Urbanization (optional) - Urbanization code (Puerto Rico only)
Using the Test Environment

To use the USPS testing environment instead of production:

config := uspsaddr.Config{
    ClientID:     "your-client-id",
    ClientSecret: "your-client-secret",
    ServerURL:    "https://apis-tem.usps.com/addresses/v3",
    TokenURL:     "https://apis-tem.usps.com/oauth2/v3/token",
}

client, err := uspsaddr.NewClient(config)
Checking Validation Results
address := &uspsaddr.Address{
    StreetAddress: "123 Main St",
    City:          "Anytown",
    State:         "CA",
    ZIPCode:       "12345",
}

results, err := client.ValidateAddress(ctx, address)
if err != nil {
    // Handle error
    if uspsErr, ok := err.(*uspsaddr.Error); ok {
        fmt.Printf("USPS Error: %s\n", uspsErr.Detail)
        if uspsErr.Source != nil {
            fmt.Printf("Problem with: %s\n", uspsErr.Source.Parameter)
            fmt.Printf("Example: %s\n", uspsErr.Source.Example)
        }
    }
    return
}

for _, result := range results {
    // Check for corrections needed
    if len(result.Corrections) > 0 {
        fmt.Println("Address needs corrections:")
        for _, c := range result.Corrections {
            fmt.Printf("  %s: %s\n", c.Code, c.Text)
        }
    }

    // Check match quality
    if len(result.Matches) > 0 {
        for _, m := range result.Matches {
            fmt.Printf("Match: %s - %s\n", m.Code, m.Text)
        }
    }

    // Check warnings
    if len(result.Warnings) > 0 {
        fmt.Println("Warnings:")
        for _, w := range result.Warnings {
            fmt.Printf("  - %s\n", w)
        }
    }

    // Use the canonicalized address
    addr := result.Address
    fmt.Printf("%s\n%s, %s %s-%s\n",
        addr.StreetAddress,
        addr.City,
        addr.State,
        addr.ZIPCode,
        addr.ZIPPlus4,
    )
}

Types

Address

The canonicalized address structure:

type Address struct {
    Firm                      string // Business name
    StreetAddress             string // Street address
    StreetAddressAbbreviation string // Abbreviated street
    SecondaryAddress          string // Apt, Suite, etc.
    City                      string // City name
    CityAbbreviation          string // Abbreviated city
    State                     string // 2-letter state code
    ZIPCode                   string // 5-digit ZIP
    ZIPPlus4                  string // 4-digit extension
    Urbanization              string // Puerto Rico only
}
ValidationResult
type ValidationResult struct {
    Address        Address        // Canonicalized address
    Corrections    []Correction   // How to improve input
    Matches        []Match        // Match quality indicators
    Warnings       []string       // Warning messages
    AdditionalInfo *AdditionalInfo // Delivery info
}
AdditionalInfo

Additional delivery information:

type AdditionalInfo struct {
    DeliveryPoint        string // Delivery point code
    CarrierRoute         string // Carrier route
    DPVConfirmation      string // Delivery point validation
    DPVCMRA              string // Commercial mail receiving agency
    Business             string // Business flag
    CentralDeliveryPoint string // Central delivery
    Vacant               string // Vacant flag
}

Building

The library uses oapi-codegen to generate the USPS API client from the OpenAPI spec:

# Generate client and build
make

# Just generate
make generate

# Clean generated files
make clean

# Run tests
make test

Development

Prerequisites
  • Go 1.23 or higher
  • oapi-codegen tool (will be downloaded by go mod)
Project Structure
  • types.go - Public API types
  • client.go - Main client implementation
  • convert.go - Conversion between USPS and public types
  • uspsinternal/ - Generated USPS API client (not public)
  • usps-addresses-v3r2_2.yaml - USPS OpenAPI spec

License

See LICENSE.md

Credits

Uses the USPS Web Tools API.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AdditionalInfo

type AdditionalInfo struct {
	// Delivery point code
	DeliveryPoint string

	// Carrier route code
	CarrierRoute string

	// DPV (Delivery Point Validation) confirmation indicator
	DPVConfirmation string

	// DPVCMRA (Commercial Mail Receiving Agency) indicator
	DPVCMRA string

	// Business flag
	Business string

	// Central delivery flag
	CentralDeliveryPoint string

	// Vacant flag
	Vacant string
}

AdditionalInfo contains additional address information

type Address

type Address struct {
	// Firm/business name at the address
	Firm string

	// Street address (primary line)
	StreetAddress string

	// Abbreviated street address
	StreetAddressAbbreviation string

	// Secondary address (apartment, suite, etc.)
	SecondaryAddress string

	// City name
	City string

	// Abbreviated city name
	CityAbbreviation string

	// Two-letter state code
	State string

	// 5-digit ZIP code
	ZIPCode string

	// 4-digit ZIP+4 extension
	ZIPPlus4 string

	// Urbanization code (Puerto Rico addresses)
	Urbanization string
}

Address represents a canonicalized USPS address

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides address validation using the USPS API

func NewClient

func NewClient(config Config) (*Client, error)

NewClient creates a new USPS address validation client The config must contain ClientID and ClientSecret from the USPS developer portal

func (*Client) ValidateAddress

func (c *Client) ValidateAddress(ctx context.Context, address *Address) ([]ValidationResult, error)

ValidateAddress validates and canonicalizes an address Returns an array of validation results (typically one, but may be multiple for ambiguous addresses)

type Config

type Config struct {
	// ClientID is the OAuth2 client ID from USPS developer portal
	ClientID string

	// ClientSecret is the OAuth2 client secret from USPS developer portal
	ClientSecret string

	// ServerURL is the USPS API server URL (optional, defaults to production)
	// Production: https://apis.usps.com/addresses/v3
	// Testing: https://apis-tem.usps.com/addresses/v3
	ServerURL string

	// TokenURL is the OAuth2 token endpoint (optional, defaults to production)
	// Production: https://apis.usps.com/oauth2/v3/token
	// Testing: https://apis-tem.usps.com/oauth2/v3/token
	TokenURL string

	LogLevel string
}

Config contains the USPS API credentials

func (*Config) Validate

func (c *Config) Validate() error

Validate checks if the config is valid

type Correction

type Correction struct {
	Code string
	Text string
	// UserMessage provides a user-friendly explanation of the correction
	// This is derived from the correction code and DPV confirmation
	UserMessage string
}

Correction indicates how to improve the address input

type Error

type Error struct {
	Status string
	Code   string
	Title  string
	Detail string
	Source *ErrorSource
}

Error represents a USPS API error

func (*Error) Error

func (e *Error) Error() string

type ErrorSource

type ErrorSource struct {
	Parameter string
	Example   string
}

ErrorSource identifies the source of an error

type Match

type Match struct {
	Code string
	Text string
}

Match indicates if an address is an exact match

type ValidationResult

type ValidationResult struct {
	// The canonicalized address
	Address Address

	// Codes indicating how to improve the address
	Corrections []Correction

	// Codes indicating match quality
	Matches []Match

	// Warning messages
	Warnings []string

	// Additional information about the address
	AdditionalInfo *AdditionalInfo
}

ValidationResult contains the results of address validation

Directories

Path Synopsis
Package uspsinternal provides primitives to interact with the openapi HTTP API.
Package uspsinternal provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL