Public Job API

Öffentliche REST-Schnittstelle für Karriereseiten, Job-Boards und Partner-Integrationen – Stellenliste mit Paginierung und Filtern, Detailabruf, Bewerbung.

Öffentliche REST-Schnittstelle für Karriereseiten, Job-Boards und Partner-Integrationen. Alle hier dokumentierten Endpoints sind ohne Authentifizierung erreichbar.

Schnellstart

# Erste Seite der offenen Stellen von "regrooter"
curl -s "https://api.regrooter.de/v1/jobs/regrooter?page=0&size=20"
{
  "content": [ { "id": 339, "title": "Senior Java Entwickler (m/w/d)", "...": "..." } ],
  "page": 0,
  "size": 20,
  "totalElements": 137,
  "totalPages": 7,
  "first": true,
  "last": false,
  "sort": "createdAt,desc"
}

Alle Seiten durchlaufen:

page=0
while :; do
  body=$(curl -s "https://api.regrooter.de/v1/jobs/regrooter?page=$page&size=100")
  echo "$body" | jq -r '.content[] | .canonicalId'
  [ "$(echo "$body" | jq -r '.last')" = "true" ] && break
  page=$((page + 1))
done

Grundbegriffe

BegriffBedeutung
companySlugStabile Kennung einer Karriereseite, z. B. regrooter. Wird von Regrooter vergeben und ändert sich nicht.
jobSlug (canonicalId)Stabile Kennung einer einzelnen Stellenanzeige, z. B. senior-java-entwickler-hamburg-339. Wird für Detailabruf und Bewerbung verwendet.
PublicationVeröffentlichung einer Stelle auf einem Kanal. Diese API liefert ausschließlich die Veröffentlichungen auf dem Kanal WEBSITE (Karriereseite).
aktivEine Stelle erscheint in der Liste, wenn ihre Publication aktiv ist, die Karriereseite aktiv ist und validThrough in der Zukunft liegt oder leer ist.

Sichtbarkeitsregeln, die serverseitig erzwungen werden und über die API nicht umgangen werden können:

  • Interne VMS-Anfragen (vmsOnly) erscheinen nie.
  • Gehaltsangaben werden nur ausgeliefert, wenn die Stelle sie freigibt (showSalaryOnJobAdd). Andernfalls ist salary null.
  • E-Mail und Telefonnummer des Ansprechpartners werden nur ausgeliefert, wenn die Karriereseite das erlaubt. Andernfalls sind die Felder null, während Name und Avatar bestehen bleiben.

CORS und Aufrufmuster

Direkte Aufrufe aus dem Browser einer fremden Domain werden vom Server abgelehnt.

Die API setzt Access-Control-Allow-Origin nur für die Regrooter-Domains und für Kundendomains, die als Custom Domain registriert und verifiziert sind. Für eine Integration bedeutet das:

MusterFunktioniertHinweis
Server-zu-Server (PHP, Node, Python, CMS-Plugin, Cronjob)Empfohlen. CORS ist irrelevant, Antworten lassen sich cachen.
Browser-Fetch von eigener DomainWird blockiert, solange die Domain nicht bei Regrooter registriert ist.
Browser-Fetch von registrierter Custom DomainRegistrierung über Regrooter anfragen.

Die praktikable Variante für eine Agentur ist ein dünner Proxy in der eigenen Anwendung: der Server ruft die API auf, cached die Antwort und liefert sie an das eigene Frontend aus.

Stellenliste (paginiert)

GET /v1/jobs/{companySlug}

Liefert die aktiven Stellen einer Karriereseite als Pagination-Envelope.

Pfadparameter

NameTypBeschreibung
companySlugstringSlug der Karriereseite

Query-Parameter

NameTypDefaultBeschreibung
pageinteger00-basierter Seitenindex
sizeinteger10Treffer pro Seite, erlaubt 1100
sortstringcreatedAt,descfeld[,asc|desc]. Felder: createdAt, publishDate, title
titlestringTeilstring-Suche im Stellentitel, Groß-/Kleinschreibung egal
salaryintegerMindestgehalt. Trifft, wenn das Maximum der Stelle ≥ Wert ist (bzw. das Minimum, falls kein Maximum gepflegt ist)
latnumberBreitengrad des Suchmittelpunkts (WGS84)
lonnumberLängengrad des Suchmittelpunkts (WGS84)
radiusinteger25Umkreis in Metern
industriesintegerBranchen-IDs, siehe Filterwerte
contractsenumContractType
senioritiesenumJobSeniority
workplacesenumWorkplaceType
employmentsenumEmploymentType
workschedulesenumWorkSchedule

