Skip to main content

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.

The decode() function is the core entry point for converting a Panama postal code string into structured geographic data. It accepts codes with or without an estafeta prefix, handles hyphens and spaces automatically, normalizes to uppercase, and returns a DecodedPostal dataclass with the latitude and longitude at the center of the matched grid cell — or None when the code cannot be parsed.

Function Signature

def decode(code: str) -> DecodedPostal | None

Parameters

code
str
required
A Panama postal code string to decode. Hyphens and spaces are stripped automatically before parsing. The string is also converted to uppercase, so lowercase input is accepted.Accepted formats:
  • "ACC99-PJ42W" — 10-char code with estafeta prefix and hyphen
  • "ACC99PJ42W" — 10-char code with estafeta prefix, no hyphen
  • "M9C9A-G4434" — 10-char code, alternate prefix
  • "M9C9AG4434" — same, no hyphen
  • Shorter body-only codes (2, 4, 6, or 8 clean characters)

Return Value

Returns a DecodedPostal dataclass on success, or None if the code is invalid.
DecodedPostal
dataclass

Normalization Rules

Before decoding, decode() passes the input through an internal _normalize() step that enforces the following rules:
  • Hyphens (-) and spaces are stripped, and the result is converted to uppercase.
  • Every remaining character must belong to the base-30 alphabet: 23456789ABCDEFGHJKLMNPQRSTVWXZ. Note that the letters I, O, U, and Y are not in the alphabet and will cause the code to be rejected.
  • The cleaned string must be no longer than 10 characters.
  • If exactly 10 characters remain, the first 2 are the estafeta prefix and the remaining 8 form the geographic body.
  • For strings shorter than 10 characters, the body length must be even: 2, 4, 6, or 8 characters. Odd-length bodies are rejected.

Decoding Levels

The geographic body is decoded in successive 2-character pairs, each subdividing the previous cell:
Pairs usedLevelBody lengthPrecision
Chars 0–1 onlyMACRO2~15,800 m
Chars 0–3MICRO4~660 m
Chars 0–5NANO6~26 m
Chars 0–7PICO8~3.3 m
Each pair is decoded from base-30 into a row/column offset within that level’s grid, then accumulated into a final latitude and longitude at the cell center.
decode() does not check whether the decoded point falls inside Panama. A syntactically valid code could yield coordinates anywhere in the encoded grid. Use validate() to confirm the point is within Panama’s bounding box, or call is_in_panama() directly on coordinates you have already decoded.

Examples

from panama_postal import decode

# Full PICO code with estafeta prefix
d = decode("ACC99-PJ42W")
print(d.lat)               # 8.944446093749999
print(d.lng)               # -79.56167109375002
print(d.level)             # PICO
print(d.precision_meters)  # 3.3
print(d.estafeta_prefix)   # AC

# Hyphens are stripped — same result
d_no_hyphen = decode("ACC99PJ42W")
print(d_no_hyphen.lat)     # 8.944446093749999

# Lowercase input is accepted
d_lower = decode("acc99-pj42w")
print(d_lower.level)       # PICO

# Body-only code (no estafeta prefix) — 8 clean chars
d2 = decode("C99PJ42W")
print(d2.estafeta_prefix)  # None

# Odd-length body after stripping → invalid
d3 = decode("C99-PJ42W")   # 9 clean chars, not 10, and length is odd
print(d3)                  # None

# Invalid character: 'I' is not in the base-30 alphabet
d4 = decode("ACCI99-PJ42W")
print(d4)                  # None

Build docs developers (and LLMs) love