# First request carries the filters and batch size.
curl -X POST "https://connect.jobo.world/api/jobs/feed/managed" \
-H "X-Api-Key: $JOBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"locations": [{"country": "United Kingdom"}], "batch_size": 1000}'
# Continuation requests carry ONLY the cursor.
curl -X POST "https://connect.jobo.world/api/jobs/feed/managed" \
-H "X-Api-Key: $JOBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"cursor": "eyJ2IjoxLCJ..."}'import requests
url = "https://connect.jobo.world/api/jobs/feed/managed"
payload = {
"locations": [
{
"country": "<string>",
"region": "<string>",
"city": "<string>"
}
],
"work_models": [],
"employment_types": [],
"experience_levels": [],
"languages": ["<string>"],
"posted_after": "2023-11-07T05:31:56Z",
"include_reactivated": False,
"description_format": "markdown",
"updated_after": "2023-11-07T05:31:56Z",
"cursor": "<string>",
"batch_size": 1000
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
locations: [{country: '<string>', region: '<string>', city: '<string>'}],
work_models: [],
employment_types: [],
experience_levels: [],
languages: ['<string>'],
posted_after: '2023-11-07T05:31:56Z',
include_reactivated: false,
description_format: 'markdown',
updated_after: '2023-11-07T05:31:56Z',
cursor: '<string>',
batch_size: 1000
})
};
fetch('https://connect.jobo.world/api/jobs/feed/managed', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://connect.jobo.world/api/jobs/feed/managed",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'locations' => [
[
'country' => '<string>',
'region' => '<string>',
'city' => '<string>'
]
],
'work_models' => [
],
'employment_types' => [
],
'experience_levels' => [
],
'languages' => [
'<string>'
],
'posted_after' => '2023-11-07T05:31:56Z',
'include_reactivated' => false,
'description_format' => 'markdown',
'updated_after' => '2023-11-07T05:31:56Z',
'cursor' => '<string>',
'batch_size' => 1000
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://connect.jobo.world/api/jobs/feed/managed"
payload := strings.NewReader("{\n \"locations\": [\n {\n \"country\": \"<string>\",\n \"region\": \"<string>\",\n \"city\": \"<string>\"\n }\n ],\n \"work_models\": [],\n \"employment_types\": [],\n \"experience_levels\": [],\n \"languages\": [\n \"<string>\"\n ],\n \"posted_after\": \"2023-11-07T05:31:56Z\",\n \"include_reactivated\": false,\n \"description_format\": \"markdown\",\n \"updated_after\": \"2023-11-07T05:31:56Z\",\n \"cursor\": \"<string>\",\n \"batch_size\": 1000\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://connect.jobo.world/api/jobs/feed/managed")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"locations\": [\n {\n \"country\": \"<string>\",\n \"region\": \"<string>\",\n \"city\": \"<string>\"\n }\n ],\n \"work_models\": [],\n \"employment_types\": [],\n \"experience_levels\": [],\n \"languages\": [\n \"<string>\"\n ],\n \"posted_after\": \"2023-11-07T05:31:56Z\",\n \"include_reactivated\": false,\n \"description_format\": \"markdown\",\n \"updated_after\": \"2023-11-07T05:31:56Z\",\n \"cursor\": \"<string>\",\n \"batch_size\": 1000\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://connect.jobo.world/api/jobs/feed/managed")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"locations\": [\n {\n \"country\": \"<string>\",\n \"region\": \"<string>\",\n \"city\": \"<string>\"\n }\n ],\n \"work_models\": [],\n \"employment_types\": [],\n \"experience_levels\": [],\n \"languages\": [\n \"<string>\"\n ],\n \"posted_after\": \"2023-11-07T05:31:56Z\",\n \"include_reactivated\": false,\n \"description_format\": \"markdown\",\n \"updated_after\": \"2023-11-07T05:31:56Z\",\n \"cursor\": \"<string>\",\n \"batch_size\": 1000\n}"
response = http.request(request)
puts response.read_body{
"jobs": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"title": "<string>",
"normalized_title": "<string>",
"company": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"website": "<string>",
"logo_url": "<string>",
"summary": "<string>",
"industries": [
"<string>"
],
"categories": [
"<string>"
],
"linkedin_url": "<string>",
"crunchbase_url": "<string>",
"details_url": "<string>"
},
"description": "<string>",
"language": "en",
"summary": "<string>",
"listing_url": "<string>",
"apply_url": "<string>",
"locations": [
{
"location": "<string>",
"city": "<string>",
"region": "<string>",
"country": "<string>",
"latitude": 123,
"longitude": 123
}
],
"compensation": {
"min": 123,
"max": 123,
"currency": "<string>",
"period": "hourly"
},
"employment_type": "Full-time",
"workplace_type": "Remote",
"experience_level": "Intern",
"source": "greenhouse",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"date_posted": "2023-11-07T05:31:56Z",
"valid_through": "2023-11-07T05:31:56Z",
"qualifications": {
"must_have": {
"education": [
"<string>"
],
"certifications": [
"<string>"
],
"skills": [
{
"name": "<string>",
"type": "hard"
}
]
},
"preferred": {
"education": [
"<string>"
],
"certifications": [
"<string>"
],
"skills": [
{
"name": "<string>",
"type": "hard"
}
]
}
},
"responsibilities": [
"<string>"
],
"benefits": [
"<string>"
],
"is_work_auth_required": true,
"is_h1b_sponsor": true,
"is_clearance_required": true,
"external_id": "000123"
}
],
"next_cursor": "<string>",
"has_more": true,
"estimated_total": 123
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}Stream the managed feed
Same batch shape and cursor semantics as POST /api/jobs/feed, but
returns only jobs from companies configured through Managed Job
Scraping in the Jobo portal. Jobo discovers and verifies career sites,
maintains collection, and delivers structured, deduplicated jobs through
a private, white-label-ready feed. Requires a customer API key — sandbox
and marketplace keys have no managed job sources and receive 403.
Differences from the main feed:
- No
sourcesfilter. You choose the companies in the Jobo portal, so filtering by their ATS provider on top of that is redundant. - No
stable_scanflag. This endpoint always pages by keyset, which is inherently stable. created_atreflects the exact ingestion time (the main feed reports the time the job first became searchable, which can lag ingestion by however long the job spent in Jobo’s pipeline).
# First request carries the filters and batch size.
curl -X POST "https://connect.jobo.world/api/jobs/feed/managed" \
-H "X-Api-Key: $JOBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"locations": [{"country": "United Kingdom"}], "batch_size": 1000}'
# Continuation requests carry ONLY the cursor.
curl -X POST "https://connect.jobo.world/api/jobs/feed/managed" \
-H "X-Api-Key: $JOBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"cursor": "eyJ2IjoxLCJ..."}'import requests
url = "https://connect.jobo.world/api/jobs/feed/managed"
payload = {
"locations": [
{
"country": "<string>",
"region": "<string>",
"city": "<string>"
}
],
"work_models": [],
"employment_types": [],
"experience_levels": [],
"languages": ["<string>"],
"posted_after": "2023-11-07T05:31:56Z",
"include_reactivated": False,
"description_format": "markdown",
"updated_after": "2023-11-07T05:31:56Z",
"cursor": "<string>",
"batch_size": 1000
}
headers = {
"X-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
locations: [{country: '<string>', region: '<string>', city: '<string>'}],
work_models: [],
employment_types: [],
experience_levels: [],
languages: ['<string>'],
posted_after: '2023-11-07T05:31:56Z',
include_reactivated: false,
description_format: 'markdown',
updated_after: '2023-11-07T05:31:56Z',
cursor: '<string>',
batch_size: 1000
})
};
fetch('https://connect.jobo.world/api/jobs/feed/managed', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://connect.jobo.world/api/jobs/feed/managed",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'locations' => [
[
'country' => '<string>',
'region' => '<string>',
'city' => '<string>'
]
],
'work_models' => [
],
'employment_types' => [
],
'experience_levels' => [
],
'languages' => [
'<string>'
],
'posted_after' => '2023-11-07T05:31:56Z',
'include_reactivated' => false,
'description_format' => 'markdown',
'updated_after' => '2023-11-07T05:31:56Z',
'cursor' => '<string>',
'batch_size' => 1000
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://connect.jobo.world/api/jobs/feed/managed"
payload := strings.NewReader("{\n \"locations\": [\n {\n \"country\": \"<string>\",\n \"region\": \"<string>\",\n \"city\": \"<string>\"\n }\n ],\n \"work_models\": [],\n \"employment_types\": [],\n \"experience_levels\": [],\n \"languages\": [\n \"<string>\"\n ],\n \"posted_after\": \"2023-11-07T05:31:56Z\",\n \"include_reactivated\": false,\n \"description_format\": \"markdown\",\n \"updated_after\": \"2023-11-07T05:31:56Z\",\n \"cursor\": \"<string>\",\n \"batch_size\": 1000\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://connect.jobo.world/api/jobs/feed/managed")
.header("X-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"locations\": [\n {\n \"country\": \"<string>\",\n \"region\": \"<string>\",\n \"city\": \"<string>\"\n }\n ],\n \"work_models\": [],\n \"employment_types\": [],\n \"experience_levels\": [],\n \"languages\": [\n \"<string>\"\n ],\n \"posted_after\": \"2023-11-07T05:31:56Z\",\n \"include_reactivated\": false,\n \"description_format\": \"markdown\",\n \"updated_after\": \"2023-11-07T05:31:56Z\",\n \"cursor\": \"<string>\",\n \"batch_size\": 1000\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://connect.jobo.world/api/jobs/feed/managed")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"locations\": [\n {\n \"country\": \"<string>\",\n \"region\": \"<string>\",\n \"city\": \"<string>\"\n }\n ],\n \"work_models\": [],\n \"employment_types\": [],\n \"experience_levels\": [],\n \"languages\": [\n \"<string>\"\n ],\n \"posted_after\": \"2023-11-07T05:31:56Z\",\n \"include_reactivated\": false,\n \"description_format\": \"markdown\",\n \"updated_after\": \"2023-11-07T05:31:56Z\",\n \"cursor\": \"<string>\",\n \"batch_size\": 1000\n}"
response = http.request(request)
puts response.read_body{
"jobs": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"title": "<string>",
"normalized_title": "<string>",
"company": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"website": "<string>",
"logo_url": "<string>",
"summary": "<string>",
"industries": [
"<string>"
],
"categories": [
"<string>"
],
"linkedin_url": "<string>",
"crunchbase_url": "<string>",
"details_url": "<string>"
},
"description": "<string>",
"language": "en",
"summary": "<string>",
"listing_url": "<string>",
"apply_url": "<string>",
"locations": [
{
"location": "<string>",
"city": "<string>",
"region": "<string>",
"country": "<string>",
"latitude": 123,
"longitude": 123
}
],
"compensation": {
"min": 123,
"max": 123,
"currency": "<string>",
"period": "hourly"
},
"employment_type": "Full-time",
"workplace_type": "Remote",
"experience_level": "Intern",
"source": "greenhouse",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"date_posted": "2023-11-07T05:31:56Z",
"valid_through": "2023-11-07T05:31:56Z",
"qualifications": {
"must_have": {
"education": [
"<string>"
],
"certifications": [
"<string>"
],
"skills": [
{
"name": "<string>",
"type": "hard"
}
]
},
"preferred": {
"education": [
"<string>"
],
"certifications": [
"<string>"
],
"skills": [
{
"name": "<string>",
"type": "hard"
}
]
}
},
"responsibilities": [
"<string>"
],
"benefits": [
"<string>"
],
"is_work_auth_required": true,
"is_h1b_sponsor": true,
"is_clearance_required": true,
"external_id": "000123"
}
],
"next_cursor": "<string>",
"has_more": true,
"estimated_total": 123
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"api_version": "2026-08-31"
}Authorizations
API key provided by Jobo
Body
Cursor-paginated export request for the managed job feed. Same filters
as JobFeedRequest minus sources (you choose the companies in the
portal) and stable_scan (this endpoint always pages by keyset). The
cursor preserves the filters and batch size from the first request;
start a new scan to change them.
Structured location filters. A job matches if it matches ANY entry.
Each entry routes to its most-specific populated level (city, then
region, then country) and every level needs country. Use
{"country": "Remote"} to match remote jobs.
Show child attributes
Show child attributes
Filter by work model: remote, hybrid, onsite. null = all jobs
remote, hybrid, onsite Filter by employment type. null = all jobs
full-time, part-time, contract, internship, freelance, temporary Filter by experience level. null = all jobs
intern, entry, mid, senior, lead, executive Filter by description language, as ISO 639-1 codes (en, de, fr). Language names and locales (English, en-US) are mapped to their code. null = all jobs.
Only return jobs posted after this date
Also return jobs that expired and were reactivated (rediscovered
and re-indexed) on or after posted_after. A reactivated job keeps
its original posting and creation dates, so posted_after alone
never re-delivers it.
Only changes the posted_after filter: it has no effect without
posted_after, and an updated_after sync does not need it —
reactivation re-indexes the job, so updated_after already returns
it. When both posted_after and updated_after are set, a job
must match both.
Format of each job's description. markdown (default) returns it
as stored. html renders it to HTML on the fly: raw HTML in the
source is escaped and only http(s), mailto and relative URLs
are kept. Read from every request, including cursor continuations.
markdown, html Only return jobs created or updated after this UTC timestamp —
incremental watermark for syncs. Includes jobs that expired and
were reactivated in the window, so syncs that use updated_after
don't need include_reactivated.
Opaque cursor from next_cursor. Omit on the first request. The
cursor embeds the filters and batch size, so values sent alongside
it are ignored — except batch_size, which a continuation may
reduce but never raise.
1 <= x <= 1000Response
Batch of jobs from managed job sources with cursor for next page