Mehrwertige Parameter werden als wiederholter Schlüssel übergeben, nicht kommasepariert:

?contracts=PERMANENT&contracts=FREELANCE&industries=12&industries=15

Umkreissuche greift nur, wenn lat, lon und radius gemeinsam gesetzt sind. Ein einzelnes lat ohne lon wird ignoriert. Stellen ohne hinterlegten Standort fallen bei aktiver Umkreissuche aus dem Ergebnis.

Alle Filter werden mit UND verknüpft, Werte innerhalb eines mehrwertigen Filters mit ODER.

Antwort 200

{
  "content": [
    {
      "id": 339,
      "title": "Senior Java Entwickler (m/w/d)",
      "canonicalId": "senior-java-entwickler-hamburg-339",
      "description": "<p>Für unseren Kunden suchen wir …</p>",
      "publishDate": "2026-08-14T09:12:00",
      "validThrough": "2026-11-14T00:00:00",
      "publicationStatus": "PUBLISHED",
      "workplaceType": "HYBRID",
      "employmentType": "FULL_TIME",
      "contractType": "PERMANENT",
      "workSchedule": "FLEXTIME",
      "industryName": "IT und Softwareentwicklung",
      "jobUri": "https://regrooter.de/jobs/regrooter/senior-java-entwickler-hamburg-339",
      "salary": {
        "salaryFrequency": "YEARLY",
        "currency": "EUR",
        "minSalary": 70000,
        "maxSalary": 90000,
        "showSalaryOnJobAdd": true
      },
      "location": {
        "id": 2911298,
        "city": "Hamburg",
        "state": "Hamburg",
        "cityState": "Hamburg, Hamburg",
        "county": "Hamburg",
        "countryCode": "DE",
        "zip": "20095",
        "lat": 53.5511,
        "lon": 9.9937
      },
      "company": {
        "companyName": "Regrooter GmbH",
        "companySlug": "regrooter",
        "companyLogoUrl": "https://cdn.regrooter.de/logos/regrooter.png"
      },
      "pointOfContact": {
        "firstname": "Max",
        "lastname": "Mustermann",
        "fullname": "Max Mustermann",
        "email": "[email protected]",
        "phonenumber": "+49 40 1234567",
        "avatarUrl": "https://cdn.regrooter.de/avatars/platzhalter.png"
      }
    }
  ],
  "page": 0,
  "size": 10,
  "totalElements": 137,
  "totalPages": 14,
  "first": true,
  "last": false,
  "sort": "createdAt,desc"
}

Hinweise zur Paginierung

  • Seiten sind 0-basiert: die erste Seite ist page=0.
  • Zum Beenden einer Schleife last auswerten, nicht content.length.
  • Eine Seite hinter dem letzten Treffer liefert 200 mit leerem content und korrektem totalElements, nicht 404.
  • Die Sortierung ist stabil: bei gleichem Sortierwert entscheidet die Publication-ID absteigend. Ein Datensatz kann dadurch beim Durchblättern nicht doppelt oder gar nicht erscheinen.
  • totalElements berücksichtigt alle gesetzten Filter.
  • Stellen, die sich während des Durchblätterns ändern, können die Seitenaufteilung verschieben. Für einen konsistenten Vollabzug empfiehlt sich sort=createdAt,desc mit size=100.

Statuscodes

CodeBedeutung
200Seite mit Treffern, ggf. leer
400page negativ, size außerhalb 1–100, oder unbekanntes sort-Feld / unbekannte Richtung
404Kein aktives Karriereseiten-Setting für diesen Slug

Einzelne Stelle

GET /v1/jobs/{companySlug}/{jobSlug}

Liefert eine einzelne Stelle inklusive vollständiger Beschreibung. Das Antwortobjekt ist ein Job ohne Envelope.

curl -s "https://api.regrooter.de/v1/jobs/regrooter/senior-java-entwickler-hamburg-339"

Abgelaufene und zurückgezogene Stellen werden bewusst weiter ausgeliefert, damit bereits verlinkte oder indexierte Detailseiten kein 404 erzeugen. Der Endpoint liefert also auch Stellen, die in der Liste aus Stellenliste nicht mehr auftauchen.

