Skip to content

Entwickler

Kostenlose Jobs-API

Alle aktiven Werkstudentenjobs und Praktika in Deutschland auf workingstudentjobs.de als JSON. Kostenlos, ohne API-Key, ohne Anmeldung, stündlich aktualisiert. Für Job-Apps, Forschung und KI-Agenten, die Studierenden bei der Jobsuche helfen.

Beta bis 31. Oktober 2026: Feldnamen und Werte können bis dahin noch korrigiert werden. Danach bekommt v1 nur noch Ergänzungen.

Maschinenlesbar:OpenAPI-3.1-Spezifikationllms.txt

Schnellstart

Eine GET-Anfrage liefert die 100 neuesten Jobs. Hänge an jede Anfrage ref=deineapp an, damit wir dich vor einer inkompatiblen Änderung erreichen können.

curl
curl "https://www.workingstudentjobs.de/api/v1/jobs?city=berlin&type=working_student&limit=20&ref=myapp"
JavaScript
// Walk every live job, pausing when rate limited.
let url = "https://www.workingstudentjobs.de/api/v1/jobs?limit=300&ref=myapp";
const jobs = [];
while (url) {
  const res = await fetch(url);
  if (res.status === 429) {
    const wait = Number(res.headers.get("Retry-After") ?? 60);
    await new Promise((resolve) => setTimeout(resolve, wait * 1000));
    continue;
  }
  if (!res.ok) throw new Error((await res.json()).error.message);
  const page = await res.json();
  jobs.push(...page.data);
  url = page.links.next;
}
Python
import requests

res = requests.get(
    "https://www.workingstudentjobs.de/api/v1/jobs",
    params={"city": "munich", "language": "en", "ref": "myapp"},
    timeout=30,
)
res.raise_for_status()
for job in res.json()["data"]:
    company = job["company"]["name"] if job["company"] else ""
    print(job["title"], company, job["apply_url"])
Beispielantwort (gekürzt)
{
  "data": [
    {
      "id": "3f6c2a1e-8b4d-4e0a-9c7f-2d5e1b6a9f80",
      "slug": "example-gmbh-working-student-data-analytics-3f6c2a1e",
      "title": "Working Student Data Analytics (m/f/d)",
      "url": "https://www.workingstudentjobs.de/jobs/example-gmbh-working-student-data-analytics-3f6c2a1e",
      "apply_url": "https://www.workingstudentjobs.de/apply/3f6c2a1e-8b4d-4e0a-9c7f-2d5e1b6a9f80?ref=myapp",
      "company": {
        "name": "Example GmbH",
        "slug": "example-gmbh",
        "url": "https://www.workingstudentjobs.de/jobs/at/example-gmbh",
        "logo_url": null,
        "website_domain": "example.com"
      },
      "location": {
        "city": "Berlin",
        "city_slug": "berlin",
        "state": "Berlin",
        "state_code": "BE",
        "country_code": "DE",
        "postal_code": "10115",
        "latitude": 52.52,
        "longitude": 13.405
      },
      "types": [
        "working_student"
      ],
      "field": "tech",
      "sub_field": "data",
      "working_mode": "hybrid",
      "salary": {
        "min": 16,
        "max": 18,
        "currency": "EUR",
        "period": "hour"
      },
      "skills": [
        "SQL",
        "Python",
        "Tableau"
      ],
      "languages": {
        "german": "optional",
        "english": "required"
      },
      "sponsored": false,
      "details": {
        "study_fields": [
          "computer science",
          "statistics"
        ],
        "study_fields_or_comparable": true,
        "study_levels": [
          "bachelor",
          "master"
        ],
        "min_semester": 3,
        "enrolment": "required",
        "german_level": null,
        "english_level": {
          "level": "fluent",
          "cefr": "C1"
        },
        "other_languages": [],
        "hours_per_week": {
          "min": 16,
          "max": 20
        },
        "start": {
          "asap": true,
          "date": null
        },
        "duration_months": {
          "min": 12,
          "max": null
        },
        "internship_type": null,
        "remote_days_max": 2,
        "benefits": [
          "flexible hours",
          "public transport ticket"
        ],
        "cover_letter": "not_needed",
        "transcripts": null,
        "prior_experience": "preferred"
      },
      "posted_at": "2026-10-16T07:12:40.000Z",
      "first_seen_at": "2026-10-16T09:03:11.482Z",
      "expires_at": null
    }
  ],
  "links": {
    "self": "https://www.workingstudentjobs.de/api/v1/jobs?city=berlin&limit=1&ref=myapp",
    "next": "https://www.workingstudentjobs.de/api/v1/jobs?city=berlin&limit=1&ref=myapp&cursor=..."
  },
  "meta": {
    "limit": 1,
    "count": 1,
    "api_version": "1.0-beta"
  }
}

