Bwendi Context API
Drop in a coordinate. Get back the place name, admin region, nearby markets, currency, language and economic context — in one request.
curl https://api.bwendi.com/\
context/CM/3.8667/11.5167 \
-H "x-api-key: YOUR_KEY"
{
"hubs": [
{ "name": "Yaoundé", "type": "city",
"context": "574m SW of Yaoundé" }
],
"hotspot": {
"name": "CCA Marché central",
"type": "bank",
"context": "11m E of CCA Marché central"
},
"metro": { "name": "Yaoundé", "type": "city" },
"nearby": [
{ "name": "CCA Marché central", "type": "bank" },
{ "name": "Agence de Régulation des Télécommunications",
"type": "government" }
],
"name": "Pharmacie du Soleil",
"lat": 3.8671, "lng": 11.51714,
"type": "pharmacy",
"within": {
"name": "Centre Commercial", "type": "quarter",
"within": {
"name": "Yaoundé I", "type": "district",
"within": {
"name": "Mfoundi", "type": "department",
"within": { "name": "Centre", "type": "region" }
}
}
},
"dem": 734,
"context": "Dans l'orbite commerciale principale de Yaoundé...",
"country": {
"name": "Cameroon", "code": "CM", "flag": "🇨🇲",
"lang": "fr",
"currency": { "symbol": "F", "code": "XAF", "name": "CFA" }
}
}
Authentication
All endpoints require a valid API key. There are no public, unauthenticated routes.
x-api-key:x-api-key: YOUR_API_KEY
Examples
curl https://api.bwendi.com/context/CM/3.8667/11.5167 \
-H "x-api-key: YOUR_API_KEY"
fetch('https://api.bwendi.com/context/CM/3.8667/11.5167', {
headers: { 'x-api-key': 'YOUR_API_KEY' }
})
Try it
Fire a live request from your browser. Responses appear below.
Tip: click Test on any endpoint page to pre-fill and auto-send.
Full geographic context for a coordinate. Returns the named place, admin region, nearby markets, country info, and more.
/context/:lat/:lng — skip the country code; we auto-detect it (+1 cr).
Parameters
| Param | Type | Note |
|---|---|---|
| cc | string | ISO 3166-1 alpha-2 (e.g. CM) |
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
Query options
| Param | Effect | Cost |
|---|---|---|
| ?lang=xx | Translate all labels (e.g. fr, es) | +1 cr |
| ?expand=true | Resolve place anchors to full names | +1 cr |
| ?metrics=true | Include raw gravity and weight on every place in the response | +3 cr |
Example request
GET /context/CM/3.8667/11.5167
Example response
{
"hubs": [
{
"name": "Yaoundé",
"type": "city",
"context": "574m SW of Yaoundé"
}
],
"hotspot": {
"name": "CCA Marché central",
"type": "bank",
"context": "11m E of CCA Marché central"
},
"metro": {
"name": "Yaoundé",
"type": "city",
"context": "574m SW of Yaoundé"
},
"nearby": [
{
"name": "CCA Marché central",
"type": "bank",
"context": "11m E of CCA Marché central"
},
{
"name": "Agence de Régulation des Télécommunications",
"type": "government",
"context": "85m NE of Agence de Régulation des Télécommunications"
}
],
"name": "Pharmacie du Soleil",
"ascii_name": "Pharmacie du Soleil",
"lat": 3.8671,
"lng": 11.51714,
"type": "pharmacy",
"within": {
"name": "Centre Commercial",
"label": "Chefferie",
"type": "quarter",
"level": 10,
"within": {
"name": "Yaoundé I",
"label": "Arrondissement",
"type": "district",
"level": 8,
"within": {
"name": "Communauté urbaine de Yaoundé",
"label": "Communauté Urbaine",
"type": "council",
"level": 7,
"within": {
"name": "Mfoundi",
"label": "Département",
"type": "department",
"level": 6,
"within": {
"name": "Centre",
"label": "Région",
"type": "region",
"level": 4
}
}
}
}
},
"dem": 734,
"anchors": {
"immediate": ["mall", "marketplace", "supermarket", "pharmacy"],
"local": ["city"],
"reachable": ["town"]
},
"context": "Dans l'orbite commerciale principale de Yaoundé. Accès immédiat à centre commercial, marché, supermarché et pharmacie.",
"country": {
"name": "Cameroon",
"localName": "Cameroun",
"code": "CM",
"callingCode": "237",
"flag": "🇨🇲",
"lang": "fr",
"currency": {
"symbol": "F",
"code": "XAF",
"name": "CFA",
"localName": "FCFA"
}
}
}
Fuzzy place-name search within a country. Results ranked by population — great for autocomplete inputs.
Parameters
| Param | Type | Note |
|---|---|---|
| cc | string | ISO 3166-1 alpha-2 |
| q | string | Required, min 2 chars |
| limit | int | 1–50 (default 10) |
| types | string | city, town, village (comma-separated) |
| lang | string | Translate labels (+1 cr) |
Example request
GET /search/CM?q=Douala
Example response
{
"country_code": "CM",
"query": "Douala",
"count": 3,
"results": [
{
"name": "Douala", "type": "city",
"lat": 4.0483, "lng": 9.7043,
"population": 2768400,
"economic_tier": "dominant",
"within": "Littoral"
}
]
}
List all markets at or above an economic tier for a country. Use hubs as the tier to get the top market hubs by gravity (80/20 rule).
Parameters
| Param | Type | Note |
|---|---|---|
| tier | string | dominant · prime · high · integrated · moderate · peripheral · marginal · isolated · hubs |
| cc | string | Optional — omit to detect from headers |
dominant › prime › high › integrated › moderate › peripheral › marginal › isolated
Example request
GET /markets/prime/CM
Example response
{
"tier": "prime",
"country_code": "CM",
"count": 8,
"markets": [
{ "name": "Douala", "type": "city", "lat": 4.0483, "lng": 9.7043,
"population": 2768400, "economic_tier": "dominant", "market_score": 11.5 }
]
}
Country info — no backend round-trip. Resolves from three sources:
| Path | Resolves from |
|---|---|
| /country | Cloudflare geolocation header |
| /country/CM | Country code you provide |
| /country/3.87/11.52 | Coordinates (0.25° grid) |
Example response
{
"name": "Cameroon",
"localName": "Cameroun",
"code": "CM",
"callingCode": "+237",
"flag": "🇨🇲",
"lang": "fr",
"currency": { "symbol": "FCFA", "code": "XAF", "name": "Central African CFA Franc" }
}
Send a question about a location. We resolve the full context first, then pass it to Gemini for a grounded answer. Great for analysis, reports, or smart location descriptions.
?lang and ?expand.
Parameters
| Param | Type | Note |
|---|---|---|
| cc | string | ISO 3166-1 alpha-2 |
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
Request body
| Field | Type | Note |
|---|---|---|
| prompt | string | Required, max 500 chars |
Example request
POST /interpret/CM/3.8667/11.5167
Content-Type: application/json
{ "prompt": "What is the commercial potential?" }
AI response field
"ai": {
"prompt": "What is the commercial potential?",
"response": "Yaoundé is Cameroon's political capital (pop. 2.8M). The dominant tier indicates strong commercial integration. Douala, the economic hub, is 194km SW..."
}
Device location verification using solar shadow analysis. Upload a capture and challenge data — we compute the expected sun position, analyse the visual evidence, and return a pass, fail, or inconclusive verdict on whether the device was actually at the claimed GPS location.
Raw (this endpoint): You handle capture yourself, send one image, get the verdict. 25 credits.
Turnkey: Use
POST /verify/challenge to create a challenge, redirect users to verify.bwendi.com, poll GET /verify/result/:id. We handle the camera, frame capture, and analysis. 400 credits total for the hosted flow.
Request body (multipart/form-data)
| Field | Type | Required | Note |
|---|---|---|---|
| image | file | yes | JPEG only, max 1 MB |
| challengeId | string | yes | UUID from your server |
| claimedLat | number | yes | -90 to 90 |
| claimedLng | number | yes | -180 to 180 |
| issuedAt | string | yes | ISO 8601 UTC timestamp (server-issued) |
| signature | string | yes | HMAC-SHA256 of challengeId + claimedLat + claimedLng + issuedAt |
Example request
curl -X POST https://api.bwendi.com/verify \
-H "x-api-key: YOUR_KEY" \
-F "image=@shadow.jpg" \
-F "challengeId=550e8400-e29b-41d4-a716-446655440000" \
-F "claimedLat=4.05" \
-F "claimedLng=9.7" \
-F "issuedAt=2026-03-22T12:34:56Z" \
-F "signature=abc123..."
Example response
{
"challengeId": "550e8400-e29b-41d4-a716-446655440000",
"verdict": "pass",
"solarElevation": 86.2,
"solarAzimuth": 175.3,
"geminiAssessment": {
"shadows_visible": "yes",
"shadow_length": "short",
"shadow_direction_consistent": true,
"outdoor_natural_light": true,
"artificial_light_signs": {
"detected": false,
"indicators": []
},
"signs_of_manipulation": false,
"confidence": 0.85,
"notes": "Very short shadows consistent with near-overhead sun."
}
}
Verdicts
| Verdict | Meaning |
|---|---|
pass | Shadows are consistent with the claimed location and time. |
fail | Shadows contradict the expected solar position — likely spoofed location. |
inconclusive | Cannot determine — indoor photo, overcast sky, or no visible shadows. |
Error responses
| Status | Reason |
|---|---|
| 400 | Missing/invalid fields, wrong content-type, file too large, invalid signature |
| 410 | Challenge expired (90-second window) |
| 422 | Sun below horizon at claimed location/time |
| 500 | Gemini API failure |
Turnkey Flow
Don't want to build the capture flow yourself? Use the turnkey flow — create a challenge, redirect users to verify.bwendi.com, and poll for the result. The hosted flow currently costs 400 credits, which is as little as 18 cents USD on the Star plan.
Step 1 — Create challenge
| Field | Type | Note |
|---|---|---|
| lat | number | Claimed latitude (-90 to 90) |
| lng | number | Claimed longitude (-180 to 180) |
| callback | string | Optional. URL to redirect user after verification. |
Example response
{
"challengeId": "550e8400-e29b-41d4-a716-446655440000",
"verifyUrl": "https://verify.bwendi.com/c/550e8400-e29b-41d4-a716-446655440000",
"issuedAt": "2026-03-22T12:34:56.000Z",
"expiresAt": "2026-03-22T12:36:26.000Z"
}
Step 2 — Redirect user
Send your user to the verifyUrl. Append ?callback=https://yourapp.com/done to redirect back after verification.
Or embed it: <iframe src="https://verify.bwendi.com/c/UUID">
Step 3 — Poll for result
Example response (pending)
{ "challengeId": "550e8400...", "status": "pending" }
Example response (complete)
{
"challengeId": "550e8400-e29b-41d4-a716-446655440000",
"verdict": "pass",
"solarElevation": 86.2,
"solarAzimuth": 175.3,
"frames": 3,
"frameVerdicts": ["pass", "pass", "pass"]
}
Returns the top-N places near a coordinate, ranked by gravity score. Country code is auto-resolved from the coordinate by the gateway — no CC param needed. Searches a ~33 km radius (3×3 big-zone grid) by default.
Path parameters
| Param | Type | Note |
|---|---|---|
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
| placeType | string | places for all settlement types, or a specific type (e.g. city, town, neighbourhood). Comma-separated for multiple. |
| limit | int | Max results (1–100) |
Query options
| Param | Default | Effect |
|---|---|---|
| ?wide=false | true | Restrict to a single big-zone cell (~11 km) instead of the default 3×3 grid (~33 km) |
| ?admin=true | false | Include an admin array of administrative levels derived from the nearest record's within chain |
Example request
GET /hotspots/3.8667/11.5167/places/5
Example response
{
"lat": 3.8667,
"lng": 11.5167,
"country_code": "CM",
"place_type": "places",
"limit": 5,
"count": 5,
"hotspots": [
{
"name": "Yaoundé",
"type": "city",
"lat": 3.8667,
"lng": 11.5167,
"distance_km": 0.412,
"score": 0.9823,
"population": 2765568,
"gravity": 0.9823
},
{
"name": "Mballa II",
"type": "suburb",
"lat": 3.8741,
"lng": 11.5093,
"distance_km": 1.127,
"score": 0.4102
}
]
}
With ?admin=true
GET /hotspots/3.8667/11.5167/places/5?admin=true
// Additional field in response:
"admin": [
{ "name": "Centre", "label": "Région", "type": "region", "level": 1 },
{ "name": "Cameroon", "label": "Country", "type": "country", "level": 0 }
]
Hotspot fields
| Field | Description |
|---|---|
| name | Place name |
| type | Settlement type (city, town, suburb, neighbourhood, …) |
| lat / lng | Coordinates of the place |
| distance_km | Distance from the queried coordinate (km) |
| score | Gravity score used for ranking |
| population | Population count, if available |
| gravity | Raw gravity value (same as score) |
Returns nearby anchor candidates ordered strictly by distance. Country code is auto-resolved from the coordinate by the gateway, so there is no CC parameter in the path.
Path parameters
| Param | Type | Note |
|---|---|---|
| range | string | immediate for the 3×3 zone bucket (~333 m), or local for the 3×3 local_zone bucket (~3.3 km) |
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
| placeType | string | places for all settlement/place types, or a specific type such as village, town, neighbourhood. Comma-separated values are supported. |
| limit | int | Max results (1–30) |
Example requests
GET /anchors/local/2.888527176989689/9.89871021523016/village/10
GET /anchors/immediate/2.888527176989689/9.89871021523016/places/30
Example response
{
"lat": 2.888527176989689,
"lng": 9.89871021523016,
"country_code": "CM",
"range": "local",
"bucket_width_m": 3300,
"place_type": "village",
"limit": 10,
"count": 3,
"anchors": [
{
"name": "Bwambé",
"type": "village",
"lat": 2.88846,
"lng": 9.90369,
"distance_m": 553,
"distance_km": 0.553,
"gravity": 287.34
},
{
"name": "Mbeka'a",
"type": "village",
"lat": 2.88317,
"lng": 9.90009,
"distance_m": 615,
"distance_km": 0.615,
"gravity": 287.34
},
{
"name": "Lobé",
"type": "village",
"lat": 2.88193,
"lng": 9.89304,
"distance_m": 967,
"distance_km": 0.967,
"gravity": 2254.71
}
]
}
Response fields
| Field | Description |
|---|---|
| range | The bucket tier used: immediate or local |
| bucket_width_m | Approximate width of the searched tier in metres |
| place_type | The type filter you requested |
| anchors | Array of matching places ordered by distance ascending |
| distance_m | Rounded distance from the query coordinate in metres |
| distance_km | Distance from the query coordinate in kilometres |
| population | Included when available on the source record |
| gravity | Included when available on the source record |
| label | Included when available on the source record |
Returns the dominant metro (city or town) nearest to a coordinate, scored by a gravity-weighted population model. Unlike /context, this is a focused single-object response that always includes the full within administrative chain — useful for resolving the regional hierarchy of any point without the overhead of full context resolution.
Parameters
| Param | Type | Note |
|---|---|---|
| cc | string | ISO 3166-1 alpha-2 (e.g. CM) |
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
Example request
GET /metro/CM/3.9500/11.4800
Example response
{
"lat": 3.95,
"lng": 11.48,
"country_code": "CM",
"metro": {
"name": "Yaoundé",
"type": "city",
"distance": 11240,
"direction": "SE",
"lat": 3.8667,
"lng": 11.5167,
"population": 2765568,
"economic_tier": "dominant",
"within": {
"name": "Centre",
"label": "Région",
"type": "region",
"within": {
"name": "Cameroon",
"label": "Country",
"type": "country"
}
},
"context": "11240m SE of Yaoundé"
}
}
Metro fields
| Field | Description |
|---|---|
| name | Metro city/town name |
| type | Settlement type (city or town) |
| distance | Distance from queried coordinate in metres |
| direction | Cardinal direction from coordinate to metro (N, NE, E, …) |
| lat / lng | Metro coordinates |
| population | Population count, if available |
| economic_tier | dominant · prime · high · integrated · moderate · peripheral · marginal · isolated |
| within | Nested administrative hierarchy (region → country). Present when available. |
| context | Human-readable distance + direction string |
Returns an 8-character hex channel that two nearby users will share. Use it as a pub/sub topic, WebSocket room, or proximity bucket.
Query options
| Param | Default | Range | Use case |
|---|---|---|---|
| range | 1100 m | 50–50000 | Pooling radius in metres |
Range presets
| Label | range= | Use case |
|---|---|---|
| Spot | 50 | Same room |
| Block | 100 | Building cluster |
| Street | 500 | Walking neighbourhood |
| Quarter | 1000 | Urban ward |
| Town | 5000 | City district |
| City | 15000 | City-wide |
| Region | 50000 | Metro region |
Example response
{
"channel": "6b099229",
"tier": "local",
"cell_size_m": 1100,
"range_m": 500
}
Structured address for any coordinate. Returns a hyperlocal address string, an Open Location Code (Plus Code), the full admin hierarchy, elevation, metro anchor, anchors, and the human-readable context string — all in one authenticated call.
Parameters
| Param | Type | Note |
|---|---|---|
| cc | string | ISO 3166-1 alpha-2 (e.g. CM) |
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
Query options
| Param | Default | Range | Effect |
|---|---|---|---|
| range | 1100 m | 50–50000 | Pooling radius — controls address string precision tier |
Range presets
| Label | range= | Use case |
|---|---|---|
| Spot | 50 | Indoor floor, kiosk |
| Block | 200 | Street segment, city block |
| Quarter | 500 | Neighbourhood, trading cluster |
| Town | 1100 | Town centre, district (default) |
| City | 5000 | Metro area, city-wide |
| Region | 25000 | Province, wide-area |
Example request
GET /address/CM/3.8667/11.5167
Example response
{
"lat": 3.8667,
"lng": 11.5167,
"country_code": "CM",
"address": "6b099229",
"plus_code": "6FMHVG88+MM",
"tier": "local_zone",
"range_m": 1100,
"place": {
"name": "Etoa-Meki",
"type": "locality",
"label": "Localité",
"lat": 3.8621,
"lng": 11.5203,
"distance": 540,
"direction": "SE"
},
"dem": 734,
"within": {
"name": "Centre Commercial",
"type": "quarter",
"within": {
"name": "Yaoundé I",
"type": "district",
"within": {
"name": "Mfoundi",
"type": "department",
"within": { "name": "Centre", "type": "region" }
}
}
},
"anchors": {
"immediate": ["mall", "marketplace", "pharmacy"],
"local": ["city"],
"reachable": ["town"]
},
"metro": {
"name": "Yaoundé",
"type": "city",
"context": "574m SW of Yaoundé"
},
"context": "Dans l'orbite commerciale principale de Yaoundé...",
"country": {
"name": "Cameroon",
"code": "CM",
"flag": "\uD83C\uDDE8\uD83C\uDDF2",
"lang": "fr",
"currency": { "symbol": "F", "code": "XAF", "name": "CFA" }
}
}
Response fields
| Field | Description |
|---|---|
| address | Hyperlocal channel string (precision cell key) — the coordinate's shareable address token |
| plus_code | Open Location Code (10-char) — globally interoperable, compatible with Google Maps |
| tier | Hyperlocal tier used: zone, local_zone, or big_zone |
| range_m | Effective pooling radius in metres (clamped to 50–50,000) |
| place | Nearest named place — name, type (town / village / locality / junction etc.), label, coordinates, distance (m), and direction |
| dem | Terrain elevation in metres (from nearest resolved place) |
| within | Nested admin hierarchy from immediate container up to region |
| anchors | Economic anchor types — immediate, local, and reachable |
| metro | Dominant city/town anchor with distance and direction |
| context | Human-readable location description in the country's default language |
| country | Country metadata (name, code, flag, currency) |
Returns an SVG QR code for a coordinate. The code encodes the hyperlocal address channel, the nearest place name, lat/lng, and the dominant metro anchor — everything needed to identify and share a physical location in a single scan.
image/svg+xml and cacheable for 24 hours.
3.8667° N · 11.5167° E · CM · range 1100 m
Parameters
| Param | Type | Note |
|---|---|---|
| cc | string | ISO 3166-1 alpha-2 (e.g. CM) |
| lat | number | -90 to 90 |
| lng | number | -180 to 180 |
| range | number | Pooling radius in metres (50–50,000). Controls address tier precision. |
Range presets
| Label | range= | Use case |
|---|---|---|
| Spot | 50 | Indoor floor, kiosk |
| Block | 200 | Street segment, city block |
| Quarter | 500 | Neighbourhood, trading cluster |
| Town | 1100 | Town centre, district (default) |
| City | 5000 | Metro area, city-wide |
| Region | 25000 | Province, wide-area |
QR payload (newline-separated)
6b099229 ← hyperlocal address channel
Etoa-Meki ← nearest place name
3.8667,11.5167 ← lat,lng
Yaoundé ← metro anchor (omitted if none)
Example request
GET /qr/CM/3.8667/11.5167/1100
Example usage in HTML
<img src="https://api.bwendi.com/qr/CM/3.8667/11.5167/1100"
alt="Location QR code"
width="200" height="200">
Response
An image/svg+xml document. Embed directly in <img src="...">, <object>, or save as .svg. Cached at the edge for 24 hours.
Returns the caller's IP-derived geolocation — coordinates, country code, city, and full country object — using Cloudflare's edge geolocation. The gateway enriches every request with x-cf-* headers before forwarding to the origin.
/country/:lat/:lng with device GPS for precise country resolution.Example request
GET /geo
Example response
{
"lat": 47.2017,
"lng": 7.5665,
"cc": "CH",
"city": "Zuchwil",
"country": {
"name": "Switzerland",
"localName": "Schweiz",
"code": "CH",
"callingCode": "41",
"flag": "🇨🇭",
"lang": "de",
"currency": {
"symbol": "Fr.",
"code": "CHF",
"name": "Franc",
"localName": "Schweizer Franken"
}
}
}
Fields
| Field | Description |
|---|---|
| lat | IP-derived latitude (4 d.p.), or null |
| lng | IP-derived longitude (4 d.p.), or null |
| cc | ISO 3166-1 alpha-2 country code, or null |
| city | City name from Cloudflare, or null |
| country | Full country object (name, currency, flag, lang, callingCode), or null |
Server health check. Returns process uptime, memory, and loaded-country count.
{
"status": "ok",
"uptime": 84210,
"countries_loaded": 47,
"memory_mb": 128,
"timestamp": "2026-03-12T12:00:00.000Z"
}
List all available countries, or get detailed info for one.
// GET /countries
{ "built": ["AD","AE","CM","NG", ...], "built_count": 47 }
// GET /countries/CM
{ "country_code": "CM", "has_data": true, "db_size_mb": 12.4 }
Returns a map of every built country code to its default language, plus the sorted list of unique language codes.
{
"languages": {
"CM": "fr",
"NG": "en",
"ET": "am",
"...": "..."
},
"country_count": 174,
"unique_languages": ["am", "ar", "de", "en", "es", "fr", "..." ],
"unique_count": 72
}
Language Codes
Pass any of these codes as ?lang=xx on /context to translate all place names and admin labels. Each translation costs +1 credit.
| Code | Language | Code | Language | Code | Language |
|---|---|---|---|---|---|
am | Amharic | ar | Arabic | az | Azerbaijani |
be | Belarusian | bg | Bulgarian | bn | Bengali |
bs | Bosnian | ca | Catalan | cs | Czech |
da | Danish | de | Deutsch | el | Greek |
en | English | es | Español | fa | Persian |
fi | Finnish | fr | Français | ha | Hausa |
he | Hebrew | hi | Hindi | hr | Croatian |
ht | Haitian Creole | hu | Hungarian | hy | Armenian |
id | Indonesian | is | Icelandic | it | Italiano |
ja | Japanese | ka | Georgian | kk | Kazakh |
kl | Greenlandic | km | Khmer | ko | Korean |
lb | Luxembourgish | lo | Lao | lt | Lithuanian |
lv | Latvian | mg | Malagasy | mk | Macedonian |
mn | Mongolian | ms | Malay | mt | Maltese |
my | Burmese | ne | Nepali | nl | Dutch |
no | Norwegian | om | Oromo | pl | Polish |
pt | Português | ro | Romanian | ru | Russian |
rw | Kinyarwanda | si | Sinhala | sk | Slovak |
sl | Slovenian | sm | Samoan | so | Somali |
sq | Albanian | sr | Serbian | sv | Swedish |
sw | Swahili | ta | Tamil | tg | Tajik |
th | Thai | ti | Tigrinya | tk | Turkmen |
tl | Filipino | tr | Turkish | uk | Ukrainian |
ur | Urdu | uz | Uzbek | vi | Vietnamese |
yo | Yoruba | zh | Chinese | zu | Zulu |
Credits
One credit ≈ one API call. Modifiers stack on top of the base cost. Buy credits →
fr, ar, sw)gravity and weight scores on every resolved placewithin admin chainhubs for the 80/20 primary market list.?lang and ?expand.verifyUrl for verify.bwendi.com.Response Headers
Every response includes these headers so you can track usage in real time.
| Header | Value |
|---|---|
| x-credit-cost | Credits charged for this request (0–21) |
| x-balance-remaining | Credits left on your key (−1 = unlimited) |
| x-resolved-cc | Auto-detected country code (when CC was omitted) |
Error Codes
All errors return JSON with a message field.
| Status | Meaning |
|---|---|
| 400 | Invalid parameters |
| 401 | Missing API key |
| 402 | Insufficient credits |
| 403 | Invalid or inactive key |
| 404 | Country not found or no nearby places |
| 429 | Rate limit exceeded (60 req/min default) |
| 500 | Server error |
message field so you know exactly what went wrong.