jobr.pro's Free XML Job Feed: A Field Guide

CleanJobData Engineering

TL;DR

jobr.pro's feed.xml is a genuinely open, no-key, no-approval XML job feed — unlike iCIMS's or Indeed's gated feeds covered elsewhere in this series. It supports three params: role (free text), location (a fixed 19-country allowlist, matched by name or ISO2 code — not free text, not ISO2-only), and limit (up to 500). It deliberately never exposes a real employer application URL in the XML — every listing's applyUrl points to a jobr.pro redirect route that resolves the real destination server-side. There's no salary field and no structured location, just a display string.

Most of the "free XML job feed" landscape we've covered in this series turns out to be gated — iCIMS's Standard XML Feed needs vendor approval and OAuth2, Indeed's needs a signed partner agreement and a six-week review. jobr.pro's feed is a genuine exception: it's a public endpoint, no key, no application process, live the moment you request it.

The Endpoint

The feed lives at jobr.pro/feed.xml:

curl "https://jobr.pro/feed.xml?role=engineer&location=US&limit=100"

Three query parameters, deliberately kept to just these three:

  • role — free-text role/title filter, passed through as-is with no validation.
  • locationnot free text. It only matches against a fixed allowlist of 19 countries (US, CA, GB, AU, NZ, IE, DE, NL, CH, SE, DK, NO, FR, ES, IT, AT, BE, FI, PT), and it accepts either the full country name ("United States") or the ISO2 code ("US"), case-insensitively — so it's not ISO2-only either. A value that doesn't match anything on that list isn't rejected with an error; it silently falls back to searching all 19 allowed countries. That's worth knowing, since a typo'd or unsupported location won't fail loudly — it just quietly stops filtering.
  • limit — how many jobs to return, default 100, clamped between 1 and 500 (not rejected if you pass more — just capped).

That's the whole parameter surface. There's no pagination cursor, no sort option, no city- or state-level filtering, and no date-range filter beyond what's baked into the feed itself (see freshness below) — this is intentionally a narrower, simpler feed than a full REST API, not a competitor to one.

The Response Shape

<?xml version="1.0" encoding="UTF-8"?>
<jobs source="https://jobr.pro" generatedAt="2026-08-13T12:00:00Z">
  <job>
    <id>a1b2c3</id>
    <title>Senior Backend Engineer</title>
    <description><![CDATA[<p>We're looking for...</p>]]></description>
    <location>Austin, TX</location>
    <type>Full-time</type>
    <company>
      <name>Acme Inc</name>
      <website>https://acme.com</website>
      <logo>https://acme.com/logo.png</logo>
    </company>
    <datePosted>2026-08-10T09:00:00Z</datePosted>
    <applyUrl>https://jobr.pro/r/a1b2c3</applyUrl>
  </job>
</jobs>

Field by field:

  • <jobs> — the root element, carrying source and generatedAt attributes so a consuming system can tell where the feed came from and how fresh this particular fetch is.
  • <id> — the stable per-job identifier. Safe dedup key.
  • <description> — wrapped in CDATA, so HTML content comes through without needing escaping on your end.
  • <type>, company.website, and company.logo — all omitted entirely from the XML when empty, rather than present as empty tags. Don't assume every <job> has all three; check for their presence before reading them.
  • <datePosted> — also omitted if the underlying job has no valid published date, rather than emitting a placeholder.
  • No salary field anywhere. Same gap as iCIMS's feed — if your product needs compensation data, this feed structurally can't supply it.
  • No structured location. <location> is a single display string, not split into city/state/country — the same free-text problem covered in why location normalization is harder than it looks.

The Interesting Part: applyUrl Is Never the Real URL

This is the detail worth understanding before you build around this feed. Every job's <applyUrl> points to a https://jobr.pro/r/{id} redirect route — a page on jobr.pro itself, never the employer's actual application page directly.

That redirect route looks up the real application_url server-side, validates it's a safe http:/https: link, and renders a landing page with a link on to the real employer URL — worth noting it's a rendered page a human clicks through, not an automatic HTTP redirect a script would silently follow. It also shows an expiry notice if the job has since gone stale. The real destination URL is never present anywhere in the static XML a bulk consumer reads — a scraper pulling the feed and parsing it offline literally cannot extract the real apply links without individually requesting each /r/{id} page.

If you're building something that needs to display or store the real employer application URL (rather than just linking users through to apply), this matters: you can't extract it from the feed itself. If your use case is just "let a user click through to apply," the redirect is transparent and this is a non-issue — click the link, land on the real page, same outcome as any other feed.

Freshness and Caching

The route itself computes on every request (dynamic: "force-dynamic" — no Next.js ISR caching layer), but it's cached for one hour at the Cloudflare edge in front of it via a Cache-Control response header — so freshness is handled by Cloudflare, not by Next.js, and most real-world requests hit that edge cache rather than triggering a live server computation. Jobs are filtered server-side to postings from the last 14 days and sorted by published, newest first. That 14-day window means this isn't a feed for pulling a full historical archive — it's a rolling window of recent postings, which fits its stated purpose (per the endpoint's own doc comment): "Public job feed for third-party job boards/aggregators to syndicate from."

Access and Rate Limits

Fully open — no API key, no signup, no approval process. There's no application-level rate limiting either; abuse mitigation happens at the infrastructure edge rather than in the feed's own logic. That's genuinely rare among the feeds covered in this series — worth using responsibly (reasonable polling intervals, respecting the hourly cache window rather than hammering the endpoint) precisely because it isn't gated the way most comparable feeds are.

How This Compares

jobr.pro feed.xmliCIMS Standard FeedIndeed Job Sync XML
AccessOpen, no keyVendor approval + OAuth2Partner agreement, ~6-week review
DirectionOutbound (their listings, to you)OutboundInbound (your listings, to them)
Salary fieldNoNoN/A
Structured locationNo (display string)Yes (city/state/country)N/A
RefreshHourly3x dailyN/A
Apply URLRedirect route, real URL hiddenDirectN/A

When This Is Enough

If you're building a small aggregator, a niche job board that wants to backfill listings, or a bot/tool that needs a quick, no-friction source of recent postings without an approval process, jobr.pro's feed does exactly what it says: open access, a simple three-parameter filter, hourly freshness.

When It Isn't

The moment you need salary data, structured location for real filtering, the actual employer application URL rather than a redirect, or coverage beyond one job board's own listings, you're back to the pattern covered throughout this series — reconciling multiple sources into one schema yourself, or using a normalized data API like CleanJobData that sources directly from employer ATS platforms with parsed salary and structured city/state/country built in.

Test it with live job data in the CleanJobData Playground or explore the API Documentation.