Documentation
¶
Index ¶
- Constants
- Variables
- func BaselineExtract(raw string) (extractedState string, extractedPostcode string)
- func BatchParseSeq(inputs []string) iter.Seq2[int, Result[Postcode]]
- func ClearDiskCache() error
- func Coordinates(raw string) (lat, lng float64, err error)
- func DefaultCachePath() string
- func DistanceMeters(codeA, codeB string) (float64, error)
- func ExportBuildingsJSON(w io.Writer) error
- func FormatTemporary(raw string) string
- func GetCachePath() string
- func GetCacheStats() (int, string)
- func GoogleMapsURL(raw string) (string, error)
- func IsTemporary(raw string) bool
- func IsTemporaryCode(raw string) bool
- func IsValid(raw string) bool
- func LoadBuildingsCSV(r io.Reader) (int, error)
- func LoadBuildingsJSON(r io.Reader) (int, error)
- func LoadDiskCache() error
- func LookupLegacyPrefix(sixDigit string) (prefix string, label string, ok bool)
- func NewHandlerTransport(h http.Handler) http.RoundTripper
- func ParseSeq(inputs []string) iter.Seq2[Postcode, error]
- func QRPNG(raw string, opts ...QROptions) ([]byte, error)
- func QRSVG(raw string, opts ...QROptions) (string, error)
- func QRTerminal(raw string, opts ...QROptions) (string, error)
- func RegisterKnownBuilding(rec BuildingRecord)
- func SaveDiskCache() error
- func SetCachePath(path string) error
- func Validate(raw string) error
- type APIError
- type AddressExtraction
- type AdministrativeAddress
- type AgentDispatcher
- type AgentGuardConfig
- type AgentGuardMetrics
- type AssembledPostcode
- type AutocompleteResponse
- type AutocompleteSuggestion
- type BuildingRecord
- type Cache
- type ChainGeocoder
- type Client
- func (c *Client) AgentMetrics() AgentGuardMetrics
- func (c *Client) Assemble(ctx context.Context, segs Segments) (*AssembledPostcode, error)
- func (c *Client) Autocomplete(ctx context.Context, query string) (*AutocompleteResponse, error)
- func (c *Client) Disassemble(ctx context.Context, code string) (*Segments, error)
- func (c *Client) GenerateQR(ctx context.Context, code string, opts ...QROptions) (*QRCode, error)
- func (c *Client) Health(ctx context.Context) error
- func (c *Client) Lookup(ctx context.Context, code string, level LookupLevel) (*LookupResponse, error)
- func (c *Client) Nearby(ctx context.Context, params NearbyParams) (*NearbyResponse, error)
- func (c *Client) NearbyPostcode(ctx context.Context, code string, radiusM float64) (*NearbyResponse, error)
- func (c *Client) RateLimit() *RateLimitInfo
- func (c *Client) ReferenceAreas(ctx context.Context, state, lga, district string) ([]NamedCode, error)
- func (c *Client) ReferenceDistricts(ctx context.Context, state, lga string) ([]NamedCode, error)
- func (c *Client) ReferenceLGAs(ctx context.Context, state string) ([]NamedCode, error)
- func (c *Client) ReferenceStates(ctx context.Context) ([]NamedCode, error)
- func (c *Client) ResolveLocation(ctx context.Context, code string) (*Location, error)
- func (c *Client) Reverse(ctx context.Context, params ReverseParams) (*ReverseResponse, error)
- func (c *Client) ReverseCoordinates(ctx context.Context, lat, lng, maxDistanceM float64) (*ReverseResponse, error)
- type ClientOption
- func WithAPIKey(key string) ClientOption
- func WithAgentGuard(cfg AgentGuardConfig) ClientOption
- func WithBaseTransport(rt http.RoundTripper) ClientOption
- func WithBaseURL(customURL string) ClientOption
- func WithCache(cache Cache) ClientOption
- func WithDefaultCache() ClientOption
- func WithGeocoder(g Geocoder) ClientOption
- func WithGoogleMapsKey(key string) ClientOption
- func WithHandler(h http.Handler) ClientOption
- func WithRateLimitRetry(enabled bool, maxDelay time.Duration) ClientOption
- func WithRetryConfig(cfg RetryConfig) ClientOption
- func WithTelemetry(t Telemetry) ClientOption
- func WithTimeout(d time.Duration) ClientOption
- func WithTransport(rt http.RoundTripper) ClientOption
- type DiagnosticReport
- type EvalResult
- type GeneratorOptions
- type Geocoder
- type GoogleMapsGeocoder
- type LGARecord
- type Location
- func (l Location) AppleMapsURL() string
- func (l Location) Coordinates() (lat, lng float64)
- func (l Location) DistanceTo(other Location) float64
- func (l Location) GeoURI() string
- func (l Location) GoogleMapsDirectionsURL() string
- func (l Location) GoogleMapsURL() string
- func (l Location) IsZero() bool
- func (l Location) OpenStreetMapURL() string
- func (l Location) PointGeometry() PointGeometry
- func (l Location) QR(opts ...QROptions) (*QRCode, error)
- func (l Location) SearchQuery() string
- type LookupLevel
- type LookupResponse
- type MCPOption
- type MCPServer
- type MemoryCache
- type MetricsRecorder
- type NamedCode
- type NearbyParams
- type NearbyResponse
- type NearbyUnit
- type NominatimGeocoder
- type PointGeometry
- type Postcode
- func (p Postcode) AppendFormatted(b []byte) []byte
- func (p Postcode) AppendText(b []byte) ([]byte, error)
- func (p Postcode) Area() string
- func (p Postcode) AreaPrefix() string
- func (p Postcode) BuildingUnit() string
- func (p Postcode) Compact() string
- func (p Postcode) Compare(other Postcode) int
- func (p Postcode) Coordinates() (lat, lng float64)
- func (p Postcode) Disassemble() Segments
- func (p Postcode) DistanceTo(other Postcode) float64
- func (p Postcode) District() string
- func (p Postcode) Equal(other Postcode) bool
- func (p Postcode) Formatted() string
- func (p Postcode) GoogleMapsURL() string
- func (p Postcode) IsZero() bool
- func (p Postcode) LGA() string
- func (p Postcode) Location() Location
- func (p Postcode) MarshalText() ([]byte, error)
- func (p Postcode) Masked() string
- func (p Postcode) QR(opts ...QROptions) (*QRCode, error)
- func (p Postcode) QRPNG(opts ...QROptions) ([]byte, error)
- func (p Postcode) QRSVG(opts ...QROptions) (string, error)
- func (p Postcode) QRTerminal(opts ...QROptions) (string, error)
- func (p Postcode) Raw() string
- func (p *Postcode) Scan(src any) error
- func (p Postcode) Segments() Segments
- func (p Postcode) Slug() string
- func (p Postcode) State() string
- func (p Postcode) String() string
- func (p *Postcode) UnmarshalText(text []byte) error
- func (p Postcode) Value() (driver.Value, error)
- type Precision
- type QRCode
- func (q *QRCode) ASCII() string
- func (q *QRCode) DataURI() (string, error)
- func (q *QRCode) Image() image.Image
- func (q *QRCode) LabelSVG() string
- func (q *QRCode) MatrixSVG() string
- func (q *QRCode) PNG() ([]byte, error)
- func (q *QRCode) PrintableHTML() string
- func (q *QRCode) SVG() string
- func (q *QRCode) SVGDataURI() string
- func (q *QRCode) SaveHTML(filename string) error
- func (q *QRCode) SavePNG(filename string) error
- func (q *QRCode) SaveSVG(filename string) error
- func (q *QRCode) Terminal() string
- func (q *QRCode) WritePNG(w io.Writer) error
- func (q *QRCode) WriteSVG(w io.Writer) error
- type QRErrorCorrectionLevel
- type QROptions
- type QRPayloadType
- type RateLimitInfo
- type RecentHouseAddress
- type RedactedAddress
- type Result
- type RetryConfig
- type RetryTransport
- type ReverseParams
- type ReverseResponse
- type SegmentDiagnosis
- type Segments
- type Span
- type StateRecord
- type SyntheticAddress
- type Telemetry
- type ToolDef
- type Tracer
- type ValidationError
Constants ¶
const ( // MCPProtocolVersionLatest is the modern stateless protocol revision (SEP-2575). MCPProtocolVersionLatest = "2026-07-28" // MCPProtocolVersion2025 is the intermediate 2025 specification revision. MCPProtocolVersion2025 = "2025-11-25" // MCPProtocolVersionLegacy is the original initialization-based protocol revision. MCPProtocolVersionLegacy = "2024-11-05" MCPServerName = "postcode-mcp" MCPServerVersion = "1.0.0" )
MCP Protocol Revisions & Server Metadata per MCP 2026-07-28 Specification
const (
DefaultBaseURL = "https://api.postcode.gov.ng"
)
Variables ¶
var ( ErrInvalidLength = errors.New("postcode: invalid length, must be exactly 11 alphanumeric characters") ErrInvalidFormat = errors.New("postcode: invalid format structure") ErrTemporaryCode = errors.New("postcode: temporary NIPOST code (TP-...) pending survey; resolve via gateway lookup") )
var ErrAgentBudgetExceeded = errors.New("postcode: agent call budget exceeded for session")
ErrAgentBudgetExceeded is returned when an autonomous agent reaches its configured call ceiling.
var ErrUnknownState = errors.New("postcode: unknown nigerian state code")
ErrUnknownState indicates that a postcode has a state prefix not recognized in the Nigerian state registry.
var MCPSupportedVersions = []string{ MCPProtocolVersionLatest, MCPProtocolVersion2025, MCPProtocolVersionLegacy, }
MCPSupportedVersions lists all supported protocol revisions in order of preference.
var NigerianStates = map[string]StateRecord{
"AB": {Code: "AB", Name: "Abia", Capital: "Umuahia", Latitude: 5.5320, Longitude: 7.4860, Zone: "SOUTH EAST"},
"AD": {Code: "AD", Name: "Adamawa", Capital: "Yola", Latitude: 9.2094, Longitude: 12.4818, Zone: "NORTH EAST"},
"AK": {Code: "AK", Name: "Akwa Ibom", Capital: "Uyo", Latitude: 5.0377, Longitude: 7.9128, Zone: "SOUTH SOUTH"},
"AN": {Code: "AN", Name: "Anambra", Capital: "Awka", Latitude: 6.2209, Longitude: 7.0670, Zone: "SOUTH EAST"},
"BA": {Code: "BA", Name: "Bauchi", Capital: "Bauchi", Latitude: 10.3158, Longitude: 9.8442, Zone: "NORTH EAST"},
"BY": {Code: "BY", Name: "Bayelsa", Capital: "Yenagoa", Latitude: 4.9267, Longitude: 6.2676, Zone: "SOUTH SOUTH"},
"BN": {Code: "BN", Name: "Benue", Capital: "Makurdi", Latitude: 7.7304, Longitude: 8.5211, Zone: "NORTH CENTRAL"},
"BO": {Code: "BO", Name: "Borno", Capital: "Maiduguri", Latitude: 11.8333, Longitude: 13.1500, Zone: "NORTH EAST"},
"CR": {Code: "CR", Name: "Cross River", Capital: "Calabar", Latitude: 4.9757, Longitude: 8.3417, Zone: "SOUTH SOUTH"},
"DE": {Code: "DE", Name: "Delta", Capital: "Asaba", Latitude: 6.1984, Longitude: 6.7329, Zone: "SOUTH SOUTH"},
"EB": {Code: "EB", Name: "Ebonyi", Capital: "Abakaliki", Latitude: 6.3249, Longitude: 8.1137, Zone: "SOUTH EAST"},
"ED": {Code: "ED", Name: "Edo", Capital: "Benin City", Latitude: 6.3350, Longitude: 5.6037, Zone: "SOUTH SOUTH"},
"EK": {Code: "EK", Name: "Ekiti", Capital: "Ado Ekiti", Latitude: 7.6211, Longitude: 5.2215, Zone: "SOUTH WEST"},
"EN": {Code: "EN", Name: "Enugu", Capital: "Enugu", Latitude: 6.4584, Longitude: 7.5464, Zone: "SOUTH EAST"},
"FC": {Code: "FC", Name: "Federal Capital Territory", Capital: "Abuja", Latitude: 9.0579, Longitude: 7.4951, Zone: "NORTH CENTRAL"},
"GO": {Code: "GO", Name: "Gombe", Capital: "Gombe", Latitude: 10.2897, Longitude: 11.1711, Zone: "NORTH EAST"},
"IM": {Code: "IM", Name: "Imo", Capital: "Owerri", Latitude: 5.4858, Longitude: 7.0355, Zone: "SOUTH EAST"},
"JI": {Code: "JI", Name: "Jigawa", Capital: "Dutse", Latitude: 11.7594, Longitude: 9.3389, Zone: "NORTH WEST"},
"KD": {Code: "KD", Name: "Kaduna", Capital: "Kaduna", Latitude: 10.5105, Longitude: 7.4165, Zone: "NORTH WEST"},
"KN": {Code: "KN", Name: "Kano", Capital: "Kano", Latitude: 12.0022, Longitude: 8.5920, Zone: "NORTH WEST"},
"KT": {Code: "KT", Name: "Katsina", Capital: "Katsina", Latitude: 12.9855, Longitude: 7.6171, Zone: "NORTH WEST"},
"KE": {Code: "KE", Name: "Kebbi", Capital: "Birnin Kebbi", Latitude: 12.4504, Longitude: 4.1999, Zone: "NORTH WEST"},
"KO": {Code: "KO", Name: "Kogi", Capital: "Lokoja", Latitude: 7.8023, Longitude: 6.7333, Zone: "NORTH CENTRAL"},
"KW": {Code: "KW", Name: "Kwara", Capital: "Ilorin", Latitude: 8.4966, Longitude: 4.5421, Zone: "NORTH CENTRAL"},
"LA": {Code: "LA", Name: "Lagos", Capital: "Ikeja", Latitude: 6.6018, Longitude: 3.3515, Zone: "SOUTH WEST"},
"NA": {Code: "NA", Name: "Nasarawa", Capital: "Lafia", Latitude: 8.4932, Longitude: 8.5153, Zone: "NORTH CENTRAL"},
"NI": {Code: "NI", Name: "Niger", Capital: "Minna", Latitude: 9.6139, Longitude: 6.5569, Zone: "NORTH CENTRAL"},
"OG": {Code: "OG", Name: "Ogun", Capital: "Abeokuta", Latitude: 7.1475, Longitude: 3.3619, Zone: "SOUTH WEST"},
"ON": {Code: "ON", Name: "Ondo", Capital: "Akure", Latitude: 7.2571, Longitude: 5.2058, Zone: "SOUTH WEST"},
"OS": {Code: "OS", Name: "Osun", Capital: "Osogbo", Latitude: 7.7827, Longitude: 4.5418, Zone: "SOUTH WEST"},
"OY": {Code: "OY", Name: "Oyo", Capital: "Ibadan", Latitude: 7.3775, Longitude: 3.9470, Zone: "SOUTH WEST"},
"PL": {Code: "PL", Name: "Plateau", Capital: "Jos", Latitude: 9.9271, Longitude: 8.8921, Zone: "NORTH CENTRAL"},
"RI": {Code: "RI", Name: "Rivers", Capital: "Port Harcourt", Latitude: 4.8156, Longitude: 7.0498, Zone: "SOUTH SOUTH"},
"SO": {Code: "SO", Name: "Sokoto", Capital: "Sokoto", Latitude: 13.0609, Longitude: 5.2476, Zone: "NORTH WEST"},
"TA": {Code: "TA", Name: "Taraba", Capital: "Jalingo", Latitude: 8.8937, Longitude: 11.3600, Zone: "NORTH EAST"},
"YO": {Code: "YO", Name: "Yobe", Capital: "Damaturu", Latitude: 11.7470, Longitude: 11.9608, Zone: "NORTH EAST"},
"ZA": {Code: "ZA", Name: "Zamfara", Capital: "Gusau", Latitude: 12.1702, Longitude: 6.6592, Zone: "NORTH WEST"},
}
NigerianStates contains geographic centroids and administrative capitals for all 36 States and FCT.
Functions ¶
func BaselineExtract ¶ added in v0.1.4
BaselineExtract provides an offline heuristic extractor for Nigerian addresses. It searches raw unstructured text for state names/codes and postcode patterns using the 5-stage Nigerian address disambiguation pipeline.
func BatchParseSeq ¶
BatchParseSeq yields an iter.Seq2 iterator with slice index and Result wrapper.
func ClearDiskCache ¶ added in v0.1.9
func ClearDiskCache() error
ClearDiskCache removes all custom in-memory buildings and deletes the persistent cache file.
func Coordinates ¶ added in v0.1.1
Coordinates parses any valid 11-character Nigerian postcode string and returns its latitude and longitude coordinates.
func DefaultCachePath ¶ added in v0.1.9
func DefaultCachePath() string
DefaultCachePath returns the standard user-level cache file path: ~/.postcode/cache.json
func DistanceMeters ¶ added in v0.2.2
DistanceMeters parses two Nigerian postcode strings and returns the Haversine distance in meters between their resolved geographic coordinates.
func ExportBuildingsJSON ¶ added in v0.1.9
ExportBuildingsJSON writes all cached custom building records to a JSON writer.
func FormatTemporary ¶ added in v0.2.4
FormatTemporary normalizes a temporary code to an uppercase canonical representation prefixed with "TP-". For example, "tp_01_a01_01" becomes "TP-01-A01-01", and "tp-123456" becomes "TP-123456".
func GetCachePath ¶ added in v0.1.9
func GetCachePath() string
GetCachePath returns the active cache file path.
func GetCacheStats ¶ added in v0.1.9
GetCacheStats returns the number of custom cached building records and the file location.
func GoogleMapsURL ¶ added in v0.1.1
GoogleMapsURL parses any valid 11-character Nigerian postcode string and directly generates its Google Maps location URL.
func IsTemporary ¶ added in v0.2.4
IsTemporary reports whether raw is a NIPOST temporary building code (e.g. "TP-...", "TP_..."). Temporary codes are minted by NIPOST widgets for unsurveyed buildings and resolve to official 11-character postcodes once field survey indexing is completed.
func IsTemporaryCode ¶ added in v0.2.4
IsTemporaryCode is an alias for IsTemporary.
func IsValid ¶ added in v0.1.9
IsValid reports whether raw is a valid Nigerian postcode with a recognized state code.
func LoadBuildingsCSV ¶ added in v0.1.9
LoadBuildingsCSV reads building records from a CSV reader. Expected header format: postcode,latitude,longitude,address,state_code,state_name,lga_code,lga_name,zone
func LoadBuildingsJSON ¶ added in v0.1.9
LoadBuildingsJSON reads building records from a JSON array or object reader and stores them in cache.
func LoadDiskCache ¶ added in v0.1.9
func LoadDiskCache() error
LoadDiskCache ensures disk cache entries from ~/.postcode/cache.json (or custom path) are loaded into the offline building registry.
func LookupLegacyPrefix ¶ added in v0.2.2
LookupLegacyPrefix maps a 6-digit legacy Nigerian postal code (e.g. "100001", "900001") to its corresponding modern NIPOST State-LGA prefix (e.g. "LA-11", "FC-03") and description.
func NewHandlerTransport ¶ added in v0.2.2
func NewHandlerTransport(h http.Handler) http.RoundTripper
NewHandlerTransport wraps an http.Handler as an in-memory http.RoundTripper. Ideal for deterministic, zero-network unit testing and sandboxed agent execution.
func QRPNG ¶ added in v0.2.3
QRPNG validates a Nigerian postcode string and returns its PNG QR code image bytes.
func QRSVG ¶ added in v0.2.3
QRSVG validates a Nigerian postcode string and returns its SVG QR code representation.
func QRTerminal ¶ added in v0.2.3
QRTerminal validates a Nigerian postcode string and returns a compact Unicode terminal QR code.
func RegisterKnownBuilding ¶ added in v0.1.1
func RegisterKnownBuilding(rec BuildingRecord)
RegisterKnownBuilding allows applications to register custom building units into the offline geocoding cache.
func SaveDiskCache ¶ added in v0.1.9
func SaveDiskCache() error
SaveDiskCache persists all registered custom building records to the cache file.
func SetCachePath ¶ added in v0.1.9
SetCachePath overrides the default cache file path and loads existing entries.
Types ¶
type APIError ¶
type APIError struct {
StatusCode int `json:"-"`
Code string `json:"code"`
Message string `json:"message"`
RateLimit *RateLimitInfo `json:"-"`
RetryAfter time.Duration `json:"-"`
}
APIError represents an error returned by the NIPOST Postcode API gateway.
func (*APIError) IsInsufficientCredits ¶
func (*APIError) IsNotFound ¶
func (*APIError) IsRateLimit ¶
func (*APIError) IsUnauthorized ¶
func (*APIError) UnmarshalJSON ¶
UnmarshalJSON handles both the official nested envelope {"error": {"code": ..., "message": ...}} and flat payloads {"code": ..., "message": ...}.
type AddressExtraction ¶ added in v0.2.2
type AddressExtraction struct {
Raw string `json:"raw"`
Postcode string `json:"postcode,omitempty"` // Canonical hyphenated 11-char postcode (if found/repaired)
PostcodeValid bool `json:"postcode_valid"` // True if Postcode is a valid 11-char NIPOST code
LegacyPostcode string `json:"legacy_postcode,omitempty"` // Deprecated 6-digit numeric postal code (if found)
SuggestedPrefix string `json:"suggested_prefix,omitempty"` // Resolved State or State-LGA prefix (e.g. "LA-08", "FC-03")
StateCode string `json:"state_code,omitempty"` // 2-letter NIPOST state code (e.g. "LA", "FC")
StateName string `json:"state_name,omitempty"` // Full state name (e.g. "Lagos", "Federal Capital Territory")
LGACode string `json:"lga_code,omitempty"` // 2-digit LGA code (e.g. "08", "11")
LGAName string `json:"lga_name,omitempty"` // Full LGA name (e.g. "Eti-Osa", "Ikeja")
Locality string `json:"locality,omitempty"` // Neighborhood, district, or estate (e.g. "Lekki Phase 1", "Wuse II")
Street string `json:"street,omitempty"` // Street or house number component
Landmark string `json:"landmark,omitempty"` // Landmark anchor (e.g. "Beside First Bank", "Opposite Central Mosque")
Latitude float64 `json:"latitude,omitempty"` // Best-available resolved latitude
Longitude float64 `json:"longitude,omitempty"` // Best-available resolved longitude
Confidence string `json:"confidence"` // "high", "medium", or "low"
}
AddressExtraction holds the structured entities extracted from an unstructured Nigerian address using the 5-stage NIPOST address disambiguation pipeline.
func ExtractAddress ¶ added in v0.2.2
func ExtractAddress(raw string) AddressExtraction
ExtractAddress runs the 5-stage Nigerian address disambiguation pipeline on an unstructured address string, extracting postcodes (modern or legacy 6-digit), administrative state/LGA, neighborhood locality, street, landmark anchors, and resolved coordinates.
type AdministrativeAddress ¶
type AdministrativeAddress struct {
State string `json:"state,omitempty"`
StateName string `json:"state_name,omitempty"`
LGA string `json:"lga,omitempty"`
LGAName string `json:"lga_name,omitempty"`
District string `json:"district,omitempty"`
DistrictName string `json:"district_name,omitempty"`
Area string `json:"area,omitempty"`
AreaName string `json:"area_name,omitempty"`
Unit string `json:"unit,omitempty"`
Zone string `json:"zone,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
}
AdministrativeAddress details administrative boundaries up to area level (L2+).
type AgentDispatcher ¶ added in v0.1.4
type AgentDispatcher struct {
// contains filtered or unexported fields
}
AgentDispatcher handles incoming tool executions from AI agent frameworks.
func NewAgentDispatcher ¶ added in v0.1.4
func NewAgentDispatcher(client *Client) *AgentDispatcher
NewAgentDispatcher creates a dispatcher. If client is nil, the dispatcher operates in offline mode, servicing local validation, diagnostics, state listing, and reference geocoding.
func (*AgentDispatcher) Dispatch ¶ added in v0.1.4
Dispatch executes the specified tool by name with unparsed JSON arguments.
func (*AgentDispatcher) DispatchString ¶ added in v0.1.4
func (d *AgentDispatcher) DispatchString(ctx context.Context, name string, argsJSON []byte) (string, error)
DispatchString executes the tool and returns the result serialized as a JSON string, safe for direct injection into LLM response messages.
func (*AgentDispatcher) Tools ¶ added in v0.1.4
func (d *AgentDispatcher) Tools() []ToolDef
Tools returns the list of available tools.
type AgentGuardConfig ¶ added in v0.1.4
type AgentGuardConfig struct {
// MaxCommercialCallsPerRun limits the number of paid/commercial calls (Level 2/3) in a session.
// 0 means unlimited.
MaxCommercialCallsPerRun int
// MaxTotalCallsPerRun limits the total number of all gateway calls in a session.
// 0 means unlimited.
MaxTotalCallsPerRun int
// AutoDowngradeToLevel1 automatically downgrades Level 2/3 commercial requests to
// free Level 1 validity checks if commercial limits are reached or insufficient credits occur.
AutoDowngradeToLevel1 bool
// AutoFallbackToOffline automatically falls back to offline reference geocoding
// if gateway calls fail with 429 (rate limit) or 402 (insufficient credits).
AutoFallbackToOffline bool
}
AgentGuardConfig configures autonomous guardrails for AI agents to prevent runaway costs and infinite loops during tool-calling execution.
type AgentGuardMetrics ¶ added in v0.1.4
type AgentGuardMetrics struct {
TotalCalls int64 `json:"total_calls"`
CommercialCalls int64 `json:"commercial_calls"`
DowngradedCalls int64 `json:"downgraded_calls"`
OfflineFallbacks int64 `json:"offline_fallbacks"`
}
AgentGuardMetrics reports live telemetry for calls executed under agent guardrails.
type AssembledPostcode ¶
type AssembledPostcode struct {
Postcode string `json:"postcode"` // Canonical: "EK-01-A03-FK-01"
Display string `json:"display"` // Spaced: "EK 01 A03 FK 01"
Compact string `json:"compact"` // Compact: "EK01A03FK01"
}
AssembledPostcode represents the output of POST /v1/assembly/assemble.
func AssembleSegments ¶ added in v0.1.9
func AssembleSegments(segs Segments) (AssembledPostcode, error)
AssembleSegments validates and combines segments into an AssembledPostcode locally without network calls.
type AutocompleteResponse ¶
type AutocompleteResponse struct {
Segment string `json:"segment"`
Suggestions []AutocompleteSuggestion `json:"suggestions"`
}
AutocompleteResponse contains suggestions for the currently active segment.
type AutocompleteSuggestion ¶
AutocompleteSuggestion represents an individual suggestion returned by autocomplete.
type BuildingRecord ¶ added in v0.1.1
type BuildingRecord struct {
Postcode string // Canonical (e.g. "EK-01-A03-FK-01") or Compact ("EK01A03FK01")
Latitude float64
Longitude float64
Address string
StateCode string
StateName string
LGACode string
LGAName string
Zone string
}
BuildingRecord holds high-precision point geometry for a specific building unit.
func AllBuildingRecords ¶ added in v0.1.9
func AllBuildingRecords() []BuildingRecord
AllBuildingRecords returns all known building benchmark records and loaded custom cached buildings.
type Cache ¶ added in v0.1.4
type Cache interface {
Get(key string) (any, bool)
Set(key string, val any, ttl time.Duration)
Delete(key string)
Clear()
Len() int
}
Cache defines the interface for caching postcode gateway lookups and resolutions. Enables idempotency and prevents redundant paid API calls during AI agent loops.
type ChainGeocoder ¶ added in v0.1.9
type ChainGeocoder struct {
Geocoders []Geocoder
}
ChainGeocoder attempts each provided Geocoder in sequence until one succeeds.
func NewChainGeocoder ¶ added in v0.1.9
func NewChainGeocoder(geocoders ...Geocoder) *ChainGeocoder
NewChainGeocoder creates a composite geocoder.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶
func NewClient(opts ...ClientOption) (*Client, error)
NewClient instantiates a production-tuned HTTP client.
func (*Client) AgentMetrics ¶ added in v0.1.4
func (c *Client) AgentMetrics() AgentGuardMetrics
AgentMetrics returns live telemetry metrics for calls executed under agent guardrails.
func (*Client) Assemble ¶
Assemble builds canonical, display, and compact postcodes from individual segments. Numeric segments are zero-filled (e.g. "1" -> "01") and alpha segments are converted to uppercase.
func (*Client) Autocomplete ¶
Autocomplete retrieves segment-aware suggestions for a partial postcode input (e.g. "EK 01 A").
func (*Client) Disassemble ¶
Disassemble decomposes a postcode string into its 5 structural segments.
func (*Client) GenerateQR ¶ added in v0.2.3
GenerateQR resolves the postcode location via the NIPOST gateway (falling back to offline reference data) and generates a QRCode enriched with any available street address and point coordinates.
func (*Client) Health ¶ added in v0.1.9
Health checks the operational status of the gateway via GET /healthz. Returns nil if the gateway responds with HTTP 200 OK.
func (*Client) Lookup ¶
func (c *Client) Lookup(ctx context.Context, code string, level LookupLevel) (*LookupResponse, error)
Lookup queries the gateway for detailed attributes of a postcode. Level defaults to Level1 (free) if 0 or unspecified.
func (*Client) Nearby ¶
func (c *Client) Nearby(ctx context.Context, params NearbyParams) (*NearbyResponse, error)
Nearby searches for active postcode units within a radius (default 300m) of a coordinate or reference postcode.
func (*Client) NearbyPostcode ¶ added in v0.1.9
func (c *Client) NearbyPostcode(ctx context.Context, code string, radiusM float64) (*NearbyResponse, error)
NearbyPostcode searches for active units within a radius of a reference postcode.
func (*Client) RateLimit ¶
func (c *Client) RateLimit() *RateLimitInfo
RateLimit returns the most recent rate limit quotas reported by the NIPOST gateway, or nil if no request has yet returned rate limit headers.
func (*Client) ReferenceAreas ¶ added in v0.1.9
func (c *Client) ReferenceAreas(ctx context.Context, state, lga, district string) ([]NamedCode, error)
ReferenceAreas queries all postal area codes under a state, LGA, and district (GET /v1/reference/areas?state=...&lga=...&district=...). Areas have no human name (code only). Free, no credits consumed.
func (*Client) ReferenceDistricts ¶ added in v0.1.9
ReferenceDistricts queries all postal district codes under a state and LGA (GET /v1/reference/districts?state=...&lga=...). Districts have no human name (code only). Free, no credits consumed.
func (*Client) ReferenceLGAs ¶ added in v0.1.9
ReferenceLGAs queries all Local Government Areas for a given state code (GET /v1/reference/lgas?state=...). This endpoint is free and consumes no credits.
func (*Client) ReferenceStates ¶ added in v0.1.9
ReferenceStates queries the official precomputed catalog for all 37 Nigerian states (GET /v1/reference/states). This endpoint is free and consumes no credits.
func (*Client) ResolveLocation ¶ added in v0.1.1
ResolveLocation resolves rich geographic metadata for a postcode. It enriches the location via the NIPOST gateway at the highest available commercial tier (Level 3 down to Level 1) if configured, adopting any explicit point geometry returned by the gateway (e.g. enterprise accounts or simulator). If point geometry is not present, it leverages the SDK's high-precision offline reference geocoding engine (building benchmarks -> LGA centroid -> State centroid) to guarantee reliable coordinates and mapping URLs.
func (*Client) Reverse ¶
func (c *Client) Reverse(ctx context.Context, params ReverseParams) (*ReverseResponse, error)
Reverse resolves a geographic coordinate to the nearest active postcode unit.
func (*Client) ReverseCoordinates ¶ added in v0.1.9
func (c *Client) ReverseCoordinates(ctx context.Context, lat, lng, maxDistanceM float64) (*ReverseResponse, error)
ReverseCoordinates resolves geographic coordinates directly to the nearest active postcode unit.
type ClientOption ¶
type ClientOption func(*Client)
func WithAPIKey ¶
func WithAPIKey(key string) ClientOption
WithAPIKey sets the NIPOST API key sent in the X-API-Key header. An apiKey is optional for public endpoints (L1 lookup, search, assembly).
func WithAgentGuard ¶ added in v0.1.4
func WithAgentGuard(cfg AgentGuardConfig) ClientOption
WithAgentGuard configures budget and safety ceilings for autonomous agents.
func WithBaseTransport ¶
func WithBaseTransport(rt http.RoundTripper) ClientOption
WithBaseTransport sets the underlying round tripper underneath the retry middleware.
func WithBaseURL ¶
func WithBaseURL(customURL string) ClientOption
WithBaseURL overrides the default gateway URL (e.g. for testing with httptest.Server).
func WithCache ¶ added in v0.1.4
func WithCache(cache Cache) ClientOption
WithCache configures a custom cache implementation for the client.
func WithDefaultCache ¶ added in v0.1.4
func WithDefaultCache() ClientOption
WithDefaultCache configures a standard in-memory TTL cache (1000 items, 30m TTL).
func WithGeocoder ¶ added in v0.1.9
func WithGeocoder(g Geocoder) ClientOption
WithGeocoder configures an external geocoder for resolving textual address locations into coordinates.
func WithGoogleMapsKey ¶ added in v0.1.9
func WithGoogleMapsKey(key string) ClientOption
WithGoogleMapsKey configures Google Maps Geocoding API key for the client's geocoding chain.
func WithHandler ¶ added in v0.2.2
func WithHandler(h http.Handler) ClientOption
WithHandler configures the client to execute HTTP requests directly in-memory against h (such as simulator.NewHandler()) without opening TCP sockets, while preserving retry and telemetry middleware.
func WithRateLimitRetry ¶
func WithRateLimitRetry(enabled bool, maxDelay time.Duration) ClientOption
WithRateLimitRetry configures automatic retry on 429 Too Many Requests responses. If enabled is false, 429 responses will not be retried. maxDelay sets the maximum duration the client is willing to sleep for a rate limit cooldown.
func WithRetryConfig ¶
func WithRetryConfig(cfg RetryConfig) ClientOption
WithRetryConfig configures backoff, jitter, and retry limits.
func WithTelemetry ¶
func WithTelemetry(t Telemetry) ClientOption
WithTelemetry registers custom observability hooks.
func WithTimeout ¶
func WithTimeout(d time.Duration) ClientOption
WithTimeout sets the overall client request timeout.
func WithTransport ¶
func WithTransport(rt http.RoundTripper) ClientOption
WithTransport explicitly overrides the entire round tripper stack (bypassing retries).
type DiagnosticReport ¶ added in v0.1.4
type DiagnosticReport struct {
Input string `json:"input"`
Valid bool `json:"valid"`
IsTemporary bool `json:"is_temporary,omitempty"` // True if input is a temporary NIPOST building code (TP-...)
Normalized string `json:"normalized,omitempty"` // Hyphenated canonical form if valid or recoverable
SuggestedFix string `json:"suggested_fix,omitempty"` // Auto-repaired canonical postcode when deterministically recoverable
CleanLength int `json:"clean_length"` // Number of alphanumeric characters found
Diagnoses []SegmentDiagnosis `json:"diagnoses,omitempty"`
ActionableTip string `json:"actionable_tip,omitempty"` // Summary recommendation for the caller/agent
FormatScore float64 `json:"format_score"` // Structural conformance score (0.0 to 100.0)
}
DiagnosticReport provides deep structural and administrative analysis of a postcode string. Designed for humans and autonomous AI agents to self-correct invalid inputs.
func Diagnose ¶ added in v0.1.4
func Diagnose(raw string) DiagnosticReport
Diagnose inspects a candidate postcode string, performing exhaustive grammar, structural, and administrative checks. Returns an actionable DiagnosticReport that AI agents can use to understand the error and formulate corrections.
type EvalResult ¶ added in v0.1.4
type EvalResult struct {
TotalSamples int `json:"total_samples"`
StateAccuracy float64 `json:"state_accuracy"`
PostcodeAccuracy float64 `json:"postcode_accuracy"`
ValidRate float64 `json:"valid_rate"`
AvgFormatScore float64 `json:"avg_format_score"`
DurationMs int64 `json:"duration_ms"`
}
EvalResult contains accuracy and performance scores from evaluating an agent on synthetic data.
func EvaluateAgent ¶ added in v0.1.4
func EvaluateAgent(dataset []SyntheticAddress, extractor func(raw string) (string, string)) EvalResult
EvaluateAgent runs an extraction function against a synthetic dataset and tallies accuracy metrics.
type GeneratorOptions ¶ added in v0.1.4
type GeneratorOptions struct {
Count int `json:"count"`
Seed uint64 `json:"seed,omitempty"`
NoiseRate float64 `json:"noise_rate,omitempty"` // 0.0 to 1.0 (default 0.3)
}
GeneratorOptions configures the synthetic Nigerian address generator.
type Geocoder ¶ added in v0.1.9
type Geocoder interface {
Geocode(ctx context.Context, query string) (lat, lng float64, err error)
}
Geocoder resolves a geographic textual address or landmark query to latitude and longitude coordinates.
type GoogleMapsGeocoder ¶ added in v0.1.9
type GoogleMapsGeocoder struct {
APIKey string
BaseURL string // Defaults to "https://geocode.googleapis.com"
HTTPClient *http.Client
}
GoogleMapsGeocoder resolves coordinates using the modern Google Maps Geocoding API v4 (https://geocode.googleapis.com/v4/geocode/address), with automatic fallback to v3.
func NewGoogleMapsGeocoder ¶ added in v0.1.9
func NewGoogleMapsGeocoder(apiKey string, client *http.Client) *GoogleMapsGeocoder
NewGoogleMapsGeocoder creates a Geocoder backed by Google Maps Geocoding API v4.
type LGARecord ¶ added in v0.1.1
type LGARecord struct {
StateCode string
LGACode string
Name string
Latitude float64
Longitude float64
}
LGARecord holds reference coordinates and names for an LGA within a state.
type Location ¶ added in v0.1.1
type Location struct {
Postcode string `json:"postcode"` // Canonical hyphenated: "EK-01-A03-FK-01"
Compact string `json:"compact"` // Compact 11-char: "EK01A03FK01"
Latitude float64 `json:"latitude"` // Geographic latitude (-90 to +90)
Longitude float64 `json:"longitude"` // Geographic longitude (-180 to +180)
Address string `json:"address,omitempty"` // Known street/building address if available
StateCode string `json:"state_code"` // 2-letter state code (e.g. "EK")
StateName string `json:"state_name"` // Full state name (e.g. "Ekiti")
LGACode string `json:"lga_code,omitempty"` // 2-digit LGA code (e.g. "01")
LGAName string `json:"lga_name,omitempty"` // Full LGA name (e.g. "Ado Ekiti")
Zone string `json:"zone,omitempty"` // Geopolitical zone (e.g. "SOUTH WEST")
Precision Precision `json:"precision"` // Coordinate precision tier (placed at end to minimize struct alignment padding)
}
Location encapsulates geographic coordinates, address descriptors, and mapping URLs.
func ResolveLocation ¶ added in v0.1.1
ResolveLocation parses any valid 11-character Nigerian postcode string (compact, hyphenated, or spaced) and returns its resolved geographic Location. Uses local administrative reference data without requiring network calls.
func (Location) AppleMapsURL ¶ added in v0.1.1
AppleMapsURL returns an Apple Maps URL for iOS/macOS devices. Format: https://maps.apple.com/?ll=lat,lng&q=...
func (Location) Coordinates ¶ added in v0.1.1
Coordinates returns the latitude and longitude as a float64 pair.
func (Location) DistanceTo ¶ added in v0.2.2
DistanceTo returns the Haversine distance in meters between this location and other.
func (Location) GeoURI ¶ added in v0.2.3
GeoURI returns an RFC 5870 geo: URI for this location (e.g. "geo:7.621100,5.221500?q=EK-01-A03-FK-01").
func (Location) GoogleMapsDirectionsURL ¶ added in v0.1.1
GoogleMapsDirectionsURL returns a Google Maps navigation/directions URL to this location. Format: https://www.google.com/maps/dir/?api=1&destination=lat,lng
func (Location) GoogleMapsURL ¶ added in v0.1.1
GoogleMapsURL returns a standard, universal Google Maps search URL with exact coordinates when Precision is Building, or a rich search query for coarse (LGA/State) locations. Format: https://www.google.com/maps/search/?api=1&query=...
func (Location) IsZero ¶ added in v0.1.1
IsZero reports whether the location represents a zero/uninitialized value.
func (Location) OpenStreetMapURL ¶ added in v0.1.1
OpenStreetMapURL returns an OpenStreetMap pin URL.
func (Location) PointGeometry ¶ added in v0.2.2
func (l Location) PointGeometry() PointGeometry
PointGeometry returns a GeoJSON PointGeometry ([longitude, latitude]) for this location.
func (Location) QR ¶ added in v0.2.3
QR generates a QRCode from a resolved Location, preserving any enriched address and coordinate data.
func (Location) SearchQuery ¶ added in v0.1.1
SearchQuery produces a descriptive location query string suitable for search engines (e.g. "Ado Ekiti, Ekiti State, Nigeria" or "Abuja Municipal, Federal Capital Territory, Nigeria").
type LookupLevel ¶
type LookupLevel int
LookupLevel specifies the depth of attributes returned by a lookup request. Per official NIPOST documentation (docs.postcode.gov.ng/concepts/lookup-levels): Lookup responses are graded into 3 cumulative levels (L1–L3):
- Level 1 (Free, Public): Validity status (valid: true/false) and canonical postcode.
- Level 2 (Commercial): Administrative address (state, LGA, district, area) and street address.
- Level 3 (Commercial): Full building use status (residential, commercial, mixed, etc.) and all lower levels.
Standard commercial API keys are strictly capped at Level 3 (LevelMax). Attempting to request a level higher than your organization's granted quota yields a 403 Forbidden ("key lacks scope or level").
Note on Level 4 & Level 5: In raw backend OpenAPI schemas (docs.postcode.gov.ng/api-reference/graded-postcode-lookup-levels-1–5-cumulative), levels 4 and 5 represent unreleased or restricted government tiers:
- Level 4: other_building_info (unreleased building metadata)
- Level 5: point_geometry (restricted government GIS coordinates)
Standard commercial keys do NOT have access to L4/L5. The SDK defines Level4 and Level5 for backward compatibility and private enterprise mock environments.
const ( LevelDefault LookupLevel = 0 // Default to Level 1 Level1 LookupLevel = 1 // Free: Validity check and canonical postcode Level2 LookupLevel = 2 // Commercial: Administrative boundaries and street address Level3 LookupLevel = 3 // Commercial: Building use status and unit metadata (Official Maximum) LevelMax LookupLevel = 3 // Standard commercial maximum level (L3) // Restricted / Internal tiers (not accessible with standard API keys): Level4 LookupLevel = 4 // Internal/Enterprise: Additional building info Level5 LookupLevel = 5 // Restricted: High-precision point geometry (requires special government grant) )
type LookupResponse ¶
type LookupResponse struct {
Postcode string `json:"postcode"`
Valid bool `json:"valid"`
Temporary bool `json:"temporary,omitempty"`
AdministrativeAddress *AdministrativeAddress `json:"administrative_address,omitempty"`
RecentHouseAddress *RecentHouseAddress `json:"recent_house_address,omitempty"`
BuildingUseStatus string `json:"building_use_status,omitempty"`
OtherBuildingInfo map[string]any `json:"other_building_info,omitempty"`
PointGeometry *PointGeometry `json:"point_geometry,omitempty"`
}
LookupResponse represents the graded attributes returned by GET /v1/lookup.
type MCPOption ¶ added in v0.1.4
type MCPOption func(*MCPServer)
MCPOption configures an MCPServer instance.
func WithMCPLogger ¶ added in v0.1.4
WithMCPLogger specifies a logger for internal MCP diagnostics (must write to stderr).
type MCPServer ¶ added in v0.1.4
type MCPServer struct {
// contains filtered or unexported fields
}
MCPServer implements a dual-era Model Context Protocol (MCP) server conforming to the MCP 2026-07-28 specification, with backward compatibility for legacy clients. Operates statelessly over stdio or any streaming io.ReadWriter.
func NewMCPServer ¶ added in v0.1.4
NewMCPServer creates a ready-to-run MCP server. If client is nil, the server operates in offline mode, servicing local validation, diagnostics, and reference geocoding.
type MemoryCache ¶ added in v0.1.4
type MemoryCache struct {
// contains filtered or unexported fields
}
MemoryCache provides a thread-safe, in-memory TTL cache with size bounding.
func NewMemoryCache ¶ added in v0.1.4
func NewMemoryCache(maxEntries int, defaultTTL time.Duration) *MemoryCache
NewMemoryCache creates a memory cache. If maxEntries <= 0, defaults to 1000 entries. If defaultTTL <= 0, defaults to 30 minutes.
func (*MemoryCache) Clear ¶ added in v0.1.4
func (c *MemoryCache) Clear()
Clear flushes all entries from the cache.
func (*MemoryCache) Delete ¶ added in v0.1.4
func (c *MemoryCache) Delete(key string)
Delete removes a specific key from the cache.
func (*MemoryCache) Get ¶ added in v0.1.4
func (c *MemoryCache) Get(key string) (any, bool)
Get retrieves an item from the cache if present and unexpired.
func (*MemoryCache) Len ¶ added in v0.1.4
func (c *MemoryCache) Len() int
Len returns the current count of items in the cache.
type MetricsRecorder ¶
type MetricsRecorder interface {
RecordDuration(ctx context.Context, method, endpoint string, statusCode int, duration time.Duration)
AddInflight(ctx context.Context, delta int64)
}
MetricsRecorder defines standard metrics contracts for client operations.
type NamedCode ¶ added in v0.1.9
NamedCode represents a geographic administrative unit code with an optional human name. For states and LGAs, Name is populated. For districts and areas, Name is omitted or empty.
type NearbyParams ¶
type NearbyParams struct {
Postcode string `json:"postcode,omitempty"` // Optional reference postcode (auto-resolves centroid if coordinates are 0)
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
RadiusM float64 `json:"radius_m"` // Search radius in meters (default 300, max 300)
}
NearbyParams configures location search around a geographic coordinate or reference postcode.
type NearbyResponse ¶
type NearbyResponse struct {
Results []NearbyUnit `json:"results"`
}
NearbyResponse contains location units within the requested radius.
func (*NearbyResponse) UnmarshalJSON ¶ added in v0.1.9
func (r *NearbyResponse) UnmarshalJSON(data []byte) error
UnmarshalJSON supports both a direct slice of units `[...]` (returned by live NIPOST Gateway) and an object payload `{"results": [...]}` (returned by simulators/proxies).
type NearbyUnit ¶
type NearbyUnit struct {
Postcode string `json:"postcode"`
Display string `json:"display"`
DistanceM float64 `json:"distance_m"`
Confidence string `json:"confidence"`
StateName string `json:"state_name,omitempty"`
LGAName string `json:"lga_name,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
Address string `json:"address,omitempty"`
}
NearbyUnit represents a building unit found near a coordinate.
func SearchNearbyBuildingsOffline ¶ added in v0.1.9
func SearchNearbyBuildingsOffline(lat, lng, radiusM float64) []NearbyUnit
SearchNearbyBuildingsOffline searches local embedded and cached buildings within radiusM meters of (lat, lng).
type NominatimGeocoder ¶ added in v0.1.9
type NominatimGeocoder struct {
UserAgent string
BaseURL string // Defaults to "https://nominatim.openstreetmap.org"
HTTPClient *http.Client
}
NominatimGeocoder resolves coordinates using OpenStreetMap Nominatim with country restricted to Nigeria.
func NewNominatimGeocoder ¶ added in v0.1.9
func NewNominatimGeocoder(userAgent string, client *http.Client) *NominatimGeocoder
NewNominatimGeocoder creates a Geocoder backed by OpenStreetMap Nominatim.
type PointGeometry ¶
type PointGeometry struct {
Type string `json:"type,omitempty"`
Coordinates []float64 `json:"coordinates,omitempty"` // [lng, lat]
}
PointGeometry represents GeoJSON point coordinates (L5).
type Postcode ¶
type Postcode struct {
// contains filtered or unexported fields
}
Postcode represents an immutable, validated 11-byte Nigerian postcode. Backed by a fixed byte array to ensure zero heap escapes.
func MustParse ¶ added in v0.2.2
MustParse is like Parse but panics if raw cannot be parsed as a valid 11-character postcode. Intended for package-level test fixtures and static initialization.
func Repair ¶ added in v0.2.2
Repair attempts to deterministically self-heal a postcode string, returning a ValidationError if unrecoverable.
func TryRepair ¶ added in v0.2.2
TryRepair attempts to deterministically self-heal a malformed or noisy Nigerian postcode string. It handles:
- Single-digit unpadded LGA or BuildingUnit segments in delimited strings (e.g. "EK-1-A03-FK-1" -> "EK-01-A03-FK-01")
- Zero-floor violations ("00" -> "01" in LGA or BuildingUnit)
- Common state code aliases ("BE" -> "BN" for Benue)
- OCR lookalikes in digit/alpha segments ('O' <-> '0', 'I'/'L' <-> '1', 'S' <-> '5', 'B' <-> '8')
- Surrounding noise or punctuation (e.g. "(LA-11-W06-TC-10)")
Returns the repaired Postcode and true only if the resulting candidate passes full Validate().
func (Postcode) AppendFormatted ¶ added in v0.2.2
AppendFormatted appends the canonical hyphenated representation (e.g. "EK-01-A03-FK-01") to b with 0 heap allocations when b has sufficient capacity (15 bytes).
func (Postcode) AppendText ¶
AppendText implements encoding.TextAppender for zero-alloc formatting. Outputs the spaced format: "AA 99 H77 BB 55".
func (Postcode) AreaPrefix ¶ added in v0.2.3
AreaPrefix returns the 4-segment Area-level prefix (e.g. "EK-01-A03-FK") without the building unit.
func (Postcode) BuildingUnit ¶
func (Postcode) Compact ¶ added in v0.1.4
Compact returns the compact 11-character representation without delimiters (e.g. "EK01A03FK01"). Alias for Raw().
func (Postcode) Compare ¶ added in v0.2.2
Compare returns an integer comparing two postcodes lexicographically: 0 if p == other, -1 if p < other, and +1 if p > other. Suitable for use with slices.SortFunc.
func (Postcode) Coordinates ¶ added in v0.1.1
Coordinates returns the latitude and longitude coordinates for this postcode.
func (Postcode) Disassemble ¶ added in v0.2.0
Disassemble returns the 5 constituent administrative segments of the postcode. Alias for Segments().
func (Postcode) DistanceTo ¶ added in v0.2.2
DistanceTo returns the Haversine distance in meters between this postcode and other.
func (Postcode) Equal ¶ added in v0.2.2
Equal reports whether p and other represent the same 11-character postcode.
func (Postcode) Formatted ¶
Formatted returns the canonical hyphenated representation (e.g. "EK-01-A03-FK-01").
func (Postcode) GoogleMapsURL ¶ added in v0.1.1
GoogleMapsURL returns a direct Google Maps search URL with exact coordinates.
func (Postcode) Location ¶ added in v0.1.1
Location returns the resolved geographic location and mapping URLs for this postcode. Resolves offline via built-in administrative and building registries without network calls.
func (Postcode) MarshalText ¶
func (Postcode) Masked ¶ added in v0.2.3
Masked returns the NDPA data-minimized representation of the postcode (e.g. "EK-01-A03-FK-**"), preserving State, LGA, District, and Area for routing and analytics while masking the exact building unit ("UU") to protect residential privacy under the Nigeria Data Protection Act (NDPA).
func (Postcode) QR ¶ added in v0.2.3
QR generates a QRCode for this Postcode. Returns an error if the postcode is zero or has an unrecognized Nigerian state code.
func (Postcode) QRSVG ¶ added in v0.2.3
QRSVG returns an SVG string of the QR code for this Postcode.
func (Postcode) QRTerminal ¶ added in v0.2.3
QRTerminal returns a compact Unicode terminal representation of the QR code for this Postcode.
func (*Postcode) Scan ¶ added in v0.2.2
Scan implements sql.Scanner, accepting string, []byte, or nil database values.
func (Postcode) Segments ¶ added in v0.2.0
Segments returns the 5 constituent administrative segments of the postcode.
func (Postcode) Slug ¶ added in v0.2.2
Slug returns the URL-friendly lowercase hyphenated representation (e.g. "ek-01-a03-fk-01").
func (*Postcode) UnmarshalText ¶
type Precision ¶ added in v0.1.1
type Precision uint8
Precision indicates the resolution accuracy of the resolved coordinates.
const ( // PrecisionBuilding indicates exact building-level point geometry. PrecisionBuilding Precision = iota // PrecisionArea indicates area or street axis level resolution. PrecisionArea // PrecisionDistrict indicates district-level centroid resolution. PrecisionDistrict // PrecisionLGA indicates Local Government Area centroid resolution. PrecisionLGA // PrecisionState indicates State-level centroid resolution. PrecisionState )
func (Precision) MarshalJSON ¶ added in v0.1.1
MarshalJSON implements json.Marshaler.
func (Precision) MarshalText ¶ added in v0.1.1
MarshalText implements encoding.TextMarshaler.
func (Precision) String ¶ added in v0.1.1
String returns the human-readable description of the precision level.
func (*Precision) UnmarshalJSON ¶ added in v0.1.1
UnmarshalJSON implements json.Unmarshaler to accept both string ("building") and numeric (0) forms.
func (*Precision) UnmarshalText ¶ added in v0.1.1
UnmarshalText implements encoding.TextUnmarshaler.
type QRCode ¶ added in v0.2.3
type QRCode struct {
Postcode string `json:"postcode"`
Compact string `json:"compact"`
Spaced string `json:"spaced"`
StateCode string `json:"state_code"`
StateName string `json:"state_name"`
LGACode string `json:"lga_code,omitempty"`
LGAName string `json:"lga_name,omitempty"`
Zone string `json:"zone,omitempty"`
Address string `json:"address,omitempty"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
GoogleMapsURL string `json:"google_maps_url"`
Payload string `json:"payload"`
PayloadType QRPayloadType `json:"payload_type"`
Level QRErrorCorrectionLevel `json:"level"`
Version int `json:"version"`
Dimension int `json:"dimension"`
QuietZone int `json:"quiet_zone"`
Size int `json:"size"`
ForegroundColor string `json:"foreground_color"`
BackgroundColor string `json:"background_color"`
IncludeLabel bool `json:"include_label"`
Title string `json:"title,omitempty"`
Subtitle string `json:"subtitle,omitempty"`
InvertASCII bool `json:"invert_ascii,omitempty"`
Modules [][]bool `json:"-"`
}
QRCode represents a generated, standards-compliant (ISO/IEC 18004) QR code for a Nigerian postcode.
func GenerateQR ¶ added in v0.2.3
GenerateQR validates a Nigerian postcode string and generates a QRCode with the given options.
func (*QRCode) ASCII ¶ added in v0.2.3
ASCII renders the QR code using pure 2-character ASCII/Unicode blocks ("██" and " ").
func (*QRCode) DataURI ¶ added in v0.2.3
DataURI returns a base64-encoded PNG data URI ("data:image/png;base64,...") suitable for HTML <img> src attributes.
func (*QRCode) Image ¶ added in v0.2.3
Image renders the QRCode as a standard Go image.Image. When IncludeLabel is true, a footer banner with the formatted postcode and State/LGA is drawn below the QR matrix.
func (*QRCode) LabelSVG ¶ added in v0.2.3
LabelSVG renders a print-ready NIPOST Postcode Badge / Placard SVG containing the QR code, canonical hyphenated postcode, State & LGA administrative details, and coordinates.
func (*QRCode) MatrixSVG ¶ added in v0.2.3
MatrixSVG returns a standalone SVG of the QR code matrix without an outer printable card frame.
func (*QRCode) PrintableHTML ¶ added in v0.2.3
PrintableHTML generates a standalone, print-ready HTML page containing the NIPOST Postcode QR Card with one-click printing and sharing metadata.
func (*QRCode) SVG ¶ added in v0.2.3
SVG returns a scalable vector graphics (<svg>) representation of the QR code. If IncludeLabel was set in QROptions, it returns the full printable NIPOST postcode badge SVG.
func (*QRCode) SVGDataURI ¶ added in v0.2.3
SVGDataURI returns a base64-encoded SVG data URI ("data:image/svg+xml;base64,...").
func (*QRCode) SaveHTML ¶ added in v0.2.3
SaveHTML writes the printable HTML label page to a file at filename.
func (*QRCode) SavePNG ¶ added in v0.2.3
SavePNG writes the PNG-encoded QR code image to a file at filename.
func (*QRCode) SaveSVG ¶ added in v0.2.3
SaveSVG writes the SVG-encoded QR code to a file at filename.
func (*QRCode) Terminal ¶ added in v0.2.3
Terminal renders the QR code using compact Unicode half-block characters ('▀', '▄', '█', ' ') so that two vertical modules occupy a single terminal row, preserving a 1:1 square aspect ratio.
type QRErrorCorrectionLevel ¶ added in v0.2.3
type QRErrorCorrectionLevel string
QRErrorCorrectionLevel defines the Reed-Solomon error correction capacity of a QR code.
const ( // QRLevelL recovers up to ~7% of damaged codewords. QRLevelL QRErrorCorrectionLevel = "L" // QRLevelM recovers up to ~15% of damaged codewords (default). QRLevelM QRErrorCorrectionLevel = "M" // QRLevelQ recovers up to ~25% of damaged codewords (recommended for printed labels). QRLevelQ QRErrorCorrectionLevel = "Q" // QRLevelH recovers up to ~30% of damaged codewords. QRLevelH QRErrorCorrectionLevel = "H" )
type QROptions ¶ added in v0.2.3
type QROptions struct {
// Payload controls what content the QR code encodes when scanned. Defaults to QRPayloadPostcode ("postcode").
Payload QRPayloadType `json:"payload,omitempty"`
// Level sets the Reed-Solomon error correction level ("L", "M", "Q", "H"). Defaults to "M" (or "Q" when IncludeLabel is true).
Level QRErrorCorrectionLevel `json:"level,omitempty"`
// Size is the target width/height in pixels for SVG and PNG rendering. Defaults to 256 (or 400 when IncludeLabel is true).
Size int `json:"size,omitempty"`
// QuietZone is the margin around the QR matrix in modules. Defaults to 4. Set to -1 for zero margin.
QuietZone int `json:"quiet_zone,omitempty"`
// ForegroundColor is the hex color for dark QR modules (e.g. "#000000" or "#008751"). Defaults to "#000000".
ForegroundColor string `json:"foreground_color,omitempty"`
// BackgroundColor is the hex color for light QR background (e.g. "#FFFFFF"). Defaults to "#FFFFFF".
BackgroundColor string `json:"background_color,omitempty"`
// IncludeLabel renders a printable NIPOST postcode badge/label with human-readable postcode, State/LGA, and coordinates.
IncludeLabel bool `json:"include_label,omitempty"`
// Title overrides the header text on printable labels (defaults to "NIGERIA DIGITAL POSTCODE").
Title string `json:"title,omitempty"`
// Subtitle adds a custom street address or recipient line on printable labels.
Subtitle string `json:"subtitle,omitempty"`
// InvertASCII inverts dark and light blocks when rendering terminal/ASCII output.
InvertASCII bool `json:"invert_ascii,omitempty"`
}
QROptions configures how a postcode QR code is encoded and rendered for sharing or printing.
type QRPayloadType ¶ added in v0.2.3
type QRPayloadType string
QRPayloadType specifies what data is encoded inside the QR code when scanned.
const ( // QRPayloadPostcode encodes the canonical hyphenated 11-character postcode (e.g. "EK-01-A03-FK-01"). Default. QRPayloadPostcode QRPayloadType = "postcode" // QRPayloadCompact encodes the compact 11-character postcode without hyphens (e.g. "EK01A03FK01"). QRPayloadCompact QRPayloadType = "compact" // QRPayloadSpaced encodes the spaced 5-segment display format (e.g. "EK 01 A03 FK 01"). QRPayloadSpaced QRPayloadType = "spaced" // QRPayloadGoogleMaps encodes a direct Google Maps search URL for the postcode location. QRPayloadGoogleMaps QRPayloadType = "google-maps" // QRPayloadDirections encodes a turn-by-turn Google Maps navigation URL to the postcode. QRPayloadDirections QRPayloadType = "directions" // QRPayloadAppleMaps encodes an Apple Maps pin URL for iOS/macOS devices. QRPayloadAppleMaps QRPayloadType = "apple-maps" // QRPayloadOSM encodes an OpenStreetMap pin URL. QRPayloadOSM QRPayloadType = "osm" // QRPayloadGeoURI encodes an RFC 5870 geo: URI (e.g. "geo:7.621100,5.221500?q=EK-01-A03-FK-01"). QRPayloadGeoURI QRPayloadType = "geo" // QRPayloadJSON encodes a compact JSON object with postcode, state, LGA, coordinates, and map URL. QRPayloadJSON QRPayloadType = "json" // QRPayloadText encodes a human-readable multi-line address card with postcode, location, and map link. QRPayloadText QRPayloadType = "text" )
type RateLimitInfo ¶
type RateLimitInfo struct {
Limit int // Maximum requests allowed in current window (from X-RateLimit-Limit)
Remaining int // Remaining requests in current window (from X-RateLimit-Remaining)
CreditBalance int // Remaining commercial credit balance, or -1 if header not present (from X-Credit-Balance)
ResetAt time.Time // Timestamp when quota resets (from X-RateLimit-Reset or Retry-After)
RetryAfter time.Duration // Cooldown duration requested by server (from Retry-After or X-RateLimit-Reset)
}
RateLimitInfo contains the rate-limiting quotas returned by the NIPOST API gateway as documented in https://docs.postcode.gov.ng/authentication.
func ParseRateLimitInfo ¶
func ParseRateLimitInfo(h http.Header) *RateLimitInfo
ParseRateLimitInfo extracts rate limit quotas and cooldown durations from HTTP response headers.
type RecentHouseAddress ¶
type RecentHouseAddress struct {
Address string `json:"address,omitempty"`
Recent string `json:"recent,omitempty"`
HouseNumber string `json:"house_number,omitempty"`
StreetName string `json:"street_name,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
}
RecentHouseAddress contains residential and street metadata (L2+).
type RedactedAddress ¶ added in v0.2.3
type RedactedAddress struct {
RedactedText string `json:"redacted_text"`
MaskedPostcode string `json:"masked_postcode,omitempty"`
MaskedPostcodes []string `json:"masked_postcodes,omitempty"`
AreaPrefix string `json:"area_prefix,omitempty"`
StateCode string `json:"state_code,omitempty"`
LGACode string `json:"lga_code,omitempty"`
PIIRedactedCount int `json:"pii_redacted_count"`
RedactedTypes []string `json:"redacted_types,omitempty"`
NDPACompliant bool `json:"ndpa_compliant"`
}
RedactedAddress holds the result of NDPA-compliant PII redaction on an unstructured Nigerian address or log line.
func RedactPII ¶ added in v0.2.3
func RedactPII(raw string) RedactedAddress
RedactPII scrubs personal identifiable information (Nigerian phone numbers, email addresses, 11-digit BVN/NIN numbers, and exact building unit numbers in NIPOST postcodes) from raw text while retaining State, LGA, District, and Area routing context in line with the Nigeria Data Protection Act (NDPA).
type RetryConfig ¶
type RetryConfig struct {
MaxRetries int // Maximum retry attempts for transient errors (default: 3)
BaseDelay time.Duration // Initial exponential backoff delay (default: 100ms)
MaxDelay time.Duration // Maximum exponential backoff delay (default: 2s)
DisableRateLimit bool // If true, 429 Too Many Requests will not be retried automatically
MaxRateLimitDelay time.Duration // Maximum sleep duration client will wait for a 429 cooldown (default: 10s)
}
RetryConfig configures backoff, jitter, and rate-limit handling for HTTP requests.
type RetryTransport ¶
type RetryTransport struct {
Base http.RoundTripper
Config RetryConfig
}
func NewRetryTransport ¶
func NewRetryTransport(base http.RoundTripper, cfg RetryConfig) *RetryTransport
type ReverseParams ¶
type ReverseParams struct {
Latitude float64
Longitude float64
MaxDistanceM float64 // Search radius in meters (default 25, max 250)
}
ReverseParams configures reverse geocoding to snap coordinates to the nearest unit.
type ReverseResponse ¶
type ReverseResponse struct {
Found bool `json:"found"`
Coordinate []float64 `json:"coordinate"` // [lng, lat]
Unit *NearbyUnit `json:"unit,omitempty"`
Area string `json:"area,omitempty"`
District string `json:"district,omitempty"`
State string `json:"state,omitempty"`
Message string `json:"message,omitempty"`
RadiusM float64 `json:"radius_m"`
}
ReverseResponse represents the result of reverse geocoding a coordinate.
func ReverseCoordinatesOffline ¶ added in v0.1.9
func ReverseCoordinatesOffline(lat, lng, maxDistanceM float64) *ReverseResponse
ReverseCoordinatesOffline resolves geographic coordinates to the closest building unit in the local database.
type SegmentDiagnosis ¶ added in v0.1.4
type SegmentDiagnosis struct {
Segment string `json:"segment"` // "Length", "LegacyFormat", "State", "LGA", "District", "Area", "BuildingUnit"
Input string `json:"input"` // The actual segment characters received
Expected string `json:"expected"` // What the NIPOST grammar requires
Message string `json:"message"` // Human & agent readable explanation
Suggestions []string `json:"suggestions,omitempty"` // Actionable candidates for agent self-correction
}
SegmentDiagnosis describes an issue identified in a specific segment of a postcode.
type Segments ¶
type Segments struct {
State string `json:"state"`
LGA string `json:"lga"`
District string `json:"district"`
Area string `json:"area"`
Unit string `json:"unit"`
}
Segments represents the 5 administrative components of a Nigerian postcode.
func NormalizeSegments ¶ added in v0.1.9
NormalizeSegments trims whitespace, converts alpha segments to uppercase, and zero-fills single-digit numeric segments (e.g. "1" -> "01") according to official NIPOST rules.
type Span ¶
type Span interface {
End()
RecordError(err error)
SetAttribute(key, value string)
SetStatus(code int, msg string)
}
Span encapsulates active span operations without coupling to any trace vendor.
type StateRecord ¶ added in v0.1.1
type StateRecord struct {
Code string
Name string
Capital string
Latitude float64
Longitude float64
Zone string
}
StateRecord holds reference coordinates and metadata for a Nigerian state.
func LookupState ¶ added in v0.2.2
func LookupState(query string) (StateRecord, bool)
LookupState resolves a Nigerian state record by its 2-letter NIPOST code, full state name, capital city name, or common alias (e.g. "LA", "Lagos", "Lagos State", "Ikeja", "FCT", "Abuja").
type SyntheticAddress ¶ added in v0.1.4
type SyntheticAddress struct {
RawText string `json:"raw_text"`
ExpectedState string `json:"expected_state"`
ExpectedStateCode string `json:"expected_state_code"`
ExpectedLGA string `json:"expected_lga,omitempty"`
ExpectedPostcode string `json:"expected_postcode,omitempty"`
ExpectedLat float64 `json:"expected_lat,omitempty"`
ExpectedLng float64 `json:"expected_lng,omitempty"`
NoiseType string `json:"noise_type,omitempty"`
}
SyntheticAddress represents a synthesized Nigerian address with ground-truth labels. Used to benchmark and evaluate AI agent entity extraction, validation, and geocoding accuracy.
func GenerateSyntheticDataset ¶ added in v0.1.4
func GenerateSyntheticDataset(opts GeneratorOptions) []SyntheticAddress
GenerateSyntheticDataset produces a slice of realistic synthetic Nigerian addresses.
type Telemetry ¶
type Telemetry struct {
Tracer Tracer
Metrics MetricsRecorder
}
Telemetry bundles tracing and metrics hooks.
func NopTelemetry ¶
func NopTelemetry() Telemetry
NopTelemetry provides zero-overhead, no-op telemetry by default.
type ToolDef ¶ added in v0.1.4
type ToolDef struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]any `json:"parameters"`
}
ToolDef describes an agent-executable function schema compliant with JSON Schema Draft-07.
func DefaultAgentTools ¶ added in v0.1.4
func DefaultAgentTools() []ToolDef
DefaultAgentTools returns the standard suite of tool declarations for Nigerian postcode operations.
func (ToolDef) AnthropicTool ¶ added in v0.1.4
AnthropicTool formats the tool declaration for the Anthropic Claude Messages API.
func (ToolDef) GeminiFunctionDeclaration ¶ added in v0.1.4
GeminiFunctionDeclaration formats the tool declaration for Google Gemini / Google GenAI SDK.
func (ToolDef) OpenAITool ¶ added in v0.1.4
OpenAITool formats the tool declaration for OpenAI, Mistral, Groq, and Ollama APIs.
type ValidationError ¶ added in v0.1.4
type ValidationError struct {
Report DiagnosticReport
}
ValidationError represents a validation failure enriched with an actionable DiagnosticReport.
func (*ValidationError) Error ¶ added in v0.1.4
func (e *ValidationError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
postcode
module
|
|
|
examples
|
|
|
ai_agent_guardrails
command
|
|
|
ai_synthetic_eval
command
|
|
|
otelpostcode
module
|
|
|
skills
|
|
|
nipost-postcode/examples
command
|
|