This guide walks you through Panama Postal’s core workflows from the Python library and the command-line interface. All examples use real postal codes and real output values from the source. Start with a simple decode and build up to full geographic enrichment.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/kass507/panama-postal/llms.txt
Use this file to discover all available pages before exploring further.
Import
decode from panama_postal and pass any valid code. The returned DecodedPostal dataclass contains the center coordinates of the encoded grid cell, the precision level, and the estafeta prefix extracted from the first two characters.from panama_postal import decode
d = decode("ACC99-PJ42W")
print(d.lat, d.lng) # 8.944446093749999 -79.56167109375002
print(d.level) # PICO
print(d.precision_meters) # 3.3
print(d.estafeta_prefix) # AC
The
level field reflects how many character pairs were decoded. A full ten-character code (eight-character body) decodes to PICO level — the finest precision at approximately 3.3 meters. Shorter codes resolve to NANO (~26 m), MICRO (~660 m), or MACRO (~15.8 km).decode() returns None if the input cannot be parsed — for example if it contains characters outside the base-30 alphabet (23456789ABCDEFGHJKLMNPQRSTVWXZ).validate() checks two things: that the code has a valid format, and that the decoded coordinates fall within Panama’s geographic bounding box. It returns True only when both conditions pass.from panama_postal import validate
validate("ACC99-PJ42W") # True
validate("ACCI99-PJ42W") # False (I is not in the base-30 alphabet)
validate("22-2222-2222", strict=True) # False (coordinates fall outside strict Panama bbox)
By default,
validate() uses the official site’s permissive bounding box (lat ∈ [6, 11], lng ∈ [-86, -74]), which includes adjacent ocean and border areas. Pass strict=True (or omit the --laxo CLI flag) to use the tighter territorial bounding box (lat ∈ [7.15, 9.70], lng ∈ [-83.10, -77.10]).encode() converts a (lat, lng) pair into the geographic body of a postal code — the eight characters that represent the grid position. Note that the two-character estafeta prefix is not included in this output; resolving it requires a point-in-polygon lookup against estafeta.geojson.gz.from panama_postal import encode
cuerpo = encode(8.305509375, -79.20167109375001)
print(cuerpo) # 'M2C9A-F9A33'
You can also encode at a coarser resolution by passing a
level argument: "MACRO" (2 chars), "MICRO" (4 chars), "NANO" (6 chars), or "PICO" (8 chars, default).The CLI supports both interactive and non-interactive modes. It automatically loads
estafeta.geojson.gz and the political division GeoJSON files if they are present in the current directory.In interactive mode, type a postal code at the
código> prompt. Enter salir, exit, quit, or q to exit. The CLI prints coordinates, precision, estafeta data (if available), and political division hierarchy (if available or reachable via the API), along with a Google Maps link.EstafetaIndex loads the compressed GeoJSON and performs a point-in-polygon search to identify which estafeta (post office service zone) a coordinate belongs to. When multiple polygons overlap, it returns the one with the smallest area.from panama_postal import decode
from panama_postal_estafeta import EstafetaIndex
idx = EstafetaIndex.from_file("estafeta.geojson.gz")
d = decode("ACC99-PJ42W")
info = idx.lookup(d.lat, d.lng)
print(info["ESTAF_NAME"]) # Estafeta de paraiso
print(info["VM_LEVEL2D"]) # AC
print(info["AREA"] / 1e6) # area in km²
lookup() returns a dictionary of all properties stored in the GeoJSON feature, or None if the point does not fall within any estafeta polygon. Load the index once and reuse it across many lookups — from_file() parses the entire file into an in-memory spatial index.HybridLocator resolves a coordinate to its full political division hierarchy: province, district, corregimiento, village, and neighborhood. It checks for local GeoJSON files first and falls back to the official remote API if none are present.from panama_postal_location import HybridLocator
loc = HybridLocator(".")
r = loc.lookup(8.94444609375, -79.56167109375001)
print(r["provincia"]["nombre"]) # PANAMÁ
print(r["distrito"]["nombre"]) # PANAMÁ
print(r["corregimiento"]["nombre"]) # ANCÓN
print(r["poblado"]["nombre"]) # ANCÓN
print(r["barrio"]["nombre"]) # AMADOR
Each key in the result dictionary maps to either a
{"nombre": ..., "codigo": ...} dict or None if the data was unavailable for that level. The "." argument tells HybridLocator to look for GeoJSON files in the current directory.Next Steps
Installation
Set up the repo and download optional GeoJSON data files for fully offline operation.
Postal System Guide
Deep-dive into Panama’s four-level geospatial grid and the base-30 alphabet.
decode() Reference
Full parameter and return type reference for the
decode function.HybridLocator Reference
Configure local-first or remote-only lookup behavior for political divisions.