Jobs APIjobs.lk ↗
Search Sri Lanka job vacancies, retrieve detailed listings, and browse categories via the TopJobs.lk API. Includes employer email, closing dates, and apply links.
What is the Jobs API?
The jobs.lk API provides access to job vacancy data from TopJobs.lk, Sri Lanka's primary online job portal, through 3 endpoints. Use search_jobs to query openings by keyword or category code, get_job_details to retrieve employer contact email, apply links, and closing dates for a specific vacancy, and list_categories to enumerate all valid category codes for filtered searches.
curl -X POST 'https://api.parse.bot/scraper/38dde6af-0fbb-4015-b446-25b7b99f9fea/search_jobs' \
-H 'X-API-Key: $PARSE_API_KEY' \
-H 'Content-Type: application/json' \
-d '{}'Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace jobs-lk-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
TopJobs Sri Lanka Job Search API Client
Search and retrieve job listings from TopJobs.lk
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Optional, Dict, Any, List
class ParseClient:
"""Client for TopJobs Sri Lanka Job Search API"""
def __init__(self, api_key: Optional[str] = None):
"""Initialize the Parse API client
Args:
api_key: API key for authentication. If not provided, uses PARSE_API_KEY env var
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "38dde6af-0fbb-4015-b446-25b7b99f9fea"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError("API key must be provided or set in PARSE_API_KEY environment variable")
def _call(self, endpoint: str, method: str = "POST", **params) -> Dict[str, Any]:
"""Make an API call to the Parse Bot service
Args:
endpoint: API endpoint name
method: HTTP method (GET or POST)
**params: Query/body parameters
Returns:
API response as dictionary
Raises:
requests.RequestException: If API call fails
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json"
}
try:
if method == "GET":
response = requests.get(url, headers=headers, params=params)
else: # POST
response = requests.post(url, headers=headers, json=params)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"API Error: {e}")
raise
def search_jobs(self, keyword: Optional[str] = None,
category: Optional[str] = None,
page: int = 1) -> Dict[str, Any]:
"""Search for open job vacancies
Args:
keyword: Search keyword (e.g., 'engineer', 'accountant')
category: Job category code (e.g., 'SDQ' for IT roles)
page: Page number for pagination (default: 1)
Returns:
Dictionary containing total_jobs, total_pages, current_page, and jobs list
Raises:
ValueError: If neither keyword nor category is provided
"""
if not keyword and not category:
raise ValueError("At least one of keyword or category must be provided")
params = {}
if keyword:
params["keyword"] = keyword
if category:
params["category"] = category
if page > 1:
params["page"] = page
return self._call("search_jobs", method="POST", **params)
def get_job_details(self, job_ref_no: str) -> Dict[str, Any]:
"""Get detailed information about a specific job vacancy
Args:
job_ref_no: Job reference number (e.g., '1512058')
Returns:
Dictionary containing detailed job information
"""
return self._call("get_job_details", method="GET", job_ref_no=job_ref_no)
def list_categories(self) -> Dict[str, Any]:
"""List all available job categories
Returns:
Dictionary containing list of categories with code and name
"""
return self._call("list_categories", method="GET")
def main():
"""Main function demonstrating practical workflow"""
# Initialize the client
client = ParseClient()
print("=" * 60)
print("TopJobs Sri Lanka Job Search - Practical Workflow")
print("=" * 60)
# Step 1: List available categories
print("\n1. Fetching available job categories...")
try:
categories_response = client.list_categories()
categories = categories_response.get("categories", [])
print(f" Found {len(categories)} job categories")
# Display some sample categories
print("\n Sample categories:")
for category in categories[:5]:
print(f" - {category['code']}: {category['name']}")
except Exception as e:
print(f" Error fetching categories: {e}")
return
# Step 2: Search for IT jobs using keyword
print("\n2. Searching for 'engineer' positions...")
try:
search_response = client.search_jobs(keyword="engineer", page=1)
total_jobs = search_response.get("total_jobs", 0)
jobs = search_response.get("jobs", [])
print(f" Found {total_jobs} total jobs matching 'engineer'")
print(f" Showing {len(jobs)} jobs on current page")
if jobs:
print("\n Top job listings:")
for i, job in enumerate(jobs[:3], 1):
print(f"\n {i}. {job.get('position', 'N/A')}")
print(f" Employer: {job.get('employer', 'N/A')}")
print(f" Location: {job.get('town', 'N/A')}")
print(f" Posted: {job.get('opening_date', 'N/A')}")
print(f" Closing: {job.get('closing_date', 'N/A')}")
except Exception as e:
print(f" Error searching jobs: {e}")
return
# Step 3: Get detailed information for the first job
if jobs:
first_job = jobs[0]
job_ref_no = first_job.get("job_ref_no")
print(f"\n3. Fetching detailed information for job {job_ref_no}...")
try:
job_details = client.get_job_details(job_ref_no)
print(f"\n Job Details:")
print(f" Position: {job_details.get('position', 'N/A')}")
print(f" Employer: {job_details.get('employer', 'N/A')}")
print(f" Location: {job_details.get('location', 'N/A')}")
print(f" Job Type: {job_details.get('job_type', 'N/A')}")
print(f" Closing Date: {job_details.get('closing_date', 'N/A')}")
print(f" Date Posted: {job_details.get('date_posted', 'N/A')}")
if job_details.get('company_email'):
print(f" Company Email: {job_details.get('company_email')}")
locations = job_details.get('locations', [])
if locations:
print(f" Locations: {', '.join(locations)}")
apply_links = job_details.get('apply_links', [])
if apply_links:
print(f"\n Application Links:")
for link in apply_links:
print(f" - {link}")
except Exception as e:
print(f" Error fetching job details: {e}")
# Step 4: Search by category (IT Software)
print("\n4. Searching for IT Software/Database/QA positions...")
try:
category_search = client.search_jobs(category="SDQ", page=1)
category_jobs = category_search.get("jobs", [])
total_category_jobs = category_search.get("total_jobs", 0)
print(f" Found {total_category_jobs} total jobs in IT-Software category")
print(f" Showing {len(category_jobs)} jobs on current page")
if category_jobs:
print("\n Recent postings in this category:")
for i, job in enumerate(category_jobs[:3], 1):
print(f" {i}. {job.get('position', 'N/A')} at {job.get('employer', 'N/A')}")
except Exception as e:
print(f" Error searching by category: {e}")
print("\n" + "=" * 60)
print("Workflow completed successfully!")
print("=" * 60)
if __name__ == "__main__":
main()Search for open job vacancies by keyword and/or job category. Returns a paginated list of job listings with position title, employer, dates, and location. At least one of keyword or category must be provided.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination. |
| keyword | string | Search keyword to find jobs (e.g. 'engineer', 'accountant', 'marketing'). At least one of keyword or category must be provided. |
| category | string | Job category code to filter results. Use list_categories endpoint to get valid codes. Examples: SDQ (IT-Sware/DB/QA/Web/Graphics/GIS), HNS (IT-HWare/Networks/Systems), ACA (Accounting/Auditing/Finance), BAF (Banking & Finance/Insurance), SMM (Sales/Marketing/Merchandising), HAT (HR/Training), COM (Corporate Management/Analysts), OAS (Office Admin/Secretary/Receptionist), CCE (Civil Eng/Interior Design/Architecture), ITT (IT-Telecoms), CUR (Customer Relations/Public Relations), LWT (Logistics/Warehouse/Transport), MAE (Eng-Mech/Auto/Elec), POS (Manufacturing/Operations), MAC (Media/Advert/Communication), HRF (Hotel/Restaurant/Hospitality), HOT (Travel/Tourism), SRF (Sports/Fitness/Recreation), MHN (Medical/Nursing/Healthcare), LEL (Legal/Law), SQC (Supervision/Quality Control), APC (Apparel/Clothing), AIM (Ticketing/Airline/Marine), TAL (Education), RLT (R&D/Science/Research), AGD (Agriculture/Dairy/Environment), SEC (Security), BEC (Fashion/Design/Beauty), IDV (International Development), KPO (KPO/BPO), IME (Imports/Exports). At least one of keyword or category must be provided. |
{
"type": "object",
"fields": {
"jobs": "array of job listing objects with job_ref_no, position, employer, job_description, opening_date, closing_date, town, job_code",
"total_jobs": "integer",
"total_pages": "integer",
"current_page": "integer"
},
"sample": {
"jobs": [
{
"town": "Colombo",
"employer": "Commercial Bank",
"job_code": "0001512058",
"position": "AIOps & Automation Engineer",
"job_ref_no": "1512058",
"closing_date": "Sat Jun 27 2026",
"opening_date": "Sun Jun 14 2026",
"job_description": "Please refer the vacancy"
}
],
"total_jobs": 453,
"total_pages": 1,
"current_page": 1
}
}About the Jobs API
Search and Filter Job Listings
The search_jobs endpoint accepts a keyword (e.g. "engineer", "accountant") and/or a category code to return a paginated list of matching vacancies. At least one of the two parameters is required. Each result object includes job_ref_no, position, employer, job_description, opening_date, closing_date, town, and job_code. Pagination is controlled via the page parameter, with total_jobs, total_pages, and current_page returned alongside the results so you can iterate through large result sets.
Job Detail and Employer Contact
Passing a job_ref_no — obtained from search_jobs results — to get_job_details returns the full record for that vacancy: employer, position, job_type, location, locations (array for multi-location roles), date_posted, closing_date, company_email, and apply_links. The company_email field is particularly useful for direct outreach or recruiter contact workflows, and apply_links provides direct application URLs where the employer has listed them.
Category Codes
The list_categories endpoint takes no inputs and returns an array of objects, each with a code and name. Category codes like SDQ (IT/Software) are passed as the category parameter in search_jobs. Fetching this list first is the recommended approach before running category-filtered searches, since codes are not human-readable.
The Jobs API is a managed, monitored endpoint for jobs.lk — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when jobs.lk changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official jobs.lk API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a Sri Lanka-focused job aggregator that surfaces new TopJobs.lk listings by keyword each day.
- Track closing dates across multiple job categories to alert candidates before deadlines pass.
- Extract company_email fields to build a recruiter contact database segmented by industry category.
- Monitor specific employer names in search_jobs results to watch hiring activity over time.
- Power a category-browse UI by pre-loading all codes and names from list_categories.
- Identify multi-location roles by checking the locations array in get_job_details for vacancies that appear in search results.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.