Skip to content

Commit d749e94

Browse files
Merge pull request #65 from bundesAPI/copilot/align-jobsuche-docs-with-live-api
Align OpenAPI spec and docs with currently working live Jobsuche API
2 parents de2f589 + fc6e379 commit d749e94

43 files changed

Lines changed: 743 additions & 121 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
__pycache__/
2+
*.py[cod]
3+
*.egg-info/
4+
dist/
5+
build/
6+
.eggs/

README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,17 @@ ie Authentifizierung funktioniert über die clientId:
99

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

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

14+
15+
## Ablauf
16+
17+
Der typische Ablauf ist:
18+
19+
1. **Stellen suchen** via `/pc/v4/jobs` oder `/pc/v4/app/jobs``refnr` aus der Antwort merken.
20+
2. **Details abrufen** via `/pc/v4/jobdetails/{base64(refnr)}` (empfohlen) oder `/pc/v3/jobdetails/{base64(refnr)}`.
21+
3. **Arbeitgeberlogo abrufen** via `/ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash}` (sofern im Detail-Response vorhanden).
22+
1523
## Jobbörse
1624

1725
**URL:** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobs
@@ -121,3 +129,51 @@ jobs=$(curl -m 60 \
121129
-H "X-API-Key: jobboerse-jobsuche" \
122130
'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')
123131
```
132+
133+
134+
## Jobdetails
135+
136+
**URL (empfohlen):** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/{encryptedJobCode}
137+
138+
**URL (alternativ):** https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v3/jobdetails/{encryptedJobCode}
139+
140+
Der `encryptedJobCode` ist der Base64-kodierte Wert der `refnr` aus der Jobsuche-Antwort.
141+
142+
**Beispiel:** `refnr = 10001-1002716922-S``base64(refnr) = MTAwMDEtMTAwMjcxNjkyMi1T`
143+
144+
Die Detail-Antwort enthält u.a.:
145+
- `stellenangebotsTitel` – Titel der Stelle
146+
- `stellenangebotsBeschreibung` – Beschreibung der Stelle
147+
- `referenznummer` – Referenznummer der Stelle
148+
- `arbeitgeberKundennummerHash` – Hash für den Logo-Abruf (kann `null` sein)
149+
150+
### Hinweise zu Sonderfällen
151+
152+
- Manche Stellenanzeigen haben kein `kundennummerHash` in der Suchantwort und kein `arbeitgeberKundennummerHash` in der Detail-Antwort – in diesem Fall steht kein Logo zur Verfügung.
153+
- Externe Stellenanzeigen können ein `externeUrl`-Feld in der Suchantwort enthalten.
154+
155+
### Beispiel:
156+
```bash
157+
refnr="10001-1002716922-S"
158+
encoded=$(python3 -c "import base64; print(base64.b64encode('$refnr'.encode()).decode())")
159+
curl -m 60 \
160+
-H "X-API-Key: jobboerse-jobsuche" \
161+
"https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/$encoded"
162+
```
163+
164+
165+
## Arbeitgeberlogo
166+
167+
**URL:** https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/{kundennummerHash}
168+
169+
Der `kundennummerHash` entspricht dem Feld `arbeitgeberKundennummerHash` aus der Jobdetail-Antwort (URL-kodiert falls nötig, da der Wert `=`-Zeichen enthalten kann).
170+
171+
Gibt `200 image/webp` oder `200 image/png` zurück, wenn ein Logo vorhanden ist.
172+
Gibt `404` zurück, wenn kein Logo für diesen Arbeitgeber hinterlegt ist – dies ist ein normaler Fall, kein Fehler.
173+
174+
### Beispiel:
175+
```bash
176+
curl -m 60 \
177+
-H "X-API-Key: jobboerse-jobsuche" \
178+
"https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA%3D"
179+
```

api_example.R

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,17 @@ data=httr::content(data_request)
1414

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

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

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

api_example.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
import base64
12
import requests
23

4+
HEADERS = {
5+
'User-Agent': 'Jobsuche/2.9.2 (de.arbeitsagentur.jobboerse; build:1077; iOS 15.1.0) Alamofire/5.4.4',
6+
'Host': 'rest.arbeitsagentur.de',
7+
'X-API-Key': 'jobboerse-jobsuche',
8+
'Connection': 'keep-alive',
9+
}
10+
311
def search(what, where):
412
"""search for jobs. params can be found here: https://jobsuche.api.bund.dev/"""
513
params = (
@@ -11,16 +19,48 @@ def search(what, where):
1119
('was', what),
1220
('wo', where),
1321
)
14-
headers = {
15-
'User-Agent': 'Jobsuche/2.9.2 (de.arbeitsagentur.jobboerse; build:1077; iOS 15.1.0) Alamofire/5.4.4',
16-
'Host': 'rest.arbeitsagentur.de',
17-
'X-API-Key': 'jobboerse-jobsuche',
18-
'Connection': 'keep-alive',
19-
}
2022
response = requests.get('https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/app/jobs',
21-
headers=headers, params=params, verify=False)
23+
headers=HEADERS, params=params, verify=False)
2224
return response.json()
2325

26+
27+
def get_job_details(refnr):
28+
"""Retrieve job details by refnr. The refnr is base64-encoded before sending."""
29+
encrypted = base64.b64encode(refnr.encode()).decode()
30+
response = requests.get(
31+
f'https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobdetails/{encrypted}',
32+
headers=HEADERS, verify=False)
33+
return response.json()
34+
35+
36+
def get_employer_logo(kundennummer_hash):
37+
"""Retrieve employer logo by arbeitgeberKundennummerHash from job details.
38+
Returns None if no logo is available (404).
39+
"""
40+
import urllib.parse
41+
encoded_hash = urllib.parse.quote(kundennummer_hash, safe='')
42+
response = requests.get(
43+
f'https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service/ct/v1/arbeitgeberlogo/{encoded_hash}',
44+
headers=HEADERS, verify=False)
45+
if response.status_code == 404:
46+
return None
47+
return response.content
48+
49+
2450
result = search("bahn", "berlin")
2551

26-
print(result['stellenangebote'][0]["refnr"])
52+
refnr = result['stellenangebote'][0]["refnr"]
53+
print("refnr:", refnr)
54+
55+
details = get_job_details(refnr)
56+
print("Titel:", details.get("stellenangebotsTitel") or details.get("titel"))
57+
58+
kundennummer_hash = details.get("arbeitgeberKundennummerHash")
59+
if kundennummer_hash:
60+
logo = get_employer_logo(kundennummer_hash)
61+
if logo:
62+
print("Logo gefunden, Größe:", len(logo), "Bytes")
63+
else:
64+
print("Kein Logo für diesen Arbeitgeber vorhanden.")
65+
else:
66+
print("Kein arbeitgeberKundennummerHash – kein Logo verfügbar.")

openapi.yaml

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
openapi: "3.0.0"
22
info:
3-
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."
4-
version: "2.0.2"
3+
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)."
4+
version: "2.1.0"
55
title: "Arbeitsagentur Jobsuche API"
66

77
servers:
@@ -259,25 +259,74 @@ paths:
259259
required: false
260260

261261

262-
/ed/v1/arbeitgeberlogo/{hashID}:
262+
/pc/v4/jobdetails/{encryptedJobCode}:
263+
get:
264+
summary: Jobdetails (v4)
265+
description: "Abrufen der Details einer Stellenanzeige anhand des Base64-kodierten Referenzwertes (base64(refnr)). Empfohlene Version."
266+
parameters:
267+
- name: encryptedJobCode
268+
in: path
269+
required: true
270+
schema:
271+
type: string
272+
example: MTAwMDEtMTAwMjcxNjkyMi1T
273+
description: "Base64-kodierter Wert der refnr aus der Jobsuche. Beispiel: base64('10001-1002716922-S') = 'MTAwMDEtMTAwMjcxNjkyMi1T'"
274+
responses:
275+
'200':
276+
description: OK
277+
content:
278+
application/json:
279+
schema:
280+
$ref: '#/components/schemas/JobDetails'
281+
282+
/pc/v3/jobdetails/{encryptedJobCode}:
283+
get:
284+
summary: Jobdetails (v3)
285+
description: "Abrufen der Details einer Stellenanzeige anhand des Base64-kodierten Referenzwertes (base64(refnr))."
286+
parameters:
287+
- name: encryptedJobCode
288+
in: path
289+
required: true
290+
schema:
291+
type: string
292+
example: MTAwMDEtMTAwMjcxNjkyMi1T
293+
description: "Base64-kodierter Wert der refnr aus der Jobsuche. Beispiel: base64('10001-1002716922-S') = 'MTAwMDEtMTAwMjcxNjkyMi1T'"
294+
responses:
295+
'200':
296+
description: OK
297+
content:
298+
application/json:
299+
schema:
300+
$ref: '#/components/schemas/JobDetails'
301+
302+
/ct/v1/arbeitgeberlogo/{kundennummerHash}:
303+
servers:
304+
- url: "https://rest.arbeitsagentur.de/vermittlung/ag-darstellung-service"
263305
get:
264306
summary: Unternehmen Logo
265-
description: "Abrufen des Logos eines Unternehmens"
307+
description: "Abrufen des Logos eines Unternehmens anhand des arbeitgeberKundennummerHash aus der Jobdetail-Antwort. Gibt 404 zurück, wenn kein Logo vorhanden ist."
266308
parameters:
267-
- name: hashID
309+
- name: kundennummerHash
268310
in: path
269311
required: true
270312
schema:
271313
type: string
272-
example: VK2qoXBe0s-UAdH_qxLDRrZrY5iY8a1PJt3MjJCXsdo=
314+
example: Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=
315+
description: "Wert des Feldes arbeitgeberKundennummerHash aus der Jobdetail-Antwort (URL-kodiert falls nötig)."
273316
responses:
274317
'200':
275318
description: OK
276319
content:
320+
image/webp:
321+
schema:
322+
type: string
323+
format: binary
277324
image/png:
278325
schema:
279326
type: string
280327
format: binary
328+
'404':
329+
description: Kein Logo für diesen Arbeitgeber vorhanden.
281330

282331

283332
security:
@@ -348,6 +397,16 @@ components:
348397
lon:
349398
type: number
350399
example: 13.4025753
400+
kundennummerHash:
401+
type: string
402+
nullable: true
403+
example: Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=
404+
description: "Hash-ID des Arbeitgebers für den Logo-Abruf. Ist nicht immer vorhanden."
405+
externeUrl:
406+
type: string
407+
nullable: true
408+
example: https://example.com/job/123
409+
description: "Externe URL zur Stellenanzeige (optional)."
351410
modifikationsTimestamp:
352411
type: string
353412
maxErgebnisse:
@@ -495,6 +554,11 @@ components:
495554
arbeitgeberHashId:
496555
type: string
497556
example: dj32HpGiU3tdrYi6ohcMOtUhtBLPvwGIRiRlcvDsebg=
557+
arbeitgeberKundennummerHash:
558+
type: string
559+
nullable: true
560+
example: Z-HzVkUCLGQiQFxQSAICs302sSdB9Sp7XtgOiO4GGCA=
561+
description: "Hash-ID des Arbeitgebers für den Logo-Abruf (/ct/v1/arbeitgeberlogo/{arbeitgeberKundennummerHash}). Kann null sein."
498562
arbeitsorte:
499563
type: array
500564
items:
@@ -555,6 +619,10 @@ components:
555619
titel:
556620
type: string
557621
example: Wissenschaftlicher Mitarbeiter (m/w/d)
622+
stellenangebotsTitel:
623+
type: string
624+
example: Wissenschaftlicher Mitarbeiter (m/w/d)
625+
description: "Stellen-Titel (Feldname in v3/v4 jobdetails-Antworten)."
558626
hashId:
559627
type: string
560628
example: VK2qoXBe0s-UAdH_qxLDRrZrY5iY8a1PJt3MjJCXsdo=
@@ -566,9 +634,16 @@ components:
566634
example: 2021-07-25T13:12:33.913
567635
stellenbeschreibung:
568636
type: string
637+
stellenangebotsBeschreibung:
638+
type: string
639+
description: "Stellenbeschreibung (Feldname in v3/v4 jobdetails-Antworten)."
569640
refnr:
570641
type: string
571642
example: 10000-1183999289-S
643+
referenznummer:
644+
type: string
645+
example: 10000-1183999289-S
646+
description: "Referenznummer der Stelle (Feldname in v3/v4 jobdetails-Antworten)."
572647
fuerFluechtlingeGeeignet:
573648
type: boolean
574649
example: false

python-client/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# jobsuche
2-
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.
2+
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).
33

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

6-
- API version: 2.0.2
6+
- API version: 2.1.0
77
- Package version: 0.1.0
88
- Build package: org.openapitools.codegen.languages.PythonClientCodegen
99

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

7879
try:
7980
# Unternehmen Logo
80-
api_response = api_instance.ed_v1_arbeitgeberlogo_hash_id_get(hash_id)
81+
api_response = api_instance.ct_v1_arbeitgeberlogo_kundennummer_hash_get(kundennummer_hash)
8182
pprint(api_response)
8283
except jobsuche.ApiException as e:
83-
print("Exception when calling DefaultApi->ed_v1_arbeitgeberlogo_hash_id_get: %s\n" % e)
84+
print("Exception when calling DefaultApi->ct_v1_arbeitgeberlogo_kundennummer_hash_get: %s\n" % e)
8485
```
8586

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