Zwei Felder zeigen den Zustand an, beide sollten vor der Anzeige geprüft werden:

SignalBedeutung
validThrough liegt in der VergangenheitDie Anzeige ist abgelaufen
publicationStatus ist nicht PUBLISHEDDie Anzeige wurde zurückgezogen oder geschlossen

Trifft eines davon zu, sollte die Seite als „Stelle nicht mehr verfügbar" dargestellt und keine Bewerbung mehr angeboten werden.

Der companySlug im Pfad muss zur Stelle gehören — ein Job eines anderen Kunden ist unter dem eigenen Slug nicht abrufbar.

CodeBedeutung
200Die Stelle
404Kein Job mit diesem Slug, oder der Job gehört nicht zu diesem companySlug

Filterwerte

GET /v1/jobs/filters/{companySlug}

Liefert die Filteroptionen für eine Karriereseite: die für diese Company freigeschalteten Branchen sowie die Enum-Filter mit deutschen Labels. Damit lässt sich eine Filter-UI aufbauen, ohne Werte fest zu verdrahten.

{
  "industries": [
    { "id": 12, "name": "IT und Softwareentwicklung", "level": 1, "sortOrder": 10 }
  ],
  "seniorities":   [ { "key": "SENIOR", "label": "Senior" } ],
  "contracts":     [ { "key": "PERMANENT", "label": "Festanstellung" } ],
  "workplaces":    [ { "key": "HYBRID", "label": "Hybrid" } ],
  "employments":   [ { "key": "FULL_TIME", "label": "Vollzeit" } ],
  "workschedules": [ { "key": "FLEXTIME", "label": "FLEXTIME" } ]
}

key ist der Wert, der an die Stellenliste übergeben wird; label ist die Anzeigebezeichnung. Für Werte ohne hinterlegte Übersetzung entspricht label dem key.

Die Branchenliste ist company-spezifisch — industries-IDs aus einer anderen Karriereseite treffen unter Umständen nichts.

Eine Variante über die technische Company-ID steht unter GET /v1/jobs/filters/company/{companyId} bereit.

Standorte

GET /v1/locations

Liefert die größeren Städte mit Koordinaten. Aus diesem Ergebnis stammen die lat/lon-Werte für die Umkreissuche.

[ { "id": 2911298, "city": "Hamburg", "state": "Hamburg", "countryCode": "DE", "lat": 53.5511, "lon": 9.9937 } ]

Die Liste ist umfangreich und ändert sich selten — einmal täglich abrufen und lokal vorhalten.

Branding

GET /v1/branding/{companySlug}

Liefert Name, Logo, Hero-Bild und Farbschema. Nützlich, um eine eingebettete Jobliste im Erscheinungsbild des Kunden darzustellen.

{
  "name": "Regrooter GmbH",
  "logo": "https://cdn.regrooter.de/logos/regrooter.png",
  "heroImage": "https://cdn.regrooter.de/hero/regrooter.jpg",
  "heroHeadline": "Arbeiten bei Regrooter",
  "heroSubtext": "Finde deinen nächsten Schritt.",
  "theme": { "primary": "#1a73e8", "secondary": "#0c4a6e" },
  "companySlug": "regrooter",
  "customDomain": "jobs.beispielkunde.de"
}

Zusätzlich existiert GET /v1/branding?domain=jobs.beispielkunde.de zur Auflösung einer Custom Domain auf den zugehörigen companySlug.

Schlanke Liste für Sitemaps

GET /v1/seo/jobs/{companySlug}

Liefert alle aktiven Job-Slugs mit Änderungsdatum, ohne Paginierung und ohne Beschreibungstexte. Für Sitemap-Generierung und Delta-Abgleich deutlich günstiger als die vollständige Stellenliste.

[ { "canonicalId": "senior-java-entwickler-hamburg-339", "updatedAt": "2026-09-02T11:04:00" } ]

Bewerbung einreichen

POST /v1/jobs/{companySlug}/{jobSlug}/apply
Content-Type: multipart/form-data
FeldTypPflichtBeschreibung
beliebiger FeldnameDateijaBewerbungsunterlagen. Mehrere Dateien sind erlaubt; alle Datei-Parts werden übernommen.
frc-captcha-responsestringjaToken aus dem Friendly-Captcha-Widget

