# 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>",
"occupation": {
"id": "esco:8d3e8aaa-791b-4c75-a465-f3f827028f50",
"name": "Registered Nurse",
"category": "Healthcare",
"subcategory": "Nursing",
"isco_code": "2221",
"onet_soc_codes": [
"29-1141.00"
]
},
"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,
"warnings": [
{
"code": "companies_unmatched",
"field": "companies.include",
"message": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"docs_url": "https://jobo.world/docs/guides/sync-a-database",
"api_version": "2026-08-31"
}{
"error": "Invalid or expired API key",
"api_version": "2026-08-31"
}{
"error": "Insufficient credits",
"detail": "This request needs 75 credits ($0.075). Your wallet balance is 12 credits ($0.012). Top up your wallet to continue.",
"group": "JobSearch",
"credits_required": 123,
"credits_balance": 123,
"cost_per_request_usd": 0.075,
"quota_remaining": 123
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"docs_url": "https://jobo.world/docs/guides/sync-a-database",
"api_version": "2026-08-31"
}{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not available in the sandbox",
"status": 404,
"code": "not_available_in_sandbox",
"detail": "Sandbox keys (jbe_test_…) serve job search, job and company lookups, Auto Apply applications, and reading mailboxes. Use a live key for every other endpoint.",
"instance": "/api/jobs/feed/managed"
}{
"error": "Rate limit exceeded",
"detail": "Per-minute JobSearch request limit of 180 exceeded. Try again shortly.",
"retry_after_seconds": 1,
"code": "rate_limit_exceeded",
"group": "JobSearch",
"api_version": "2026-08-31"
}{
"message": "An error occurred",
"detail": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"docs_url": "https://jobo.world/docs/guides/sync-a-database",
"api_version": "2026-08-31"
}Stream the managed feed
Stream the jobs of your managed job sources: the companies you add in the dashboard under Managed Services → Job Scraping. Batches, cursor rules and billing match POST /api/jobs/feed.
Differences from the main feed:
- Pages always run oldest first by
created_at; there is nostable_scanflag. - No
sources, noexclude_lists, and no occupation or company filters (companies,job_categories,industries,company_sizesand the rest). To filter on those, save a Feed Builder feed that starts from Managed feed and stream it withPOST /api/jobs/feed/{feed_id}. updated_afteralso returns every job of a company you added on or after that time, so an incremental sync picks up a new company’s existing jobs.
Needs a customer API key. A sandbox key (jbe_test_…) gets 404 with code not_available_in_sandbox; a credential without a customer account, such as a marketplace key, gets 403.
# 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>",
"occupation": {
"id": "esco:8d3e8aaa-791b-4c75-a465-f3f827028f50",
"name": "Registered Nurse",
"category": "Healthcare",
"subcategory": "Nursing",
"isco_code": "2221",
"onet_soc_codes": [
"29-1141.00"
]
},
"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,
"warnings": [
{
"code": "companies_unmatched",
"field": "companies.include",
"message": "<string>"
}
]
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"docs_url": "https://jobo.world/docs/guides/sync-a-database",
"api_version": "2026-08-31"
}{
"error": "Invalid or expired API key",
"api_version": "2026-08-31"
}{
"error": "Insufficient credits",
"detail": "This request needs 75 credits ($0.075). Your wallet balance is 12 credits ($0.012). Top up your wallet to continue.",
"group": "JobSearch",
"credits_required": 123,
"credits_balance": 123,
"cost_per_request_usd": 0.075,
"quota_remaining": 123
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"docs_url": "https://jobo.world/docs/guides/sync-a-database",
"api_version": "2026-08-31"
}{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not available in the sandbox",
"status": 404,
"code": "not_available_in_sandbox",
"detail": "Sandbox keys (jbe_test_…) serve job search, job and company lookups, Auto Apply applications, and reading mailboxes. Use a live key for every other endpoint.",
"instance": "/api/jobs/feed/managed"
}{
"error": "Rate limit exceeded",
"detail": "Per-minute JobSearch request limit of 180 exceeded. Try again shortly.",
"retry_after_seconds": 1,
"code": "rate_limit_exceeded",
"group": "JobSearch",
"api_version": "2026-08-31"
}{
"message": "An error occurred",
"detail": "<string>"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"code": "<string>",
"docs_url": "https://jobo.world/docs/guides/sync-a-database",
"api_version": "2026-08-31"
}Authorizations
Body
Cursor-paginated request for the managed feed: jobs from the companies you chose under Managed Services → Job Scraping, oldest first as with stable_scan: true. There is no sources, stable_scan, exclude_ list, or occupation and company filter (companies, job_categories, industries, company_sizes, …). For those, stream a saved feed built from your managed feed.
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.
Return jobs whose employer posting time or first-indexed time is on or after this UTC timestamp. Use updated_after when edits matter.
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.
No effect without posted_after. An updated_after sync doesn't need it: updated_after already returns reactivated jobs. With both timestamps 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 Return jobs created, updated or re-indexed on or after this UTC timestamp, including jobs reactivated in that window, plus every job of a company added to your managed job sources since then. The watermark for incremental syncs.
Opaque cursor from next_cursor. Omit on the first request. It keeps the first request's filters and batch_size: filters sent with it are ignored, and batch_size can be lowered but never raised.
1 <= x <= 1000Response
Batch of jobs from managed job sources with cursor for next page
Show child attributes
Show child attributes
Estimated number of jobs the scan will deliver. Present on the first page of a scan only; null on continuation pages. Exact when 1,000 or fewer jobs match; above that an estimate that can run a few percent high.
POST /api/jobs/feed only: non-fatal problems with the first page's request, e.g. a companies entry that matched no company (companies_unmatched, companies_exclude_unmatched, companies_outside_sources). Present on the first page only, and only when there is something to report. The same codes are on the X-Jobo-Warnings response header, comma-separated.
Show child attributes
Show child attributes

