1. Хурдан эхлэх
Нэвтрэх шаардлагагүйТүлхүүр хэрэггүй Бүх endpoint нээлттэй, HTTPS. Үндсэн хаяг:
https://api.bulgan-trip.mn/api/v1
Гурван дуудлагаар бүх зүйл гарна:
# 1. Аймгийн id авна (одоогоор зөвхөн Булган)
curl -s "https://api.bulgan-trip.mn/api/v1/provinces"
# 2. Тэр id-гаар бүх өгөгдлийг нэг дор татна
curl -s "https://api.bulgan-trip.mn/api/v1/sync/snapshot?province=<province_id>&locale=mn"
# 3. Дараа нь өөрчлөгдсөн эсэхийг л шалгана (хөнгөн)
curl -s "https://api.bulgan-trip.mn/api/v1/sync/manifest?province=<province_id>"
2. Өгөгдөл татах
Аймаг — GET /provinces
[
{
"id": "4e3af807-59c2-40dc-8bcc-7d613f2bacdd",
"code": "bulgan",
"name_mn": "Булган",
"name_en": "Bulgan",
"status": "active"
}
]
Одоогоор зөвхөн Булган идэвхтэй. Энэ id-г доорх дуудлагуудад хэрэглэнэ.
Бүх өгөгдөл — GET /sync/snapshot?province=<id>&locale=mn
Жагсаалт барихад энэ нэг дуудлага хангалттай.
Ойролцоогоор 500 КБ, бүх идэвхтэй газар, ангилал, сум, маршрут, арга хэмжээг агуулна. Хариу:
{
"synced_at": "2026-09-29T11:57:38Z",
"province_id": "4e3af807-…",
"categories": [ … 15 ],
"districts": [ … 16 ],
"places": [ … 163 ],
"routes": [ … ],
"events": [ … ]
}
places дотор зөвхөн нийтлэгдсэн, идэвхтэй газрууд ирнэ. Нуусан эсвэл устгасан
газар огт орохгүй тул тусад нь шүүх шаардлагагүй.
Өөрчлөлт шалгах — GET /sync/manifest?province=<id>
{
"province_id": "4e3af807-…",
"updated_at": "2026-09-29T09:14:45Z",
"counts": { "places": 163, "categories": 15, "routes": 2, "events": 3 }
}
Хэдхэн байт. updated_at өөрчлөгдсөн үед л snapshot-ыг дахин татна.
Өдөрт нэг удаа шалгахад хангалттай.
Шүүлттэй жагсаалт — GET /places
Сервер талаас шүүх, хайх, хуудаслах шаардлагатай бол:
GET /places?locale=mn&page=1&page_size=50
GET /places?locale=mn&q=рашаан
GET /places?locale=mn&category=<category_id>
GET /places?locale=mn&lat=48.8125&lng=103.5347 # зайгаар эрэмбэлнэ
GET /places?locale=mn&lat=…&lng=…&radius_km=10 # ойролцоох
Хариу нь { "items": [...], "page": 1, "page_size": 50 }.
lat/lng өгвөл газар бүрт distance_m нэмэгдэнэ — энэ нь
замаар явах бодит зай (шулуун шугамын зай биш), метрээр.
page-ийг үргэлж тодорхой бичиж өгнө үү.
3. Газрын бүтэц
Хамгийн их хэрэглэгддэг талбарууд:
| Талбар | Утга |
|---|---|
id | UUID. Хэзээ ч өөрчлөгдөхгүй. Өөрийн талдаа энэ id-гаар холбоно. |
deeplink | Аппыг нээх холбоос. Доорх 4-р хэсгийг үзнэ үү. |
translations | mn, en, ko, zh, ru түлхүүртэй. Тус бүрд name, short_desc, description. |
location | { "lat": 49.169, "lng": 102.351 } |
cover_image_url | Үндсэн зургийн бүтэн URL. Байхгүй бол null. |
images | Бүх зураг: { id, url, is_cover, sort_order } |
category_id | Snapshot-ийн categories жагсаалттай тааруулна. |
district_id | Сум. districts жагсаалттай тааруулна. |
contacts | [{ "type": "phone", "value": "95826063" }] — дугаар бүр тусдаа мөр. |
price_status | free | paid | unknown |
price_min, price_max | Үнийн хязгаар. price_currency ихэвчлэн MNT. Байхгүй бол null. |
is_24h, open_time, close_time | Ажиллах цаг. Цаг нь "09:00" хэлбэртэй, Улаанбаатарын цагаар. |
slug | Битгий хадгалаарай. Админаас гараар засагддаг тул хожим өөрчлөгдөж болно. Танигчаар зөвхөн id хэрэглэнэ. |
4. Deeplink — аппыг нээх
Газар бүрийн deeplink талбарыг хэвээр нь хэрэглэнэ. Өөрөө URL угсрахгүй.
"deeplink": "https://bulgan-trip.mn/place/4a569305-c799-4529-9d9d-534e6c9e44d5"
Энэ бол энгийн HTTPS холбоос. Хэрэглэгч дээр нь дарахад:
- Bulgan Trip апп суулгаатай бол апп шууд нээгдэж тухайн газрын хуудас гарна;
- суулгаагүй бол ижил холбоос вэб дээр тэр газрыг харуулна.
Сонгох цонх гарахгүй, «апп олдсонгүй» алдаа гарахгүй. Та апп суусан эсэхийг шалгах шаардлагагүй — үүнийг үйлдлийн систем өөрөө хийнэ.
Нээх код
// Android (Kotlin)
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(place.deeplink)))
// iOS (Swift)
if let url = URL(string: place.deeplink) {
UIApplication.shared.open(url)
}
// Flutter
import 'package:url_launcher/url_launcher.dart';
await launchUrl(Uri.parse(place.deeplink), mode: LaunchMode.externalApplication);
<!-- Вэб -->
<a href="https://bulgan-trip.mn/place/4a569305-…">Дэлгэрэнгүй</a>
Анхаарах: холбоосыг WebView дотор биш,
гадаад байдлаар нээнэ үү (Flutter дээр LaunchMode.externalApplication).
WebView дотор нээвэл апп руу шилжихгүй, зүгээр вэб хуудас болж харагдана.
Мөн bulgan-trip:// гэсэн схем байдаг ч
түүнийг хэрэглэхгүй: апп суулгаагүй үед чимээгүй бүтэлгүйтдэг тул fallback байхгүй.
5. Хэл ба зураг
Хэл. Snapshot-д 5 хэлний орчуулга бүгд ирдэг тул хэл солиход дахин татах
шаардлагагүй — translations дотроос сонгоод харуулна. Хэрэв тухайн хэлэнд
орчуулга байхгүй бол mn-г хэрэглэнэ.
Зураг. Бүх зураг https://cdn.bulgan-trip.mn/… дээр байрлана, шууд
ачаалж болно. Хэмжээ өөрчлөх параметр байхгүй тул өөрийн талдаа кэшлэх, багасгахыг
зөвлөе. Зураггүй газар байж болох тул cover_image_url нь null
байх тохиолдлыг заавал бодолцоорой.
6. Дүрэм, хязгаарлалт
| Дүрэм | Учир нь |
|---|---|
GET /places/:id-г давтан бүү дууд | Дуудалт бүр тухайн газрын үзэлтийн тоог нэмдэг тул манай статистик гуйвна. Жагсаалтаа snapshot-оос ав. |
| Өгөгдлийг өөртөө кэшлэ | Контент өдөр бүр өөрчлөгддөггүй. manifest-ээр шалгаад шаардлагатай үед л snapshot тат. |
Танигчаар id хэрэглэ | slug өөрчлөгдөж болно, id өөрчлөгдөхгүй. |
deeplink-ийг хэвээр нь хадгал | Форматыг бид цаашид өөрчилж болно. Талбарыг нь хэрэглэвэл танд өөрчлөлт хэрэггүй. |
| Эх сурвалжаа дурд | Мэдээлэл Bulgan Trip-ээс гаралтай гэдгийг хэрэглэгчдэд ойлгомжтой байлгана уу. |
Дуудлагын хязгаар. IP хаяг тус бүрээр:
| Endpoint | Хязгаар |
|---|---|
/sync/snapshot, /routing/* | минутад 30 |
| бусад бүх нээлттэй endpoint | минутад 240 |
Хэвийн ашиглалтад хүрэхгүй тоо. Хэтэрвэл 429 Too Many Requests буцаах бөгөөд
Retry-After толгойд хэдэн секунд хүлээхийг бичнэ. Жагсаалтаа snapshot-оос
нэг удаа татаад кэшлэвэл энэ хязгаарт огт ойртохгүй. Илүү өндөр хязгаар хэрэгтэй бол
урьдчилж бидэнтэй холбогдоно уу — таныг таних боломжтой болгож өгье.
Түлхүүр авах (санал болгоё)
Бидэнтэй холбогдож API түлхүүр авч болно. Түлхүүртэй бол:
| Endpoint | Түлхүүргүй | Түлхүүртэй |
|---|---|---|
/sync/snapshot, /routing/* | минутад 30 | минутад 120 |
| бусад | минутад 240 | минутад 600 |
Хүсэлт бүрдээ ийн бичнэ:
X-API-Key: bt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Түлхүүргүй ч ажиллана — түлхүүр нь нэвтрэх эрх биш, зөвхөн таныг таних, илүү өгөөмөр хязгаар өгөх зориулалттай. Буруу эсвэл хүчингүй түлхүүр илгээсэн ч хүсэлт татгалзагдахгүй, зүгээр түлхүүргүйтэй адил хязгаартай болно.
Түлхүүрээ нууцлах шаардлагагүй ч бусадтай хуваалцахгүй байхыг хүсье — асуудал гарвал бид тухайн түлхүүрийг л таслах болно.
Нэмэлт. Хүсэлт бүрдээ X-Client толгойд аппынхаа нэр, хувилбарыг
бичиж өгвөл баярлалаа (жишээ нь X-Client: tavan-bogd-app/2.1).
CORS. Хөтчөөс шууд (browser fetch) дуудах бол таны домэйныг манай
зөвшөөрөгдсөн жагсаалтад нэмэх шаардлагатай — бидэнд домэйноо илгээнэ үү. Гар утасны
эсвэл серверийн талын дуудлагад энэ хамаарахгүй.
7. Холбоо барих
Асуулт, домэйн нэмүүлэх, алдаа мэдээлэх: info@bulgan-trip.mn
Апп: bulgan-trip.mn · Ашиглалтын заавар