Python SDK Quick Start — PLSS Coordinate Conversion in Python
Install the townshipamerica Python package and convert PLSS legal land descriptions to GPS coordinates in four lines of code. Typed responses, sync and async clients.
Convert PLSS legal land descriptions to GPS coordinates in Python with the official townshipamerica package. MIT license, typed Pydantic v2 models, sync and async clients.
Installation
Install from PyPI with pip:
pip install townshipamerica
Requires Python 3.9 or later. Dependencies (httpx, pydantic) install automatically.
Your first conversion
Get an API key
Sign up at townshipamerica.com/app and subscribe to the Search API from the Developer Portal.
Set your API key
Store your key as an environment variable — never hardcode it in source files.
export TOWNSHIPAMERICA_API_KEY="your_api_key"
Convert a PLSS description
import os
from townshipamerica import TownshipAmerica
client = TownshipAmerica(api_key=os.environ["TOWNSHIPAMERICA_API_KEY"])
result = client.search("NENE 12 4N 5E Indian Meridian")
feature = result.features[0]
print(feature.properties) # Section metadata
print(feature.geometry.coordinates) # Boundary polygon
That's it — result is a typed FeatureCollection with GeoJSON geometry and PLSS metadata.
Reverse geocoding
Find the PLSS legal land description at a GPS coordinate:
result = client.reverse(-97.5, 36.1)
feature = result.features[0]
print(feature.properties.descriptor) # "NWSE 15 4N 7W Indian Meridian"
The unit parameter controls precision — "Township", "Section", "Quarter Section", or "all":
result = client.reverse(-97.5, 36.1, unit="Quarter Section")
Autocomplete
Add type-ahead search for PLSS descriptions:
suggestions = client.autocomplete("T4N R5E", limit=5)
for item in suggestions.results:
print(item.text, item.location)
The proximity parameter biases results toward a GPS coordinate:
suggestions = client.autocomplete(
"T4N",
limit=5,
proximity=(-97.5, 36.1)
)
Batch conversion
Convert up to 100 PLSS descriptions in a single request:
locations = [
"NENE 12 4N 5E Indian Meridian",
"NESW 25 5N 30E Mount Diablo Meridian",
"SWNE 22 3N 7E Montana Meridian",
]
results = client.batch_search(locations)
for fc in results:
feature = fc.features[0]
print(feature.properties.descriptor, feature.geometry.coordinates[0][0][:2])
Batch reverse geocoding works the same way:
coordinates = [(-97.5, 36.1), (-110.0, 45.5), (-104.8, 39.7)]
results = client.batch_reverse(coordinates, unit="Section")
Error handling
The SDK raises typed exceptions mapped to HTTP status codes:
from townshipamerica.exceptions import (
AuthenticationError,
NotFoundError,
RateLimitError,
ValidationError,
)
try:
result = client.search("invalid input")
except ValidationError as e:
print(f"Bad input: {e}")
except AuthenticationError:
print("Check your API key")
except RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after} seconds")
except NotFoundError:
print("No PLSS data at that location")
Context manager
The client supports with statements for automatic cleanup:
with TownshipAmerica(api_key=os.environ["TOWNSHIPAMERICA_API_KEY"]) as client:
result = client.search("NENE 12 4N 5E Indian Meridian")
print(result.features[0].properties)
# Connection closed automatically
Related guides
- Python SDK Async & GeoPandas Patterns - Async workflows, GeoPandas integration, and production patterns
- API Integration Guide - REST API endpoints, pricing, and integration patterns
- Batch Conversion - Web interface for batch processing
Need help? Contact us or open an issue on GitHub.
Related Guides
Legal Land Description API Integration Guide
Integrate legal land description APIs into your applications. Convert PLSS descriptions to coordinates, add autocomplete search, process batch records, and display survey grid maps. REST API with JSON responses.
Python SDK Advanced Patterns — Async, GeoPandas, and Production Workflows
Use the townshipamerica Python SDK with async/await, GeoPandas DataFrames, and production-ready error handling for GIS pipelines and land tech applications.