Attributionsdaten werden aus dem Query-String übernommen: source, utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_id, referrer/referer. Zusätzlich wird der Referer-Header ausgewertet.

curl -X POST \
  "https://api.regrooter.de/v1/jobs/regrooter/senior-java-entwickler-hamburg-339/apply?utm_source=agentur-xy&utm_medium=jobboard" \
  -F "[email protected]" \
  -F "frc-captcha-response=<token>"
Einschränkungen, die bei der Integration einzuplanen sind
  • Der Endpoint antwortet mit 204 No Contentauch dann, wenn das Captcha-Token ungültig ist und die Bewerbung verworfen wird. Aus der Antwort lässt sich nicht ableiten, ob die Bewerbung angekommen ist.
  • Ein gültiges Friendly-Captcha-Token erfordert das Widget im Browser des Bewerbers. Eine rein serverseitige Einreichung ist ohne gesonderte Absprache nicht möglich.
Für eine automatisierte Einreichung von Kandidaten bitte vorab mit Regrooter abstimmen.

View- und Click-Tracking

POST /v1/track-view/jobs
Content-Type: application/json

Optional; meldet einen Seitenaufruf einer Stellenanzeige an die Reporting-Auswertung des Kunden.

{
  "tenant": "regrooter",
  "slug": "senior-java-entwickler-hamburg-339",
  "utm_source": "agentur-xy",
  "utm_medium": "jobboard",
  "utm_campaign": "herbst-2026",
  "source": "agentur-xy",
  "referer": "https://jobs.agentur-xy.de/"
}

tenant und slug sind Pflicht. Antwort: 204 bei Erfolg, 404, wenn die Stelle nicht gefunden wurde. Für Klicks auf einen ausgehenden Link steht POST /v1/track-view/jobs/click mit identischem Body bereit.

Datenmodelle

PagedResponse

FeldTypBeschreibung
contentarrayTreffer der Seite, nie null
pageinteger0-basierter Index der gelieferten Seite
sizeintegerAngeforderte Seitengröße, nicht die tatsächliche Länge von content
totalElementsintegerGesamttrefferzahl über alle Seiten, unter Berücksichtigung aller Filter
totalPagesintegerAnzahl Seiten, 0 bei keinem Treffer
firstbooleantrue auf der ersten Seite
lastbooleantrue auf der letzten Seite — Abbruchkriterium für Schleifen
sortstringTatsächlich angewendete Sortierung

Job

FeldTypBeschreibung
idintegerTechnische Job-ID. Für Verlinkungen canonicalId verwenden.
titlestringStellentitel
canonicalIdstringSlug der Stelle, Eingabe für Detailabruf und Bewerbung
descriptionstringStellenbeschreibung als HTML
publishDatedatetimeVeröffentlichungszeitpunkt, ISO-8601 ohne Zeitzone (Europe/Berlin)
validThroughdatetimeEnde der Gültigkeit, null = unbefristet
publicationStatusenumPublicationStatus
workplaceTypeenumWorkplaceType
employmentTypeenumEmploymentType
contractTypeenumContractType
workScheduleenumWorkSchedule
industryNamestringBranchenbezeichnung
jobUristringKanonische URL der Stelle. Für SEO als rel="canonical" setzen, wenn die Stelle auf einer fremden Seite gespiegelt wird.
salaryobjectSalary oder null, wenn das Gehalt nicht veröffentlicht wird
locationobjectLocation
companyobjectCompany
pointOfContactobjectContact oder null

Salary

FeldTypBeschreibung
salaryFrequencyenumSalaryFrequency
currencystringISO-4217, z. B. EUR
minSalaryintegerUntergrenze, kann null sein
maxSalaryintegerObergrenze, kann null sein
showSalaryOnJobAddbooleanImmer true, wenn das Objekt geliefert wird

Location

FeldTypBeschreibung
idintegerStandort-ID, passend zu /v1/locations
citystringOrt
statestringBundesland
cityStatestringKombinierte Anzeige, z. B. Hamburg, Hamburg
countystringRegierungsbezirk / Kreis
countryCodestringISO-3166-1 alpha-2
zipstringPostleitzahl
lat, lonnumberKoordinaten (WGS84)

Company

FeldTypBeschreibung
companyNamestringAnzeigename
companySlugstringSlug der Karriereseite
companyLogoUrlstringLogo-URL, kann null sein