9091
Class | Method | HTTP request | Description
9192
------------ | ------------- | ------------- | -------------
92-
*DefaultApi* | [**ed_v1_arbeitgeberlogo_hash_id_get**](docs/DefaultApi.md#ed_v1_arbeitgeberlogo_hash_id_get) | **GET** /ed/v1/arbeitgeberlogo/{hashID} | Unternehmen Logo
93+
*DefaultApi* | [**ct_v1_arbeitgeberlogo_kundennummer_hash_get**](docs/DefaultApi.md#ct_v1_arbeitgeberlogo_kundennummer_hash_get) | **GET** /ct/v1/arbeitgeberlogo/{kundennummerHash} | Unternehmen Logo
94+
*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)
9395
*DefaultApi* | [**pc_v4_app_jobs_get**](docs/DefaultApi.md#pc_v4_app_jobs_get) | **GET** /pc/v4/app/jobs | Jobsuche via App
96+
*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)
9497
*DefaultApi* | [**pc_v4_jobs_get**](docs/DefaultApi.md#pc_v4_jobs_get) | **GET** /pc/v4/jobs | Jobsuche
9598

9699

python-client/deutschland/jobsuche/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
"""
44
Arbeitsagentur Jobsuche API
55
6-
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
6+
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
77
8-
The version of the OpenAPI document: 2.0.2
8+
The version of the OpenAPI document: 2.1.0
99
Contact: kontakt@bund.dev
1010
Generated by: https://openapi-generator.tech
1111
"""

0 commit comments

Comments
 (0)