Developers
Jobvetta API
REST access to live, vetted India jobs.
Search live India job openings gathered from official employer sources and fetch full structured job details. This guide shows the complete request flow, response shape, and copy-ready examples.
Get a key
Sign in and your key is on the dashboard's API page. One key works for both the REST API and the MCP server. Free during early access.
Get your API key →Base URL and authentication
All REST endpoints begin with:
Send your key in the Authorization header on every request. Keep it server-side and load it from an environment variable rather than committing it to source control.
Authorization: Bearer YOUR_KEY
Search jobs
Returns live jobs in India. All query parameters are optional, so GET /jobs returns the newest matches.
| Parameter | Type | Description |
|---|---|---|
| q | string | Role, skill, or company keywords, such as react developer. |
| location | string | Indian city, town, or state, such as Bengaluru or Karnataka. |
| days | integer | Only jobs first posted within the last N days. Accepted range: 1–365. |
| limit | integer | Number of jobs to return. Default: 10. Range: 1–20. |
Code examples
Each example searches for React roles in Bengaluru and then fetches the full details for the first result.
cURL
# Search jobs curl --get "https://api.jobvetta.com/v1/jobs" \ --header "Authorization: Bearer $JOBVETTA_API_KEY" \ --data-urlencode "q=react developer" \ --data-urlencode "location=Bengaluru" \ --data-urlencode "days=7" \ --data-urlencode "limit=10" # Fetch full details using a job_id returned by search curl --header "Authorization: Bearer $JOBVETTA_API_KEY" \ "https://api.jobvetta.com/v1/jobs/JOB_ID"
Python
import os
import requests
base_url = "https://api.jobvetta.com/v1"
headers = {
"Authorization": f"Bearer {os.environ['JOBVETTA_API_KEY']}"
}
params = {
"q": "react developer",
"location": "Bengaluru",
"days": 7,
"limit": 10,
}
response = requests.get(
f"{base_url}/jobs", headers=headers, params=params, timeout=30
)
response.raise_for_status()
results = response.json()
for job in results["jobs"]:
print(job["title"], "—", job["company"], job["url"])
if results["jobs"]:
job_id = results["jobs"][0]["job_id"]
detail = requests.get(
f"{base_url}/jobs/{job_id}", headers=headers, timeout=30
)
detail.raise_for_status()
print(detail.json())TypeScript
type JobSummary = {
job_id: string;
title: string;
company: string;
location: string;
work_model?: string;
employment_type?: string;
salary?: unknown;
url: string;
};
type SearchResponse = {
total: number;
jobs: JobSummary[];
};
const apiKey = process.env.JOBVETTA_API_KEY;
if (!apiKey) throw new Error("JOBVETTA_API_KEY is not set");
const baseUrl = "https://api.jobvetta.com/v1";
const params = new URLSearchParams({
q: "react developer",
location: "Bengaluru",
days: "7",
limit: "10",
});
const headers = { Authorization: `Bearer ${apiKey}` };
const response = await fetch(`${baseUrl}/jobs?${params}`, { headers });
if (!response.ok) {
throw new Error(`Job search failed (${response.status}): ${await response.text()}`);
}
const results = (await response.json()) as SearchResponse;
for (const job of results.jobs) {
console.log(`${job.title} — ${job.company}: ${job.url}`);
}
if (results.jobs.length > 0) {
const detailResponse = await fetch(
`${baseUrl}/jobs/${encodeURIComponent(results.jobs[0].job_id)}`,
{ headers },
);
if (!detailResponse.ok) {
throw new Error(`Job detail failed (${detailResponse.status})`);
}
console.log(await detailResponse.json());
}Search response
A successful search returns an estimated match count and an array containing up to limit jobs:
{
"total": 128,
"jobs": [
{
"job_id": "699f03f36a66e34ef2a55fb6_loc0",
"title": "React JS Developer",
"company": "Concentrix",
"location": "Bangalore, Karnataka, India",
"work_model": "On-site",
"employment_type": "Full-time",
"url": "https://www.jobvetta.com/jobs/699f03f36a66e34ef2a55fb6_loc0"
}
]
}
total is the search engine's estimated number of matches. Optional fields may be null or omitted when an employer does not provide them.
Fetch one job
Pass a job_id from the search response to retrieve the full structured record.
{
"job_id": "699f03f36a66e34ef2a55fb6_loc0",
"title": "React JS Developer",
"normalized_title": "React JS Developer",
"company": "Concentrix",
"location": "Bangalore, Karnataka, India",
"description": "Concentrix seeks a React JS Developer...",
"work_model": "On-site",
"employment_type": "Full-time",
"experience_level": "Senior",
"minimum_qualifications": [
"4+ years of experience with React",
"Proficiency in JavaScript and TypeScript"
],
"skills_required": ["React", "Redux", "TypeScript", "Jest"],
"responsibilities": ["Build and deliver scalable web applications"],
"salary_min": null,
"salary_max": null,
"salary_currency": null,
"created_at": 1765284099,
"last_seen_date": 1784727113,
"url": "https://www.jobvetta.com/jobs/699f03f36a66e34ef2a55fb6_loc0"
}
The detail response can include additional fields such as benefits, preferred qualifications, education, schedule, travel, sponsorship, and remote-work metadata. Unix timestamps are expressed in seconds.
Limits
50 calls per key per day, shared between the API and the MCP server, resetting at midnight UTC. Search returns at most 20 jobs per call. Coverage is India only.
Authenticated responses include X-RateLimit-Limit and X-RateLimit-Remaining headers. A rate-limited response also includes Retry-After.
Errors
Errors are JSON objects with an error message:
{
"error": "Invalid or missing API key. Get one at https://www.jobvetta.com/dashboard"
}
- 401
- The API key is missing or invalid.
- 404
- The job does not exist or is no longer active.
- 429
- The shared daily request limit has been reached.
- 502
- The job search backend is temporarily unavailable.
For AI assistants
If you are connecting an AI assistant rather than writing code, the MCP server exposes the same job search to Claude, Cursor, and any MCP client.