Search jobs
Live LinkedIn job postings by company, keyword, and filters.
https://api.up2data.ai/v1/search/jobsProvide at least one of company_url, keywords, or filters; a request with none of them (or only empty values) returns an empty, unbilled result that still counts against the search quota. Several keywords match any of them. Results come most recent first. Without filters.locations the search is worldwide; each location is resolved to LinkedIn's closest geo match. description_snippet is filled for as many jobs as the live call has time for and omitted for the rest; use job enrich for the full posting. meta.reason is success, or empty_result when nothing matched.
Counts as 1 request against the 300/min per-key limit and 1 search against the 20/hour per-organization search quota. See Rate limits.
Send many as batch operation items (operation search.jobs); up to 500 jobs per item, 1 credit per job returned. Unlike this sync endpoint, an empty batch item is rejected instead of returning a free empty result. See the batch endpoint.
#Request
| Field | Type | Notes |
|---|---|---|
company_url | string | Restrict to one company's jobs. Company page URL or slug. |
keywords | string[] | Matched against the posting; several match any of them. |
filters.locations | string[] | Place names. An unknown place answers 400. |
filters.seniority | string[] | Enum per item: entry, senior, manager, director, executive. senior and manager both map to LinkedIn's mid-senior level. |
filters.function | string[] | Job function names, e.g. Engineering, Sales, Information Technology, Marketing. An unknown function answers 400. |
filters.workplace_type | string[] | Enum per item: remote, hybrid, onsite. |
filters.posted_within_days | integer | Days back from now. 0 or less means no date limit. |
max_results | integer | Default 25. 1 to 100; a hard cap on jobs returned by this call and so on cost. Wins over per_page for the page size. |
per_page | integer | 1 to 100. Jobs per page, used to work out where a page starts; defaults to max_results. |
page | integer | Default 1. Page of per_page jobs to return. |
pagination_token | string | Opaque token for a page; used instead of page. |
#Call it
curl -X POST "https://api.up2data.ai/v1/search/jobs" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"keywords": [
"golang"
],
"filters": {
"workplace_type": [
"remote"
],
"posted_within_days": 7
},
"max_results": 25
}'import requests
url = "https://api.up2data.ai/v1/search/jobs"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
}
payload = {
"keywords": [
"golang"
],
"filters": {
"workplace_type": [
"remote"
],
"posted_within_days": 7
},
"max_results": 25
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())const url = "https://api.up2data.ai/v1/search/jobs";
const headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
};
const body = {
"keywords": [
"golang"
],
"filters": {
"workplace_type": [
"remote"
],
"posted_within_days": 7
},
"max_results": 25
};
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
});
const data = await response.json();
console.log(data);package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
url := "https://api.up2data.ai/v1/search/jobs"
body := bytes.NewBufferString(`{
"keywords": [
"golang"
],
"filters": {
"workplace_type": [
"remote"
],
"posted_within_days": 7
},
"max_results": 25
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
panic(err)
}
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
fmt.Println(string(respBody))
}#Response
{
"data": {
"jobs": [{
"url": "https://www.linkedin.com/jobs/view/4470130770",
"title": "Full-Stack Agentic Engineer (focus on Backend)",
"company": { "name": "Apoddo", "url": "https://www.linkedin.com/company/apoddo-llp", "linkedin_id": "11571939", "logo_url": "https://media.licdn.com/dms/image/v2/D4D0BAQExample/company-logo_200_200/0/apoddo_llp_logo" },
"location": "Serbia (Remote)",
"posted_at": "2026-09-25T09:22:27.000Z",
"workplace_type": "remote",
"description_snippet": "Apoddo is a software development-as-a-service company...",
"job_id": "4470130770",
"employment_type": "full-time"
}]
},
"meta": { "creditsUsed": 25, "creditsRemaining": 98394, "billed": true, "reason": "success", "requestId": "req_example", "latencyMs": 21000 }
}#Errors
| Status | Type | When | Billed |
|---|---|---|---|
| 400 | invalid_request | Unknown field, bad enum value, unknown function, or a location or company that matches nothing. | No |
| 401 | invalid_api_key | Missing, malformed, or revoked key. | No |
| 402 | insufficient_credits | Balance can't cover max_results jobs. | No |
| 429 | rate_limited | Over the 300 requests/min limit, or the 20 searches/hour per-organization quota. Honor Retry-After. | No |
| 500 | upstream_error | LinkedIn rejected the search query, or something broke on the server side. | No |
| 504 | upstream_timeout | The live scrape didn't complete in time. | No |
See the Errors guide for every error type this version can return.