Sri Lankan Bus Fare API
A comprehensive REST API for calculating bus fares across Sri Lanka. Supports multilingual stop name search (Sinhala, English, Tamil) and returns all available routes between two stops with their respective fares.
Annual Bus Fare Revision July 2025
Effective from 04th of July 2025 (from 00.01 hrs.).
Source: ntc.gov.lk
Getting Started
This API is hosted and managed by us. You do not need to install or deploy anything. To start using the API, you only need your API key.
Get Your API Key
Please contact us to obtain your unique sk_live_... API key. You will need this key to authenticate all your requests.
API Reference
Base URL
Calculate Fare
Calculate bus fare between two stops. Returns all available routes with their fares.
Headers
Body Parameters
Example Request
curl -X POST https://v2.srilankabusfare.com/api/fare \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{"start": "Monaragala", "end": "Ampara Bus Stand"}'Success Response
{
"results": [
{
"routeId": "909",
"routeName": "මොණරාගල - අම්පාර බස් නැවතුම්පොල",
"routeNameEnglish": "Monaragala - Ampara Bus Stand",
"routeNameTamil": "மொனராகலை - அம்பாறை பேருந்து நிலையம்",
"category": "Normal",
"startStop": {
"name": "මොණරාගල",
"englishName": "Monaragala",
"tamilName": "மொனராகலை",
"instance": 0
},
"endStop": {
"name": "අම්පාර බස් නැවතුම්පොල",
"englishName": "Ampara Bus Stand",
"tamilName": "அம்பாரா பேருந்து நிලையम்",
"instance": 48
},
"distanceStages": 48,
"fare": 337,
"semiLuxuryFare": 404,
"luxuryFare": 471,
"superLuxuryFare": 538,
"currency": "LKR"
},
{
"routeId": "909A",
"routeName": "මොණරාගල - අම්පාර බස් නැවතුම්පොල",
"routeNameEnglish": "Monaragala - Ampara Bus Stand",
"routeNameTamil": "மொனராகலை - அம்பாறை பேருந்து நிலையம்",
"category": "Semi-Luxury",
"startStop": {
"name": "මොණරාගල",
"englishName": "Monaragala",
"tamilName": "மொனராகலை",
"instance": 0
},
"endStop": {
"name": "අම්පාර බස් නැවතුම්පොල",
"englishName": "Ampara Bus Stand",
"tamilName": "அம்பாரா பேருந்து நிலையம்",
"instance": 48
},
"distanceStages": 48,
"fare": 337,
"semiLuxuryFare": 404,
"luxuryFare": 471,
"superLuxuryFare": 538,
"currency": "LKR"
}
],
"query": {
"start": "Monaragala",
"end": "Ampara Bus Stand"
},
"totalRoutes": 2
}Search Stops
Search for bus stops by name to implement autocomplete. Returns a list of matching stops. Supports partial matching for Sinhala, English, and Tamil names.
Query Parameters
Example Request
curl -X GET "https://v2.srilankabusfare.com/api/stops?q=Nit" \
-H "x-api-key: YOUR_API_KEY"Success Response
{
"results": [
{
"stopId": "507f1f77bcf86cd799439011",
"stopKey": "nittambuwa",
"name": "නිට්ටඹුව",
"englishName": "Nittambuwa",
"tamilName": "நிட்டம்புவ"
}
],
"query": {
"q": "Nit"
},
"count": 1
}Client Integration Guide
1. Get an API Key
You must obtain a valid API key (sk_live_...) to access the API.
2. Configure Your Project
Store the API key securely in your project's environment variables.
BUSFAIR_API_KEY="sk_live_..."3. Make API Requests
You must include the x-api-key header in every request.
Node.js (Fetch)
const API_KEY = process.env.BUSFAIR_API_KEY;
async function getFare(start, end) {
const response = await fetch('https://v2.srilankabusfare.com/api/fare', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY
},
body: JSON.stringify({ start, end })
});
const data = await response.json();
console.log(data);
}Python (Requests)
import os
import requests
api_key = os.getenv('BUSFAIR_API_KEY')
response = requests.post(
'https://v2.srilankabusfare.com/api/fare',
headers={
'Content-Type': 'application/json',
'x-api-key': api_key
},
json={'start': 'Monaragala', 'end': 'Ampara'}
)
print(response.json())Data Model
Routes Object
{
"routeId": "909",
"routeName": "මොණරාගල - අම්පාර", // Sinhala
"routeNameEnglish": "Monaragala - Ampara", // English
"routeNameTamil": "மொனராகலை - அம்பாறை", // Tamil
"category": "Normal",
"startStop": {
"name": "මොණරාගල", // Sinhala
"englishName": "Monaragala", // English
"tamilName": "மொනராகலை", // Tamil
"instance": 0 // Position on route
},
"endStop": {
"name": "අම්පාර බස් නැවතුම්පොල",
"englishName": "Ampara Bus Stand",
"tamilName": "அம්பාරா பேருந்து நிலையම்",
"instance": 48
},
"distanceStages": 48,
"fare": 337,
"semiLuxuryFare": 404,
"luxuryFare": 471,
"superLuxuryFare": 538,
"currency": "LKR"
}Field Descriptions
name / routeName
Primary name in Sinhala script
englishName / routeNameEnglish
English transliteration (optional)
tamilName / routeNameTamil
Tamil translation (optional)
instance
Position of the stop on the route (sequence number)
distanceStages
Number of stages between start and end stops
fare
Base fare for Normal/Regular buses
semiLuxuryFare / luxuryFare / superLuxuryFare
Optional premium fares for different bus categories
React Integration Best Practices
Common React Error
Error: "Objects are not valid as a React child"
This occurs when trying to render multilingual string fields directly without accessing the specific language property.
✅ Correct Usage
All name fields are returned as separate string properties. Access them directly:
// ✅ CORRECT: Access language-specific properties
function FareCard({ route }) {
return (
<div>
<h3>{route.routeNameEnglish}</h3>
<p>From: {route.startStop.englishName}</p>
<p>To: {route.endStop.englishName}</p>
<p>Fare: {route.fare} {route.currency}</p>
</div>
);
}
// ✅ CORRECT: Display multiple languages
function MultilingualStopName({ stop }) {
return (
<div>
<p className="font-sinhala">{stop.name}</p>
<p className="text-sm text-gray-600">{stop.englishName}</p>
<p className="font-tamil text-sm">{stop.tamilName}</p>
</div>
);
}
// ✅ CORRECT: Conditional rendering for optional fields
function RouteName({ route }) {
return (
<h2>
{route.routeNameEnglish || route.routeName || 'Unknown Route'}
</h2>
);
}❌ Incorrect Usage
These patterns will cause React errors:
// ❌ WRONG: Trying to render the entire stop object
function BrokenComponent({ route }) {
return (
<div>
{/* This will cause: "Objects are not valid as a React child" */}
<p>{route.startStop}</p>
</div>
);
}
// ❌ WRONG: Incorrect property access
function AnotherBrokenComponent({ route }) {
return (
<div>
{/* These properties don't exist in the API response */}
<p>{route.startStop.si}</p>
<p>{route.startStop.en}</p>
<p>{route.startStop.ta}</p>
</div>
);
}Language Preference Helper
Use a helper function to select the appropriate language:
// Helper function to get name in preferred language
function getLocalizedName(
item: { name?: string; englishName?: string; tamilName?: string },
preferredLang: 'si' | 'en' | 'ta' = 'en'
): string {
const nameMap = {
si: item.name,
en: item.englishName,
ta: item.tamilName,
};
// Return preferred language or fallback to available names
return nameMap[preferredLang] ||
item.englishName ||
item.name ||
item.tamilName ||
'Unknown';
}
// Usage in component
function SmartFareCard({ route, language = 'en' }) {
return (
<div>
<h3>{getLocalizedName({
name: route.routeName,
englishName: route.routeNameEnglish,
tamilName: route.routeNameTamil
}, language)}</h3>
<p>From: {getLocalizedName(route.startStop, language)}</p>
<p>To: {getLocalizedName(route.endStop, language)}</p>
</div>
);
}