Contact

Ansprechpartner der Stelle. E-Mail und Telefon erscheinen nur, wenn die Karriereseite sie freigibt.

FeldTypBeschreibung
firstname, lastnamestringName
fullnamestringAbgeleitet aus Vor- und Nachname
emailstringnull, wenn nicht freigegeben
phonenumberstringnull, wenn nicht freigegeben
avatarUrlstringProfilbild, kann null sein

Enum-Referenz

Enum-Werte werden als Großbuchstaben-Konstanten übertragen und bei Filtern exakt so erwartet. Anzeigelabels liefert der Endpoint Filterwerte.

ContractType

WertBedeutung
PERMANENTFestanstellung
FIXED_TERMZeitlich befristet
FREELANCEFreelancer
TEMP_AGENCYArbeitnehmerüberlassung
INTERNSHIPPraktikum
WORKING_STUDENTWerkstudent
APPRENTICESHIPAusbildung

EmploymentType

WertBedeutung
FULL_TIMEVollzeit
PART_TIMETeilzeit
MINI_JOBMinijob
OTHERAndere

WorkplaceType

WertBedeutung
ONSITEVor Ort
HYBRIDHybrid
REMOTERemote

JobSeniority

WertBedeutung
INTERNPraktikant
JUNIORBerufseinsteiger
PROFESSIONALFachkraft
SENIORSpezialist
LEADTeamlead
MANAGERManager
EXECUTIVEGeschäftsführung

WorkSchedule

WertBedeutung
REGULARRegelarbeitszeit
SHIF_WORKSchichtarbeit (Schreibweise historisch bedingt)
FLEXTIMEGleitzeit
ON_CALLAuf Abruf

SalaryFrequency

WertBedeutung
HOURLYpro Stunde
DAILYpro Tag
WEEKLYpro Woche
MONTHLYpro Monat
YEARLYpro Jahr

PublicationStatus

Status der Veröffentlichung. Über die Public API erscheinen praktisch ausschließlich aktive Veröffentlichungen; der Wert wird der Vollständigkeit halber mitgeliefert.

WertBedeutung
DRAFTEntwurf
PENDINGVeröffentlichung läuft
PUBLISHEDVeröffentlicht
FAILEDVeröffentlichung fehlgeschlagen
PARTIALLY_FAILEDTeilweise fehlgeschlagen
UNPUBLISHEDZurückgezogen
CLOSEDGeschlossen
ARCHIVEDArchiviert

Fehlerbehandlung

Fehler werden einheitlich als JSON zurückgegeben:

{
  "errorCode": "COMPANY_NOT_FOUND",
  "message": "Company with slug 'gibtsnicht' not found",
  "status": 404
}
StatuserrorCodeTypische Ursache
400BAD_REQUESTpage negativ, size außerhalb 1–100, unbekanntes sort-Feld
404COMPANY_NOT_FOUNDUnbekannter companySlug oder jobSlug
500INTERNAL_SERVER_ERRORServerseitiger Fehler

message ist für Menschen gedacht und kann sich ändern — Auswertungen bitte auf status und errorCode stützen.

Betriebshinweise

Caching. Stellenanzeigen ändern sich selten. Empfohlen: Listen 5–15 Minuten, Detailseiten 15–60 Minuten, /v1/locations und die Filterwerte bis zu 24 Stunden serverseitig cachen. Die API sendet aktuell keine ETag- oder Cache-Control-Header.

Lastverhalten. Es gibt derzeit kein hartes Rate-Limit. Für einen Vollabzug size=100 verwenden und Requests seriell absetzen; bitte nicht parallel über alle Seiten fahren. Regrooter behält sich vor, Rate-Limits einzuführen — dann würden sie mit 429 und Retry-After beantwortet.

Delta-Abgleich. Für einen periodischen Sync ist /v1/seo/jobs/{companySlug} der günstigste Einstieg: updatedAt je Slug abgleichen und nur geänderte Stellen im Detail nachladen.

SEO. Wird eine Stelle auf einer fremden Seite gespiegelt, sollte jobUri als rel="canonical" gesetzt werden, damit die Original-Anzeige nicht als Duplicate Content abgewertet wird.

Zeitangaben. Alle Datumsfelder sind ISO-8601 ohne Zeitzonen-Offset und beziehen sich auf Europe/Berlin.

Support. [email protected]