Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__pycache__/
*.py[cod]
*.egg-info/
dist/
build/
.eggs/
58 changes: 57 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ ie Authentifizierung funktioniert über die clientId:

Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben.


**Update:** Falls client_id nicht funktioniert kann man stattdessen "X-API-KEY: jobboerse-jobsuche" verwenden


## Ablauf

Der typische Ablauf ist:

1. **Stellen suchen** via `/pc/v4/jobs` oder `/pc/v4/app/jobs` → `refnr` aus der Antwort merken.
2. **Details abrufen** via `/pc/v4/jobdetails/{base64(refnr)}` (empfohlen) oder `/pc/v3/jobdetails/{base64(refnr)}`.
3. **Arbeitgeberlogo abrufen** via `/ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash}` (sofern im Detail-Response vorhanden).

## Jobbörse

**URL:** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobs
Expand Down Expand Up @@ -121,3 +129,51 @@ jobs=$(curl -m 60 \
-H "X-API-Key: jobboerse-jobsuche" \
'https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobs?angebotsart=1&wo=Berlin&umkreis=200&arbeitszeit=ho;mj&page=1&size=25&pav=false')
```


## Jobdetails

**URL (empfohlen):** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/{encryptedJobCode}

**URL (alternativ):** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v3/jobdetails/{encryptedJobCode}

Der `encryptedJobCode` ist der Base64-kodierte Wert der `refnr` aus der Jobsuche-Antwort.

**Beispiel:** `refnr = 10001-1002716922-S` → `base64(refnr) = MTAwMDEtMTAwMjcxNjkyMi1T`

Die Detail-Antwort enthält u.a.:
- `stellenangebotsTitel` – Titel der Stelle
- `stellenangebotsBeschreibung` – Beschreibung der Stelle
- `referenznummer` – Referenznummer der Stelle
- `arbeitgeberKundennummerHash` – Hash für den Logo-Abruf (kann `null` sein)

### Hinweise zu Sonderfällen

- Manche Stellenanzeigen haben kein `kundennummerHash` in der Suchantwort und kein `arbeitgeberKundennummerHash` in der Detail-Antwort – in diesem Fall steht kein Logo zur Verfügung.
- Externe Stellenanzeigen können ein `externeUrl`-Feld in der Suchantwort enthalten.

### Beispiel:
```bash
refnr="10001-1002716922-S"
encoded=$(python3 -c "import base64; print(base64.b64encode('$refnr'.encode()).decode())")
curl -m 60 \
-H "X-API-Key: jobboerse-jobsuche" \
"https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/$encoded"
```


## Arbeitgeberlogo

**URL:** https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/{kundennummerHash}

Der `kundennummerHash` entspricht dem Feld `arbeitgeberKundennummerHash` aus der Jobdetail-Antwort (URL-kodiert falls nötig, da der Wert `=`-Zeichen enthalten kann).

Gibt `200 image/webp` oder `200 image/png` zurück, wenn ein Logo vorhanden ist.
Gibt `404` zurück, wenn kein Logo für diesen Arbeitgeber hinterlegt ist – dies ist ein normaler Fall, kein Fehler.

### Beispiel:
```bash
curl -m 60 \
-H "X-API-Key: jobboerse-jobsuche" \
"https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA%3D"
```
14 changes: 12 additions & 2 deletions api_example.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@ data=httr::content(data_request)

writeLines(jsonlite::toJSON(data$facetten,pretty=TRUE,auto_unbox=TRUE),paste0(Sys.Date(),"_jobsuche_facetten.json"))

urlLogo="https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/ed/v1/arbeitgeberlogo/arJ0dxbYlPFXeMuZtdZzooRdCOnK2TjUXjLQlkBr-Ew="
dataLogo=httr::content(httr::GET(url=urlLogo, httr::add_headers(.headers=c("X-API-Key"=clientId)), config=httr::config(connecttimeout=60)))
# Jobdetails abrufen: base64(refnr) als Pfadparameter
refnr <- data$stellenangebote[[1]]$refnr
encryptedJobCode <- base64enc::base64encode(charToRaw(refnr))
urlDetails <- paste0("https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/", encryptedJobCode)
details_request <- httr::GET(url=urlDetails, httr::add_headers(.headers=c("X-API-Key"=clientId)),
config=httr::config(connecttimeout=60))
details <- httr::content(details_request)

# Arbeitgeberlogo abrufen (sofern arbeitgeberKundennummerHash vorhanden)
# Endpoint: GET /vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/{kundennummerHash}
# 404 bedeutet: kein Logo vorhanden (kein Fehler)
urlLogo="https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA%3D"
dataLogo=httr::content(httr::GET(url=urlLogo, httr::add_headers(.headers=c("X-API-Key"=clientId)), config=httr::config(connecttimeout=60)))

56 changes: 48 additions & 8 deletions api_example.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import base64
import requests

HEADERS = {
'User-Agent': 'Jobsuche/2.9.2 (de.arbeitsagentur.jobboerse; build:1077; iOS 15.1.0) Alamofire/5.4.4',
'Host': 'rest.arbeitsagentur.de',
'X-API-Key': 'jobboerse-jobsuche',
'Connection': 'keep-alive',
}

def search(what, where):
"""search for jobs. params can be found here: https://jobsuche.api.bund.dev/"""
params = (
Expand All @@ -11,16 +19,48 @@ def search(what, where):
('was', what),
('wo', where),
)
headers = {
'User-Agent': 'Jobsuche/2.9.2 (de.arbeitsagentur.jobboerse; build:1077; iOS 15.1.0) Alamofire/5.4.4',
'Host': 'rest.arbeitsagentur.de',
'X-API-Key': 'jobboerse-jobsuche',
'Connection': 'keep-alive',
}
response = requests.get('https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/app/jobs',
headers=headers, params=params, verify=False)
headers=HEADERS, params=params, verify=False)
return response.json()


def get_job_details(refnr):
"""Retrieve job details by refnr. The refnr is base64-encoded before sending."""
encrypted = base64.b64encode(refnr.encode()).decode()
response = requests.get(
f'https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/{encrypted}',
headers=HEADERS, verify=False)
return response.json()


def get_employer_logo(kundennummer_hash):
"""Retrieve employer logo by arbeitgeberKundennummerHash from job details.
Returns None if no logo is available (404).
"""
import urllib.parse
encoded_hash = urllib.parse.quote(kundennummer_hash, safe='')
response = requests.get(
f'https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/{encoded_hash}',
headers=HEADERS, verify=False)
if response.status_code == 404:
return None
return response.content


result = search("bahn", "berlin")

print(result['stellenangebote'][0]["refnr"])
refnr = result['stellenangebote'][0]["refnr"]
print("refnr:", refnr)

details = get_job_details(refnr)
print("Titel:", details.get("stellenangebotsTitel") or details.get("titel"))

kundennummer_hash = details.get("arbeitgeberKundennummerHash")
if kundennummer_hash:
logo = get_employer_logo(kundennummer_hash)
if logo:
print("Logo gefunden, Größe:", len(logo), "Bytes")
else:
print("Kein Logo für diesen Arbeitgeber vorhanden.")
else:
print("Kein arbeitgeberKundennummerHash – kein Logo verfügbar.")
87 changes: 81 additions & 6 deletions openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: "3.0.0"
info:
description: "Die größte Stellendatenbank Deutschlands durchsuchen, Details zu Stellenanzeigen und Informationen über Arbeitgeber abrufen. <br><br>Die Authentifizierung funktioniert über die clientId:<br><br>clientId: jobboerse-jobsuche<br><br>Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben."
version: "2.0.2"
description: "Die größte Stellendatenbank Deutschlands durchsuchen, Details zu Stellenanzeigen und Informationen über Arbeitgeber abrufen. <br><br>Die Authentifizierung funktioniert über die clientId:<br><br>clientId: jobboerse-jobsuche<br><br>Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben.<br><br>Ablauf: (1) Stellen suchen via /pc/v4/jobs oder /pc/v4/app/jobs → refnr merken. (2) Details abrufen via /pc/v4/jobdetails/{base64(refnr)}. (3) Arbeitgeberlogo abrufen via /ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash} (sofern vorhanden)."
version: "2.1.0"
title: "Arbeitsagentur Jobsuche API"

servers:
Expand Down Expand Up @@ -259,25 +259,74 @@ paths:
required: false


/ed/v1/arbeitgeberlogo/{hashID}:
/pc/v4/jobdetails/{encryptedJobCode}:
get:
summary: Jobdetails (v4)
description: "Abrufen der Details einer Stellenanzeige anhand des Base64-kodierten Referenzwertes (base64(refnr)). Empfohlene Version."
parameters:
- name: encryptedJobCode
in: path
required: true
schema:
type: string
example: MTAwMDEtMTAwMjcxNjkyMi1T
description: "Base64-kodierter Wert der refnr aus der Jobsuche. Beispiel: base64('10001-1002716922-S') = 'MTAwMDEtMTAwMjcxNjkyMi1T'"
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/JobDetails'

/pc/v3/jobdetails/{encryptedJobCode}:
get:
summary: Jobdetails (v3)
description: "Abrufen der Details einer Stellenanzeige anhand des Base64-kodierten Referenzwertes (base64(refnr))."
parameters:
- name: encryptedJobCode
in: path
required: true
schema:
type: string
example: MTAwMDEtMTAwMjcxNjkyMi1T
description: "Base64-kodierter Wert der refnr aus der Jobsuche. Beispiel: base64('10001-1002716922-S') = 'MTAwMDEtMTAwMjcxNjkyMi1T'"
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/JobDetails'

/ct/v1/arbeitgeberlogo/{kundennummerHash}:
servers:
- url: "https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service"
get:
summary: Unternehmen Logo
description: "Abrufen des Logos eines Unternehmens"
description: "Abrufen des Logos eines Unternehmens anhand des arbeitgeberKundennummerHash aus der Jobdetail-Antwort. Gibt 404 zurück, wenn kein Logo vorhanden ist."
parameters:
- name: hashID
- name: kundennummerHash
in: path
required: true
schema:
type: string
example: VK2qoXBe0s-UAdH_qxLDRrZrY5iY8a1PJt3MjJCXsdo=
example: Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=
description: "Wert des Feldes arbeitgeberKundennummerHash aus der Jobdetail-Antwort (URL-kodiert falls nötig)."
responses:
'200':
description: OK
content:
image/webp:
schema:
type: string
format: binary
image/png:
schema:
type: string
format: binary
'404':
description: Kein Logo für diesen Arbeitgeber vorhanden.


security:
Expand Down Expand Up @@ -348,6 +397,16 @@ components:
lon:
type: number
example: 13.4025753
kundennummerHash:
type: string
nullable: true
example: Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=
description: "Hash-ID des Arbeitgebers für den Logo-Abruf. Ist nicht immer vorhanden."
externeUrl:
type: string
nullable: true
example: https://example.com/job/123
description: "Externe URL zur Stellenanzeige (optional)."
modifikationsTimestamp:
type: string
maxErgebnisse:
Expand Down Expand Up @@ -495,6 +554,11 @@ components:
arbeitgeberHashId:
type: string
example: dj32HpGiU3tdrYi6ohcMOtUhtBLPvwGIRiRlcvDsebg=
arbeitgeberKundennummerHash:
type: string
nullable: true
example: Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=
description: "Hash-ID des Arbeitgebers für den Logo-Abruf (/ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash}). Kann null sein."
arbeitsorte:
type: array
items:
Expand Down Expand Up @@ -555,6 +619,10 @@ components:
titel:
type: string
example: Wissenschaftlicher Mitarbeiter (m/w/d)
stellenangebotsTitel:
type: string
example: Wissenschaftlicher Mitarbeiter (m/w/d)
description: "Stellen-Titel (Feldname in v3/v4 jobdetails-Antworten)."
hashId:
type: string
example: VK2qoXBe0s-UAdH_qxLDRrZrY5iY8a1PJt3MjJCXsdo=
Expand All @@ -566,9 +634,16 @@ components:
example: 2021-07-25T13:12:33.913
stellenbeschreibung:
type: string
stellenangebotsBeschreibung:
type: string
description: "Stellenbeschreibung (Feldname in v3/v4 jobdetails-Antworten)."
refnr:
type: string
example: 10000-1183999289-S
referenznummer:
type: string
example: 10000-1183999289-S
description: "Referenznummer der Stelle (Feldname in v3/v4 jobdetails-Antworten)."
fuerFluechtlingeGeeignet:
type: boolean
example: false
Expand Down
15 changes: 9 additions & 6 deletions python-client/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# jobsuche
Die größte Stellendatenbank Deutschlands durchsuchen, Details zu Stellenanzeigen und Informationen über Arbeitgeber abrufen. <br><br>Die Authentifizierung funktioniert über die clientId:<br><br>clientId: jobboerse-jobsuche<br><br>Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben.
Die größte Stellendatenbank Deutschlands durchsuchen, Details zu Stellenanzeigen und Informationen über Arbeitgeber abrufen. <br><br>Die Authentifizierung funktioniert über die clientId:<br><br>clientId: jobboerse-jobsuche<br><br>Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben.<br><br>Ablauf: (1) Stellen suchen via /pc/v4/jobs oder /pc/v4/app/jobs → refnr merken. (2) Details abrufen via /pc/v4/jobdetails/{base64(refnr)}. (3) Arbeitgeberlogo abrufen via /ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash} (sofern vorhanden).

This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:

- API version: 2.0.2
- API version: 2.1.0
- Package version: 0.1.0
- Build package: org.openapitools.codegen.languages.PythonClientCodegen

Expand Down Expand Up @@ -50,6 +50,7 @@ import time
from deutschland import jobsuche
from pprint import pprint
from deutschland.jobsuche.api import default_api
from deutschland.jobsuche.model.job_details import JobDetails
from deutschland.jobsuche.model.job_search_response import JobSearchResponse
# Defining the host is optional and defaults to https://rest.arbeitsagentur.de/jobboerse/jobsuche-service
# See configuration.py for a list of all supported configuration parameters.
Expand All @@ -73,14 +74,14 @@ configuration.api_key['APIKeyHeaders'] = 'YOUR_API_KEY'
with jobsuche.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = default_api.DefaultApi(api_client)
hash_id = "VK2qoXBe0s-UAdH_qxLDRrZrY5iY8a1PJt3MjJCXsdo=" # str |
kundennummer_hash = "Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=" # str | Wert des Feldes arbeitgeberKundennummerHash aus der Jobdetail-Antwort (URL-kodiert falls nötig).

try:
# Unternehmen Logo
api_response = api_instance.ed_v1_arbeitgeberlogo_hash_id_get(hash_id)
api_response = api_instance.ct_v1_arbeitgeberlogo_kundennummer_hash_get(kundennummer_hash)
pprint(api_response)
except jobsuche.ApiException as e:
print("Exception when calling DefaultApi->ed_v1_arbeitgeberlogo_hash_id_get: %s\n" % e)
print("Exception when calling DefaultApi->ct_v1_arbeitgeberlogo_kundennummer_hash_get: %s\n" % e)
```

