Skip to content
Code examples

Guides

Code examples

The API is plain HTTPS and JSON, so any HTTP client works. These examples use each language's standard tools.

Every request needs your API key in the Authorization header, and every error uses the same envelope, so the pattern is the same in every language: send the request, check the status, then read the JSON. See Errors for retry guidance.

cURL

curl -G "https://developers.ubhub.mn/v1/geocode" \
  --data-urlencode "q=Sukhbaatar Square" \
  -d limit=5 \
  -H "Authorization: Bearer YOUR_API_KEY"

JavaScript

Plain fetch, no dependencies. Works in Node.js 18+, Deno, Bun and server-side frameworks.

const params = new URLSearchParams({
  q: "Sukhbaatar Square",
  limit: "5",
});

const response = await fetch(`https://developers.ubhub.mn/v1/geocode?${params}`, {
  headers: { Authorization: `Bearer ${process.env.GEO_API_KEY}` },
});
const body = await response.json();

if (!response.ok) {
  // Every error uses the same envelope: { error: { code, message, details } }
  throw new Error(`${body.error.code}: ${body.error.message}`);
}

for (const place of body.results) {
  console.log(place.name, place.latitude, place.longitude);
}

TypeScript

The same requests with response types. The types mirror the API reference; you can also generate them from the OpenAPI schema with any OpenAPI type generator.

type GeocodeResult = {
  id: string;
  name: string;
  address: string | null;
  latitude: number;
  longitude: number;
  type: string;
  distance_meters?: number; // reverse lookups only
};
type GeocodeResponse = { query: string; results: GeocodeResult[]; count: number };

type ApiError = { error: { code: string; message: string; details?: Record<string, unknown> } };

const params = new URLSearchParams({
  q: "Sukhbaatar Square",
  limit: "5",
});

const response = await fetch(`https://developers.ubhub.mn/v1/geocode?${params}`, {
  headers: { Authorization: `Bearer ${process.env.GEO_API_KEY}` },
});
if (!response.ok) {
  const { error } = (await response.json()) as ApiError;
  throw new Error(`${error.code}: ${error.message}`);
}
const body = (await response.json()) as GeocodeResponse;

for (const place of body.results) {
  console.log(place.name, place.latitude, place.longitude);
}

Python

Using httpx (pip install httpx); requests works the same way.

import os

import httpx

response = httpx.get(
    "https://developers.ubhub.mn/v1/geocode",
    params={"q": "Sukhbaatar Square", "limit": 5},
    headers={"Authorization": f"Bearer {os.environ['GEO_API_KEY']}"},
    timeout=10,
)
body = response.json()
if response.is_error:
    raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")

for place in body["results"]:
    print(place["name"], place["latitude"], place["longitude"])

Flutter / Dart

Using the http package (dart pub add http).

Do not ship keys in apps

Anything inside a mobile app can be extracted. In Flutter apps, call your own backend and let it call the API with the key.
import 'dart:convert';

import 'package:http/http.dart' as http;

/// Call the API from your backend, or from an app through your own server:
/// never ship an API key inside a mobile app.
Future<void> main() async {
  const apiKey = String.fromEnvironment('GEO_API_KEY');
  final uri = Uri.parse('https://developers.ubhub.mn/v1/geocode').replace(
    queryParameters: {'q': 'Sukhbaatar Square', 'limit': '5'},
  );
  final response = await http.get(uri, headers: {'Authorization': 'Bearer $apiKey'});
  final body = jsonDecode(response.body) as Map<String, dynamic>;
  if (response.statusCode != 200) {
    throw Exception('${body['error']['code']}: ${body['error']['message']}');
  }

  for (final place in body['results'] as List<dynamic>) {
    print('${place['name']}: ${place['latitude']}, ${place['longitude']}');
  }
}