Endpunkte

EndpunktBeschreibung
GET /api/v1/jobsAktive Jobs, neueste zuerst, mit Filtern und Cursor-Seiten.
GET /api/v1/jobs/{id}Ein Job per ID. 301, wenn er mit einer anderen aktiven Anzeige zusammengeführt wurde, 410, wenn er geschlossen ist, 404, wenn es keinen öffentlichen Job mit dieser ID gibt.
GET /api/v1/citiesAlle Städte mit mindestens einem aktiven Job und deren Anzahl. Diese Slugs gelten für den Stadtfilter.
GET /openapi.jsonDie OpenAPI-3.1-Beschreibung aller Endpunkte.

Parameter für /api/v1/jobs

Alle optional. Filter werden mit UND verknüpft, kommagetrennte Werte innerhalb eines Filters mit ODER. Unbekannte Parameter werden ignoriert, ungültige Werte ergeben 400.

ParameterBeschreibung
limitJobs pro Seite, 1 bis 300. Standard 100.
cursorUndurchsichtiges Seiten-Token. Folge links.next, statt es selbst zu bauen.
cityStadt-Slugs, bis zu 20, z. B. berlin,munich. Deutsche Schreibweisen wie muenchen oder koeln funktionieren auch. Unbekannte Slugs ergeben 400 unknown_city.
fieldBereiche: tech, engineering, marketing, finance, operations, sales, hr, consulting, design, research, legal, logistics, education, healthcare, gastronomy-hospitality.
typeworking_student, internship oder beides. Ein Job kann beides sein.
languageen: Englisch reicht, Deutsch wird nicht verlangt. de: Deutsch wird verlangt.
remoteArbeitsmodelle: remote, hybrid, onsite.
sinceNur Jobs, die wir ab diesem ISO-8601-Datum oder -Zeitpunkt zuerst gesehen haben, z. B. 2026-10-15 oder 2026-10-15T08:00:00Z.
refDer Name deiner App, 1 bis 64 Zeichen aus Buchstaben, Ziffern, Punkt, Bindestrich oder Unterstrich. Bleibt an jeder apply_url erhalten.

Felder eines Jobs

Jeder Job in data hat diese Felder. Null heißt, die Anzeige sagt nichts dazu, nie "nein".

FeldBeschreibung
id, slug, titleFeste ID (UUID), URL-Slug und Jobtitel.
urlDie Jobseite auf workingstudentjobs.de.
apply_urlSchicke Bewerber hierhin. Leitet zur Bewerbungsseite des Arbeitgebers weiter, oder zu unserer Jobseite, wenn der Arbeitgeber Bewerbungen per E-Mail annimmt oder der Job geschlossen ist.
companyName, Slug, Unternehmensseite, Logo und Website-Domain. Null, wenn unbekannt.
locationStadt, Slug, Bundesland, Postleitzahl und Koordinaten. Null bei Anzeigen ohne Stadt.
typesworking_student und/oder internship.
field, sub_fieldfield ist einer der Bereiche oben, sub_field eine feinere Einordnung wie controlling.
working_moderemote, hybrid oder onsite. Onsite, wenn die Anzeige nichts sagt.
salarymin, max, Währung und Zeitraum (hour, day, week, month, year). Null, wenn die Anzeige keine Vergütung nennt.
skillsIn der Anzeige genannte Skills.
languagesgerman: required, optional oder not_required. english: required oder not_required.
sponsoredtrue bei einer bezahlten Anzeige. Nur ein Kennzeichen, die Reihenfolge ändert sich dadurch nie.
detailsFakten, die unser Extraktor aus der Anzeige gelesen hat: Studienfächer und -abschlüsse, Mindestsemester, Immatrikulation, Sprachniveaus, Wochenstunden, Start, Dauer, Praktikumsart, Remote-Tage, Benefits, Anschreiben, Zeugnisse, Vorerfahrung. Null, bis der aktuelle Anzeigentext gelesen wurde.
posted_at, first_seen_at, expires_atposted_at (Veröffentlichung durch den Arbeitgeber, sonst first_seen_at), first_seen_at (wann wir den Job zuerst gesehen haben) und expires_at.