## Documentation for API Endpoints
Expand All @@ -89,8 +90,10 @@ All URIs are relative to *https://rest.arbeitsagentur.de/jobboerse/jobsuche-serv

Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*DefaultApi* | [**ed_v1_arbeitgeberlogo_hash_id_get**](docs/DefaultApi.md#ed_v1_arbeitgeberlogo_hash_id_get) | **GET** /ed/v1/arbeitgeberlogo/{hashID} | Unternehmen Logo
*DefaultApi* | [**ct_v1_arbeitgeberlogo_kundennummer_hash_get**](docs/DefaultApi.md#ct_v1_arbeitgeberlogo_kundennummer_hash_get) | **GET** /ct/v1/arbeitgeberlogo/{kundennummerHash} | Unternehmen Logo
*DefaultApi* | [**pc_v3_jobdetails_encrypted_job_code_get**](docs/DefaultApi.md#pc_v3_jobdetails_encrypted_job_code_get) | **GET** /pc/v3/jobdetails/{encryptedJobCode} | Jobdetails (v3)
*DefaultApi* | [**pc_v4_app_jobs_get**](docs/DefaultApi.md#pc_v4_app_jobs_get) | **GET** /pc/v4/app/jobs | Jobsuche via App
*DefaultApi* | [**pc_v4_jobdetails_encrypted_job_code_get**](docs/DefaultApi.md#pc_v4_jobdetails_encrypted_job_code_get) | **GET** /pc/v4/jobdetails/{encryptedJobCode} | Jobdetails (v4)
*DefaultApi* | [**pc_v4_jobs_get**](docs/DefaultApi.md#pc_v4_jobs_get) | **GET** /pc/v4/jobs | Jobsuche


Expand Down
4 changes: 2 additions & 2 deletions python-client/deutschland/jobsuche/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"""
Arbeitsagentur Jobsuche API

Die größte Stellendatenbank Deutschlands durchsuchen, Details zu Stellenanzeigen und Informationen über Arbeitgeber abrufen. <br><br>Die Authentifizierung funktioniert über die clientId:<br><br>clientId: jobboerse-jobsuche<br><br>Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben. # noqa: E501
Die größte Stellendatenbank Deutschlands durchsuchen, Details zu Stellenanzeigen und Informationen über Arbeitgeber abrufen. <br><br>Die Authentifizierung funktioniert über die clientId:<br><br>clientId: jobboerse-jobsuche<br><br>Bei folgenden GET-requests ist die clientId als Header-Parameter 'X-API-Key' zu übergeben.<br><br>Ablauf: (1) Stellen suchen via /pc/v4/jobs oder /pc/v4/app/jobs → refnr merken. (2) Details abrufen via /pc/v4/jobdetails/{base64(refnr)}. (3) Arbeitgeberlogo abrufen via /ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash} (sofern vorhanden). # noqa: E501

The version of the OpenAPI document: 2.0.2
The version of the OpenAPI document: 2.1.0
Contact: kontakt@bund.dev
Generated by: https://openapi-generator.tech
"""
Expand Down
Loading