Hex Addressing
The core of AfriHex: every coordinate becomes a stable, human-readable code built on Uber's H3 hexagonal grid. The same coordinate always produces the same code — it's pure math, no database, no lookups. It even works offline.
Code format
AF-GH-7-0GXTQD5RFZZZZ
│ │ │ └─ short ID (Crockford base-32 of the full H3 index)
│ │ └─ resolution (default 7 ≈ 5.2 km² per cell)
│ └─ country code (ISO 3166-1 alpha-2)
└─ AfriHex prefix
The short ID is a lossless encoding — the full H3 index is recovered from it.
Encode coordinates → hex code
GET /v2/hexcode?lat=5.6037&lng=-0.1870&res=7
curl "https://api.afrihex.com/v2/hexcode?lat=5.6037&lng=-0.1870&res=7" \
-H "X-API-Key: $AFRIHEX_API_KEY"
{
"success": true,
"data": {
"code": "AF-GH-7-0GXTQD5RFZZZZ",
"h3_index": "877576970ffffff",
"resolution": 7,
"country": "Ghana",
"country_code": "GH",
"center": { "lat": 5.604078493411575, "lng": -0.19529195005881006 },
"boundary": [
{ "lat": 5.609495946766828, "lng": -0.20575170258746575 },
{ "lat": 5.598573458939036, "lng": -0.20393981349281015 },
{ "lat": 5.5931560414662345, "lng": -0.19348099764158785 },
{ "lat": 5.598660521196899, "lng": -0.184831748179894 },
{ "lat": 5.609584560860423, "lng": -0.18664210146941776 },
{ "lat": 5.615002569057701, "lng": -0.1971032403752692 }
],
"area_km2": 3.86
}
}
Resolutions range from 4 (coarse regions) to 10 (street-level). The default is 7 — roughly "suburb" scale.
Decode hex code → coordinates
GET /v2/hexcode/{code}
curl "https://api.afrihex.com/v2/hexcode/AF-GH-7-0GXTQD5RFZZZZ" \
-H "X-API-Key: $AFRIHEX_API_KEY"
Navigate the grid
| Endpoint | Returns |
|---|---|
GET /v2/hexcode/{code}/children | The 7 child cells (next finer resolution) |
GET /v2/hexcode/{code}/neighbors | The 6 adjacent cells |
GET /v2/hexcode/{code}/disk?k=2 | All cells within k hops (3k²+3k+1) |
GET /v2/hexcode/{code}/parent?res=5 | The ancestor at a coarser resolution |
GET /v2/hexcode/{code}/geojson | The cell polygon as GeoJSON |
# Zoom in: get the 7 finer cells inside a res-7 cell
curl "https://api.afrihex.com/v2/hexcode/AF-GH-7-0GXTQD5RFZZZZ/children" \
-H "X-API-Key: $AFRIHEX_API_KEY"
{
"success": true,
"data": {
"parent": "AF-GH-7-0GXTQD5RFZZZZ",
"children": [
{
"code": "AF-GH-8-0H1TQD5R1ZZZZ",
"h3_index": "8875769701fffff",
"resolution": 8,
"country_code": "GH",
"center": { "lat": 5.604078493411571, "lng": -0.19529195005881328 },
"area_km2": 0.55
}
]
}
}
neighbors and disk return the same cell objects under data.neighbors /
data.cells; parent returns data.parent (a single cell object).
Distance and path
GET /v2/hexcode/distance?origin=...&destination=... returns the number of grid
hops between two cells. GET /v2/hexcode/path returns every cell along the
shortest path.
Query parameters — both required:
| Parameter | Type | Required | Definition |
|---|---|---|---|
origin | string | required | Hex code of the starting cell |
destination | string | required | Hex code of the destination cell |
curl "https://api.afrihex.com/v2/hexcode/distance?origin=AF-GH-7-0GXTQD5RFZZZZ&destination=AF-GH-7-0GXTQD5VFZZZZ" \
-H "X-API-Key: $AFRIHEX_API_KEY"
Compact a region
POST /v2/hexcode/compact replaces complete sets of child cells with their
parent — useful for representing large areas efficiently.
Request object:
| Parameter | Type | Required | Definition |
|---|---|---|---|
codes | array<string> | required | Hex codes to compact |
resolution | integer | optional | Resolution of the input cells (default 7) |
curl -X POST "https://api.afrihex.com/v2/hexcode/compact" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"codes": ["AF-GH-7-0GXTQD5RFZZZZ", "AF-GH-7-0GXTQD5VFZZZZ"], "resolution": 7}'
Bulk encode
POST /v2/hexcode/bulk converts up to 1,000 coordinates in one call.
Request object:
| Parameter | Type | Required | Definition |
|---|---|---|---|
coordinates | array<object> | required | Up to 1,000 { lat, lng } pairs |
resolution | integer | optional | H3 resolution (default 7, range 4–10) |
curl -X POST "https://api.afrihex.com/v2/hexcode/bulk" \
-H "X-API-Key: $AFRIHEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"coordinates": [{"lat": 5.6037, "lng": -0.1870}, {"lat": 6.7, "lng": -1.62}], "resolution": 7}'
Map tiles
GET /v2/map/tiles?bbox=...&res=7 returns a GeoJSON FeatureCollection of the
cells covering a bounding box — render hex maps on Leaflet/Mapbox. Use the
coarser res while zoomed out, then subdivide with /children as the user
zooms in.
The bbox format is north,south,east,west (decimal degrees). Keep the area
small enough that the tile stays under 5,000 cells — zoom in or raise res
otherwise:
curl "https://api.afrihex.com/v2/map/tiles?bbox=5.62,5.60,-0.185,-0.195&res=8" \
-H "X-API-Key: $AFRIHEX_API_KEY"
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": { "area_km2": 0.55, "code": "AF-GH-8-0H1TQD5T3ZZZZ", "resolution": 8 },
"geometry": { "type": "Polygon", "coordinates": [] }
}
]
}
Bridge to GhanaPostGPS codes
The bridge converts between GhanaPostGPS codes and hex codes:
# GPS code → hex code
curl "https://api.afrihex.com/v2/bridge/ghanapost/GA-142-7281" \
-H "X-API-Key: $AFRIHEX_API_KEY"
{
"success": true,
"data": {
"gps_code": "GA1427281",
"hex_code": "AF-GH-7-0GXTQD5EFZZZZ",
"coordinates": { "lat": 5.547396933004167, "lng": -0.207847593183683 },
"region": "Greater Accra",
"district": "Accra",
"quality_score": 1
}
}
The hex engine itself is upstream-independent. On deployments with
ADDRESS_PROVIDER=none (or outside the addressed country), bridge calls fail
with a clear error, but all encode/decode/navigation math keeps working.
Best practices
- Pick one resolution per use case and store it with the code (it's baked into the format).
- Cache aggressively — encoding is pure math; there's never a reason to re-encode the same coordinate.
- Use the SDK —
afrihex.hex.encode / decode / children / neighbors / parent / distance / path / bulk.
API reference
See Hex Addressing — API Reference for every endpoint in this group.