Developers
Talenthic API
Jobs, employers and opportunity intelligence over a stable JSON HTTP API. Full-text and faceted filters, aggregated market insights, per-key rate limits, OpenAPI 3.1 and a hosted Postman collection.
https://www.talenthic.info/api/public/v1x-api-key header, or?api_key=.
Per-key hourly window. X-RateLimit-* on every response.
Pure application/json. CORS enabled. UTF-8.
Stable /v1. Additive only; breaking changes ship as /v2.
Endpoints
All paths are relative to https://www.talenthic.info/api/public/v1.
/healthpublicLiveness probe and build metadata/jobsSearch jobs: q, country, work_mode, employment_type, seniority, skills, salary_min, visa, days_fresh/jobs/{id}Full job record incl. description, requirements and benefits/companiesEmployer directory with verification and hiring volume/companies/{slug}Single employer profile/companies/{slug}/jobsActive openings for one employer/skillsTrending skills with demand deltas/statsAggregate market stats: volume, freshness, geographyQuickstart
Request an API key, export it as TALENTHIC_KEY, then call the API from any HTTP client.
curl -sS -H "x-api-key: $TALENTHIC_KEY" \ "https://www.talenthic.info/api/public/v1/jobs?q=react&work_mode=remote&limit=20"
const res = await fetch(
"https://www.talenthic.info/api/public/v1/jobs?q=react&work_mode=remote&limit=20",
{ headers: { "x-api-key": process.env.TALENTHIC_KEY } }
);
if (!res.ok) throw new Error(`Talenthic ${res.status}`);
const { data, meta } = await res.json();import os, requests
r = requests.get(
"https://www.talenthic.info/api/public/v1/jobs",
headers={"x-api-key": os.environ["TALENTHIC_KEY"]},
params={"q": "react", "work_mode": "remote", "limit": 20},
timeout=20,
)
r.raise_for_status()
payload = r.json()
jobs, meta = payload["data"], payload.get("meta", {})const BASE = "https://www.talenthic.info/api/public/v1";
export class Talenthic {
constructor(private key: string) {}
private async get<T>(path: string, params: Record<string, string | number> = {}) {
const qs = new URLSearchParams(
Object.entries(params).map(([k, v]) => [k, String(v)]),
);
const res = await fetch(`${BASE}${path}?${qs}`, {
headers: { "x-api-key": this.key },
});
if (res.status === 429) {
const wait = Number(res.headers.get("retry-after") ?? 60);
throw Object.assign(new Error("rate_limited"), { retryAfter: wait });
}
if (!res.ok) throw new Error(`Talenthic ${res.status}`);
return (await res.json()) as T;
}
jobs(params?: Record<string, string | number>) { return this.get("/jobs", params); }
job(id: string) { return this.get(`/jobs/${id}`); }
companies(params?: Record<string, string | number>) { return this.get("/companies", params); }
}Response envelope
Every list endpoint returns data plus meta.
{
"data": [
{
"id": "0f1c…",
"title": "Senior React Engineer",
"company": { "name": "Acme", "slug": "acme", "verified": true },
"location": "Berlin, Germany",
"work_mode": "hybrid",
"employment_type": "full_time",
"salary": { "min": 80000, "max": 110000, "currency": "EUR", "period": "year" },
"skills": ["react", "typescript"],
"url": "https://www.talenthic.info/jobs/senior-react-engineer-at-acme-0f1c…",
"posted_at": "2026-07-21T09:14:00Z"
}
],
"meta": { "limit": 20, "offset": 0, "count": 20 }
}Pagination & limits
Offset pagination with a hard ceiling per page.
limit1–100, default 20.offset0-based. Stop whenmeta.count < limit.X-RateLimit-RemainingRequests left in the current hour window.Retry-AfterSeconds to wait after a 429. Back off exponentially with jitter.days_freshPoll incrementally withdays_fresh=1instead of refetching the full corpus.
Errors
Standard HTTP status codes with a { "error": "…" } envelope.
200Success400Malformed request or invalid parameter401Missing or invalid API key404Resource not found429Rate limit exceeded — respect Retry-After500Internal error — retry with exponential backoff503Service degraded (see /health)
Interactive reference
Powered by the OpenAPI 3.1 spec at /api/public/v1/openapi.json.
