Oferty pracy, grupy ofert, kandydaci, zgody RODO i ustawienia przez API modułu Rekrutacja.
Autoryzacja: Authorization: Bearer TOKEN - token musi mieć uprawnienie recruit_jobs
(kandydaci: recruit_candidates)
Content-Type: application/json; charset=utf-8
API Endpoints
| Metoda | Ścieżka | Opis |
|---|---|---|
| GET | /recruit/jobs.json |
Lista ofert pracy (filtry: status, group_id, employment_type, work_mode, q) |
| GET | /recruit/jobs/:id.json |
Pojedyncza oferta (z token do publicznego ogłoszenia) |
| POST | /recruit/jobs.json |
Utworzenie oferty |
| PATCH | /recruit/jobs/:id.json |
Aktualizacja oferty |
| DELETE | /recruit/jobs/:id.json |
Usunięcie oferty |
| GET | /recruit/job_groups.json |
Lista grup ofert |
| GET | /recruit/job_groups/:id.json |
Pojedyncza grupa (z token do publicznej listy grupy) |
| POST | /recruit/job_groups.json |
Utworzenie grupy |
| PATCH | /recruit/job_groups/:id.json |
Aktualizacja grupy |
| DELETE | /recruit/job_groups/:id.json |
Usunięcie grupy (oferty zostają, tracą tylko group_id) |
| GET | /recruit/candidates.json |
Lista kandydatów (filtry: status, job_id, source, q; domyślnie nowe zgłoszenia na górze) |
| GET | /recruit/candidates/:id.json |
Pojedynczy kandydat |
| POST | /recruit/candidates.json |
Dodanie kandydata |
| PATCH | /recruit/candidates/:id.json |
Aktualizacja kandydata |
| PATCH | /recruit/candidates/:id/change_status.json |
Zmiana etapu kandydata (candidate[status]) |
| POST | /recruit/candidates/:id/merge.json |
Scalenie duplikatu: source_id = kandydat do wchłonięcia (znika, jego dane i pliki przechodzą do :id) |
| DELETE | /recruit/candidates/:id.json |
Usunięcie kandydata (razem ze zgodami i plikami) |
| GET | /recruit/settings.json |
Ustawienia modułu (fields z domyślnymi wartościami i ważnością zgód) |
| PATCH | /recruit/settings.json |
Aktualizacja ustawień: setting[notes], setting[fields] (JSON), własny baner stron publicznych multipartem (setting[public_banner], usunięcie: setting[public_banner_remove]=1). config z tokenami jest tylko do odczytu |
Pola oferty (job)
job)| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
name |
string | tak | Stanowisko |
status |
string | nie |
draft / open / on_hold / closed (domyślnie z ustawień, fabrycznie open) |
location |
string | nie | Lokalizacja |
employment_type |
string | nie |
permanent / b2b / permanent_or_b2b (umowa o pracę lub B2B do wyboru) / negotiable (forma do ustalenia z kandydatem) / mandate / temporary / internship (domyślnie z ustawień) |
work_mode |
string | nie |
office / hybrid / remote (domyślnie z ustawień) |
salary_from, salary_to
|
decimal | nie | Widełki; salary_to nie może być mniejsze od salary_from
|
currency |
string | nie | Kod waluty, zapisywany wielkimi literami; domyślnie z ustawień (fabrycznie PLN) |
positions_count |
integer | nie | Liczba etatów; puste = nie podano |
email, phone
|
string | nie | Kontakt pokazywany na publicznym ogłoszeniu |
group_id |
integer lub string | nie | Grupa ofert: id istniejącej grupy albo nazwa - tekst zakłada nową grupę (lub bierze istniejącą o tej nazwie) przy zapisie oferty, np. "group_id": "Magazyn Wrocław"
|
client_id |
integer | nie | Klient z CRM (rekrutacja dla klienta) - nie wychodzi na publiczne ogłoszenie |
responsible_id |
integer | nie | Prowadzący rekrutację (użytkownik) - wewnętrzne |
description |
text | nie | Opis stanowiska (widoczny w ogłoszeniu). Zwykły tekst, Markdown albo HTML - format rozpoznawany automatycznie przy renderowaniu (HTML gdy treść ma tagi, markdown gdy jednoznacznie na niego wygląda), treść jest sanityzowana |
fields |
object | nie | Dowolne pola dodatkowe (JSON) - wewnętrzne |
Tylko oferty ze statusem open wychodzą na publiczne listy i do widgetu.
Pola grupy ofert (job_group)
job_group)| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
name |
string | tak | Nazwa grupy („Magazyn Wrocław”, „Rekrutacja jesień 2026”) |
description |
text | nie | Opis wewnętrzny (nie pokazuje się na publicznej liście grupy) |
color |
string | nie | Kolor etykiety |
Pola kandydata (candidate)
candidate)| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
last_name |
string | tak | Nazwisko |
first_name, email, phone
|
string | nie | Dane kontaktowe |
status |
string | nie |
unverified / screening / interview / hired / rejected
|
source |
string | nie |
direct / referral / job_board / linkedin / website / agency / other
|
job_id |
integer | nie | Rekrutacja, do której kandydat aplikuje |
position, location
|
string | nie | Stanowisko i lokalizacja kandydata |
salary_expectation, currency
|
decimal/string | nie | Oczekiwania finansowe |
available_from |
date | nie | Dostępność |
description |
text | nie | Notatka rekrutera |
fields |
object | nie | Dowolne pola dodatkowe (JSON); fields.merged to historia scaleń zapisywana przez system |
Publiczne strony (bez logowania, bez tokenu Bearer)
| Ścieżka | Co pokazuje |
|---|---|
/recruit/job/:token |
Ogłoszenie jednej oferty (token z GET /recruit/jobs/:id.json); .json daje publiczne pola oferty |
/recruit/job/:token/apply |
Formularz aplikacyjny (tylko dla oferty open, inaczej 403) |
/recruit/group/:token |
Otwarte oferty jednej grupy (token z GET /recruit/job_groups/:id.json) |
/recruit/offers/:token |
Wszystkie otwarte oferty konta; token generuje się przy pierwszym użyciu przycisku „Link publiczny ofert” na pulpicie (config.public_jobs_token w ustawieniach) |
Zgłoszenie z formularza: POST /recruit/job/:token/apply z polami candidate[first_name],
candidate[last_name] (wymagane), candidate[email] (wymagane), candidate[phone], candidate[cv]
(plik multipart: PDF/DOC/DOCX/ODT/RTF/TXT/obraz, do 10 MB), candidate[description] (wiadomość
kandydata „kilka słów o sobie”, do 5000 znaków, zapisuje się jako notatka kandydata; wymagane
jest cv albo description) oraz zgodami consent_recruitment=1
(wymagana) i consent_future=1 (dobrowolna). Publiczne listy pokazują maksymalnie 200 ofert;
formularz przyjmuje 5 zgłoszeń na minutę z jednego IP, strony publiczne 120 wejść na minutę.
Widget „aktualne oferty pracy” (kod do wklejenia jest na pulpicie modułu) czyta statyczny JSON
z CDN pod tokenem config.widget_token, odświeżany po każdej zmianie oferty - nie odpytuje API.
Ustawienia modułu (/recruit/settings)
/recruit/settings)Pojedyncze wartości zmienia POST /account/set_field z target: "recruit_setting":
key |
Wartości |
|---|---|
recruit.jobs.default_status |
draft / open / on_hold / closed
|
recruit.jobs.default_employment_type |
jak employment_type oferty |
recruit.jobs.default_work_mode |
jak work_mode oferty |
recruit.jobs.default_currency |
kod waluty, np. PLN
|
recruit.consents.months_recruitment |
ile miesięcy ważna jest zgoda na tę rekrutację (fabrycznie 12) |
recruit.consents.months_future |
ile miesięcy ważna jest zgoda na przyszłe rekrutacje (fabrycznie 6) |
Przykład: POST /account/set_field {"key":"recruit.jobs.default_currency","value":"EUR","target":"recruit_setting"}.
Te same wartości widać w fields z GET /recruit/settings.json.
Własny baner stron publicznych (obrazek nad ogłoszeniem i listami ofert zamiast banera z logo produktu;
formularz zgłoszeniowy banera nie ma) to plik, nie wartość w fields - wgrywa się go
PATCH /recruit/settings.json jako multipart/form-data z polem setting[public_banner]
(PNG, JPG, WEBP lub GIF, do 5 MB; najlepiej ok. 1536 × 288 px, brzegi mogą zostać przycięte na telefonie).
setting[public_banner_remove]=1 usuwa go i przywraca baner z logo. Adres wgranego banera zwraca
GET /recruit/settings.json w public_banner_url (null, gdy nie wgrano).
Zasady
- oferta bez
statusdostaje domyślny z ustawień modułu;work_mode,employment_typeicurrencydziałają tak samo - kandydat z publicznego formularza ma
source: "direct", etapunverifiedi pusteseen_at(na liście pokazuje się jako „Nowy”); wejście na jego kartę ustawiaseen_at - zgody RODO (
Recruit::Consent) powstają tylko przez publiczny formularz - API ich nie tworzy; zapis zgłoszenia jest transakcją (bez zapisanej zgody nie ma kandydata) - wygasła zgoda jest oznaczana na karcie kandydata; automatycznej anonimizacji jeszcze nie ma
- publiczne strony pokazują tylko dane ogłoszenia: nazwę, lokalizację, formę zatrudnienia, tryb
pracy, widełki, opis i kontakt -
client_id,responsible_id,fieldsi opis grupy zostają wewnętrzne