Nicht enthalten: die vollständige Stellenbeschreibung und der Link zur Originalanzeige. Zeige den Job mit url und schicke Bewerber zu apply_url.

Seiten und Synchronisierung

Jobs sind nach first_seen_at sortiert, neueste zuerst. Jede Seite hat links.next, eine absolute URL zur nächsten Seite, oder null auf der letzten. Eine Gesamtzahl gibt es nicht. Um eine Kopie aktuell zu halten, frage mit since ab (letzte Abfrage minus 72 Stunden) und entferne Duplikate per id: Jobs, die wir erst prüfen, erscheinen später mit einem früheren first_seen_at. Gehe außerdem einmal am Tag die ganze Liste durch (etwa 70 Anfragen bei limit=300): So erfasst du den seltenen Job, der länger als 72 Stunden in Prüfung war, und siehst, welche Jobs geschlossen sind. Für einen einzelnen Job liefert /api/v1/jobs/{id} den Status 410, sobald er geschlossen ist.

Rate Limits

60 Anfragen pro Minute und IP. Antworten enthalten in der Regel X-RateLimit-Limit, X-RateLimit-Remaining und X-RateLimit-Reset (Unix-Sekunden). Über dem Limit gibt es 429 mit Retry-After: so viele Sekunden warten, dann weitermachen. Antworten aus unserem Edge-Cache können die Header einer früheren Antwort wiederholen.

Caching

Antworten werden bis zu eine Stunde gecacht, so oft kommen neue Jobs dazu. Schicke das ETag als If-None-Match zurück, um ein leeres 304 zu bekommen, wenn sich nichts geändert hat. CORS ist offen (Access-Control-Allow-Origin: *), Browser können die API also direkt aufrufen.

Fehler

Fehler kommen als JSON mit einem festen Code und einer lesbaren Meldung:

JSON
{ "error": { "code": "unknown_city", "message": "Unknown city slug: atlantis. GET /api/v1/cities lists the valid slugs." } }
CodeStatusBeschreibung
invalid_parameter400Ein Parameter hat ein falsches Format oder einen falschen Wert.
invalid_cursor400Der Cursor wurde verändert oder abgeschnitten. Nutze links.next unverändert.
unknown_city400Ein Stadt-Slug existiert nicht. Siehe /api/v1/cities.
not_found404Kein öffentlicher Job mit dieser ID.
method_not_allowed405Nur GET, HEAD und OPTIONS werden unterstützt.
gone410Der Job ist geschlossen.
rate_limited429Mehr als 60 Anfragen pro Minute. Warte Retry-After ab.
internal_error500Bei uns ist etwas schiefgelaufen. Später erneut versuchen.

Verlinkung und ref

Verlinke jeden Job, den du zeigst, mit seiner url oder apply_url. So stimmen die Klickzahlen, die Arbeitgeber sehen, und die Anzeigen kommen weiter. Hänge ref=deineapp an deine Anfragen: Es wird an apply_url weitergegeben, zeigt uns, welche Apps Studierende schicken, und erlaubt uns, dich vor inkompatiblen Änderungen zu kontaktieren. Kein Key, keine Anmeldung.

Versionen und Changelog

Die Version steht im Pfad (/api/v1) und in meta.api_version. Nach der Beta bekommt v1 nur noch Ergänzungen: neue Felder, neue Parameter, neue Werte. Entfernungen und Umbenennungen kommen als v2, und v1 läuft danach noch 6 Monate mit Deprecation- und Sunset-Headern weiter. 17.10.2026: v1 Beta veröffentlicht.

Bedingungen

Kostenlos nutzbar, auch in kommerziellen Apps. Die Anzeigen nicht als konkurrierende Jobbörse neu veröffentlichen und das Rate Limit nicht umgehen. Die vollständigen Bedingungen stehen in Abschnitt 6 unserer Nutzungsbedingungen.

Kontakt

Du baust etwas mit der API, hast ein falsches Feld gefunden oder brauchst einen Filter, den es noch nicht gibt? Schreib an contact@workingstudentjobs.de.