Element External Integration API — dokumentacja
REST API do integracji zewnętrznych systemów (voice-boty, ATS, pipeline'y danych) z platformą Element. Interfejs jest w fazie beta — kontrakt może się jeszcze zmienić w niekompatybilny sposób w oknie ~2–3 miesięcy testów produkcyjnych; zmiany łamiące będą komunikowane z wyprzedzeniem.
GET …/application-form— zgody RODO projektu. Nowe addytywne poleconsents[]z definicjami zgód projektu (hash,type,name,content,required,allowsCommunication). Zob. 8.6.POST …/apply— przekazywanie zaakceptowanych zgód. Nowe opcjonalne poleconsents[](hashe zgód z GET) rejestruje zgody kandydata — widoczne w zakładce RODO i honorowane przez filtry zgód. Nieznany hash →400 invalid_consents. Zob. 8.11.POST …/apply— pliki jako odpowiedzi na pytania formularza. Nowe opcjonalne poleanswerFiles[<questionId>][]pozwala przesłać pliki do pytań plikowych formularza (do 10 plików łącznie, 5 MB każdy). Błędne mapowanie →400 invalid_answer_files. Zob. 8.11.POST …/apply— automatyczne wiadomości do kandydata. Aplikacja przez API uruchamia teraz te same automatyczne wiadomości do kandydata co aplikacja przez formularz webowy (np. podziękowanie za aplikację, akcje etapu aplikacyjnego), o ile tenant ma je skonfigurowane. Bez zmian w kontrakcie. Zob. 8.11.
Wszystkie zmiany 1.4 są opcjonalne i addytywne — integracja zbudowana na 1.3 działa bez modyfikacji. Zmiany z wersji 1.2 (rozwinięte subForms[], załączniki attachments[], odpowiedzi calendarDay) i 1.3 (opcjonalny email, dane podstawowe w podglądzie formularza) pozostają oznaczone znaczkami „v1.2"/„v1.3" w sekcjach 8.6 i 8.11.
1O API
External Integration API udostępnia programowy dostęp tylko-do-odczytu do projektów rekrutacyjnych, kandydatów i formularzy aplikacyjnych oraz ograniczony zestaw operacji zapisu (utworzenie kandydata przez aplikację, dodanie publicznej notatki). Adresowany jest do zespołów developerskich wdrażających integracje z systemami zewnętrznymi.
Wszystkie ścieżki są wersjonowane prefiksem /api/v1-beta. Po stabilizacji interfejs przejdzie w zamrożone v1; przyszłe zmiany łamiące trafią pod nowy prefiks (np. /api/v2).
2Wymagania wstępne
- Aktywny tenant Element z włączonym modułem External Integration API.
- Konto API (login + hasło) utworzone w panelu — jeden zestaw poświadczeń na jeden system zewnętrzny.
- Klient HTTP obsługujący uwierzytelnianie HTTP Basic oraz
multipart/form-data(dla przesyłania plików).
3Pierwsze wywołanie
Najprostszy test łączności — endpoint health (bez uwierzytelniania):
curl https://<tenant>.elementapp.ai/api/v1-beta/health
# 200 OK
{ "status": "ok", "apiVersion": "v1-beta" }
Kolejny krok — uwierzytelnione pobranie listy projektów (zob. 8.2).
4Uwierzytelnianie
Schemat: HTTP Basic (RFC 7617), realm External Integration API.
- login — w formacie
api+<nazwa-systemu>@<tenant>.local(np.api+voicebot@acme.local). - hasło — generowane losowo, pokazywane jednorazowo przy utworzeniu, nieodzyskiwalne.
- nagłówek —
Authorization: Basic base64(login:hasło).
Wielotenantowość: tenant identyfikowany jest wyłącznie po subdomenie w URL (<tenant>.elementapp.ai); poświadczenia są zablokowane do jednego tenanta.
- (IP + login): 5 nieudanych prób → blokada 15 min.
- sam login: 20 nieudanych prób → blokada 15 min.
- Odpowiedź:
429z kodemtoo_many_failed_attempts.
5Format danych
- Odpowiedzi —
application/json; charset=utf-8. - Żądania —
application/x-www-form-urlencodedlubmultipart/form-data(dla plików). - Daty — ISO 8601 UTC z offsetem (
2026-05-28T12:34:56+00:00); daty-tylko jakoYYYY-MM-DD. - Identyfikatory — UUID v4 (np.
ff315ea1-c056-472d-aefe-b99f3d41e5c0). - Lokalizacja — parametr
locale(pl,en,de, …) dla schematu formularza i odpowiedzi.
Koperta odpowiedzi (sukces):
{ "data": { /* encja lub tablica */ },
"meta": { "page": 1, "perPage": 20, "total": 8 } }
Koperta odpowiedzi (błąd):
{ "error": { "code": "snake_case_identifier",
"message": "Czytelny opis (dla wybranych kodów)" } }
Paginacja: ?page=N&perPage=N (1–100, domyślnie 20); w odpowiedzi meta: { page, perPage, total }.
6Limity zapytań
- Domyślnie: 70 wywołań/min na poświadczenie (60 bazowe + 10 burst) ≈ 1,2 req/s.
- Odpowiedź przy przekroczeniu:
429z kodemrate_limit_exceeded. - Backoff: wykładniczy od 1 s, limit 30 s.
- Wyższe limity — kontakt ze wsparciem Element.
7Obsługa błędów
| HTTP | code | Znaczenie |
|---|---|---|
| 200 | — | Sukces (GET) |
| 201 | — | Utworzono (POST) |
| 400 | validation_failed | Nieprawidłowe/niekompletne żądanie |
| 400 | invalid_answers | POST /apply: błędny JSON lub kształt/wartości answers |
| 400 | invalid_consents | v1.4POST /apply: hash w consents[] nie pasuje do żadnej definicji zgody projektu |
| 400 | invalid_answer_files | v1.4POST /apply: błędny klucz answerFiles (nieznane / nieplikowe pytanie), zła liczba plików lub przekroczony limit 10 plików |
| 401 | — | Brak / błędne uwierzytelnianie |
| 403 | — | Brak roli lub konto dezaktywowane |
| 404 | project_not_found | Projekt nie istnieje / zarchiwizowany / spoza tenanta |
| 404 | candidate_not_found | Kandydat nie istnieje / zarchiwizowany / usunięty RODO |
| 404 | application_form_not_found | Brak formularza / niewypełniony przez kandydata |
| 409 | no_application_stage | Projekt bez etapu aplikacyjnego |
| 409 | stale_form_version | POST /apply: niezgodna wersja formularza |
| 429 | rate_limit_exceeded | Przekroczony limit zapytań |
| 429 | too_many_failed_attempts | Blokada po nieudanych logowaniach |
| 5xx | — | Błąd serwera Element; ponów z backoffem |
8Referencja endpointów
Base URL: https://<tenant>.elementapp.ai/api/v1-beta
8.1 — Health check
Kontrola łączności bez uwierzytelniania.
{ "status": "ok", "apiVersion": "v1-beta" }
8.2 — Lista projektów
Stronicowana lista aktywnych projektów.
{ "data": [
{ "id": "ff315ea1-…", "name": "Senior PHP Developer",
"positionName": null, "isRemote": true,
"statusId": "73f09ef2-…", "createdAt": "2021-10-31T11:42:24+00:00" } ],
"meta": { "page": 1, "perPage": 20, "total": 8 } }
Błędy: 401, 429.
8.3 — Szczegóły projektu
Pełne dane projektu wraz z listą etapów. Pola responsibilities, requirements, offer zawierają treść HTML. minimumSalary/maximumSalary w walucie tenanta (0 = nieustawione).
{ "data": { "id": "ff315ea1-…", "name": "Senior PHP Developer",
"minimumSalary": 12000, "maximumSalary": 18000, "numberOfVacancies": 4,
"stages": [
{ "id": "…", "name": "Aplikacja", "isApplicationType": true },
{ "id": "…", "name": "Rozmowa", "isApplicationType": false } ] } }
Błędy: 401, 404 project_not_found, 429.
8.4 — Etapy projektu
Sama tablica etapów (kształt jak data.stages z 8.3). Etap o isApplicationType: true to etap aplikacyjny (max jeden na projekt).
Błędy: 401, 404 project_not_found, 429.
8.5 — Kandydaci w projekcie
Stronicowana lista kandydatów; opcjonalny filtr stageId. Pola: id, firstName, lastName, email, stageId, isRejected, addedAt. Pole email może być puste — od v1.3 aplikację przez API można złożyć bez adresu e-mail (zob. 8.11).
Błędy: 401, 404 project_not_found, 429.
8.6 — Schemat formularza aplikacyjnego ZMIANA v1.4
Zwraca pełną strukturę formularza (metadane + zagnieżdżone sekcje → pytania → warianty odpowiedzi). Użyj do zbudowania mapy odpowiedzi, pobrania version oraz — od v1.4 — hashy zgód do POST /apply.
Odpowiedź zawiera teraz addytywne pole consents[] — definicje zgód RODO projektu: hash (identyfikator wersji treści zgody — dokładnie tę wartość odsyłasz w consents[] w POST /apply, by zarejestrować akceptację), type (np. recruitmentProcess — zgoda na tę rekrutację, futureRecruitmentProcess — zgoda na przyszłe procesy), name, content (pełna treść — tę treść masz obowiązek pokazać kandydatowi przed zebraniem zgody), required (flaga informacyjna — API jej nie egzekwuje, zob. 8.11) i allowsCommunication. Projekt bez zdefiniowanych zgód zwraca pustą tablicę.
Każda sekcja zwraca tablicę subForms[] z pełną, rozwiniętą strukturą podformularza (np. calendar-days, week-days) — zagnieżdżone sekcje i pytania. Wcześniej dostępne były wyłącznie identyfikatory. Pole subFormIds pozostaje jako powiązanie sekcja→podformularz.
{ "data": {
"id": "78132d76-…", "projectId": "ff315ea1-…", "schemaId": "d6aea4da-…",
"formType": "custom", "schemaType": "default",
"schemaName": { "pl": "Formularz aplikacyjny" },
"version": "2026-04-09T12:55:57+00:00",
"isEmailRequired": true, "isPhoneNumberRequired": true, "isCvRequired": true,
"consents": [ // ◆ v1.4: zgody RODO projektu
{ "hash": "9f8e7d6c…", "type": "recruitmentProcess",
"name": "Zgoda na rekrutację",
"content": "Wyrażam zgodę na przetwarzanie moich danych…",
"required": true, "allowsCommunication": false },
{ "hash": "1a2b3c4d…", "type": "futureRecruitmentProcess",
"name": "Zgoda na przyszłe rekrutacje",
"content": "Wyrażam zgodę na przetwarzanie moich danych również…",
"required": false, "allowsCommunication": true } ],
"sections": [
{ "id": "1f0d3c8a-…", "name": { "pl": "Dane podstawowe" }, "order": 0,
"questions": [
{ "id": "9a2c7e44-…", "type": "oneAnswer", "subtype": null,
"label": { "pl": "Forma zatrudnienia" }, "isRequired": true, "order": 0,
"answers": [
{ "id": "b7e1d2a3-…", "content": { "pl": "Umowa o pracę" },
"isDisqualifying": false, "order": 0 } ] } ],
"subFormIds": ["30c5a856-…"],
"subForms": [ // ◆ v1.2: rozwinięte
{ "id": "30c5a856-…", "type": "week-days",
"name": { "pl": "W jakich dniach możesz się spotkać?" },
"sections": [
{ "id": "c1c4ae4c-…", "name": { "pl": "pn." }, "order": 0,
"questions": [
{ "id": "4a793138-…", "type": "yesNo", "subtype": "weekDay",
"label": { "pl": "pn." }, "isRequired": false, "order": 0 },
{ "id": "499a4fed-…", "type": "oneAnswer", "subtype": "hourFrom",
"label": { "pl": "Od godziny" } } ],
"subFormIds": [], "subForms": [] } ] } ] } ] } }
Pola sekcji: id, name, description, payload, order, questions[], subFormIds[], subForms[].
Obiekt podformularza (subForms[]): id (zgodny z pozycją w subFormIds sekcji-rodzica), type (np. calendar-days, week-days), name (mapa lokalizacji), sections[] (ta sama struktura co sekcje najwyższego poziomu — rekurencyjnie z questions, subFormIds, subForms).
Obiekt pytania: id (klucz w mapie answers dla POST /apply), type (oneAnswer, multiAnswers, scale, yesNo, open, financialRequirements, languages, file, referral, …), subtype (np. calendarDay, weekDay, hourFrom, hourTo), label, isRequired, order, answers[] (warianty: id — wartość dla oneAnswer/multiAnswers — content, isDisqualifying, order).
Błędy: 401, 404 project_not_found, 404 application_form_not_found, 429.
8.7 — Wypełniony formularz kandydata
Zwraca wypełniony formularz danego kandydata — sekcje z pytaniami i przesłanymi odpowiedziami.
{ "data": { "projectId": "ff315ea1-…", "candidateId": "87c42b09-…",
"applicationFormId": "78132d76-…", "submittedAt": "2026-05-27T17:57:48+00:00",
"formVersion": "2026-04-09T12:55:57+00:00", "locale": "pl",
"sections": [
{ "title": "Pytania aplikacyjne", "items": [
{ "questionId": "ae8a8a8a-…", "label": "Ocena PHP",
"type": "scale", "subtype": null, "answer": "1" } ] } ] } }
items[].answer zależy od type (string | int | bool | tablica | null = brak odpowiedzi). Wewnętrzny scoring (obtainedScore, isDisqualified) oraz pytania plikowe są celowo pominięte.
Błędy: 401, 404 project_not_found, 404 application_form_not_found, 429.
8.8 — Profil kandydata
Pełny profil (kontakt, doświadczenie, edukacja, umiejętności, języki, certyfikaty). Pola m.in. experience[], education[], skills[], languageSkills[] (cefrLevel A1–C2), certifications[]. Wewnętrzny description CRM jest wykluczony.
Błędy: 401, 404 candidate_not_found, 429.
8.9 — Projekty kandydata
Stronicowana lista aktywnych projektów, w których uczestniczy kandydat (malejąco po dacie dodania).
Błędy: 401, 404 candidate_not_found, 429.
8.10 — Publiczne notatki kandydata
Stronicowana lista publicznych notatek. Notatki prywatne nigdy nie są ujawniane. Opcjonalny projectId zawęża do kontekstu projektu. Pola: id, content, createdAt, createdBy, projectId (lub null).
Błędy: 401, 404 candidate_not_found, 429.
8.11 — Aplikacja (utworzenie kandydata) ZMIANA v1.4
Tworzy nowego kandydata i dodaje go do projektu na etapie aplikacyjnym.
Każde wywołanie tworzy nowego kandydata — API nie deduplikuje po e-mailu. Aby uniknąć duplikatów, sprawdź najpierw /projects/{id}/candidates. Aplikując bez e-maila (dozwolone od v1.3), tracisz też możliwość deduplikacji po adresie — rozważ własny klucz idempotencji.
Content-Type: multipart/form-data (z plikami) lub application/x-www-form-urlencoded (bez plików).
| Pole | Wym. | Typ | Limit | Opis |
|---|---|---|---|---|
| firstName | tak | string | 255 | Imię |
| lastName | tak | string | 255 | Nazwisko |
| nie | string | 255 | v1.3E-mail — od v1.3 opcjonalny; jeśli podany, jest walidowany (błędny format → 400 validation_failed). Pominięcie pola tworzy kandydata bez adresu e-mail. | |
| phoneNumber | nie | string | 32 | Telefon (dowolny format) |
| source | nie | string | 64 | Identyfikator źródła; domyślnie external-api |
| cv | nie | file | 5 MB | CV kandydata. Zapisywane jako dokument CV. |
| attachments[] | nie | file[] | 3 × 5 MB | v1.2Do 3 dodatkowych plików (poza CV), wysyłanych jako powtarzane części multipart attachments[]. Te same dozwolone typy/rozmiar co cv. Każdy zapisywany jako dokument kandydata „Inne". |
| answers | nie | string (JSON) | — | Mapa {questionId: wartość} zakodowana jako JSON. Pomiń, by aplikować bez odpowiedzi. |
| version | warunk. | string | — | Wymagane gdy podano answers. Wartość z pola version w GET …/application-form; niezgodność → 409 stale_form_version. |
| consents[] | nie | string[] | — | v1.4Hashe zgód zaakceptowanych przez kandydata — wartości consents[].hash z GET …/application-form, wysyłane jako powtarzane części consents[]. Hash spoza definicji projektu → 400 invalid_consents. Pomiń pole całkowicie, by aplikować bez rejestrowania zgód (dotychczasowe zachowanie). |
| answerFiles[<questionId>][] | nie | file[] | 10 × 5 MB | v1.4Pliki jako odpowiedzi na pytania plikowe formularza — mapa kluczowana id pytania (top-level file oraz podformularzowe fileCv/fileOther/filesCollection z GET …/application-form). Pytania jednoplikowe przyjmują dokładnie 1 plik; filesCollection — wiele. Maks. 10 plików łącznie; typy/rozmiar/antywirus jak cv/attachments. Błędne mapowanie → 400 invalid_answer_files. |
Mapowanie wartości answers wg typu pytania:
| Typ pytania | Wartość w answers |
|---|---|
| open, yesNo, oneAnswer | string (dla oneAnswer — id wariantu odpowiedzi) |
| scale | integer |
| financialRequirements | number |
| multiAnswers | tablica id wariantów [id1, id2, …] |
| calendarDay (subtype; podformularz calendar-days) | v1.2data jako string YYYY-MM-DD (np. 2026-06-30) |
| file (oraz fileCv / fileOther / filesCollection) | v1.4niedozwolone w answers — pliki do tych pytań prześlesz przez answerFiles[<questionId>][] |
| languages, referral | niedozwolone — pomiń te pytania w answers |
Odpowiedź 201:
{ "candidateId": "4b257ea8-…", "projectId": "ff315ea1-…",
"answerSheetId": "3c9b1f7e-…" } // answerSheetId tylko gdy podano poprawne answers; inaczej null
- Treść zgody prezentujesz Ty. Przed zebraniem akceptacji pokaż kandydatowi dokładną treść
contentzGET …/application-form. Treści nie przekazujesz w żądaniu — system sam zapisuje snapshot treści z definicji projektu w momencie akceptacji (tak samo jak formularz webowy). - Flaga
requiredjest informacyjna. API nie odrzuci aplikacji bez zgody oznaczonej jako wymagana — odpowiedzialność za prezentację i zebranie zgód leży po stronie systemu integratora. Walidacja jest wyłącznie techniczna: nieznany hash →400 invalid_consents. - Skutki zapisu. Zaakceptowane zgody są widoczne w zakładce RODO profilu kandydata, a kandydat wchodzi w filtry „ze zgodą" i podlega śledzeniu ważności zgody. Kandydat przyjęty bez zgód nie pojawia się w filtrach „ze zgodą" i podlega obsłudze anonimizacyjnej przewidzianej dla braku ważnej zgody.
answerFiles): semantyka- Każdy plik jest zapisywany jako dokument kandydata „Inne", a odpowiadające pytanie oznaczane w arkuszu odpowiedzi jako udzielone (
Yes) — w podglądzie formularza rekruter widzi pliki z etykietą pytania. - Oznaczenie pytania w arkuszu następuje tylko gdy przesłano również
answers(zversion).answerFilesbezanswersnadal zapisuje dokumenty kandydata, ale arkusz odpowiedzi nie powstaje (answerSheetId: null). - Ograniczenie (parytet z formularzem webowym): honorowane są pytania plikowe z pierwszej sekcji formularza zawierającej podformularz plikowy; pytania plikowe z ewentualnych kolejnych sekcji z podformularzem plikowym są odrzucane jako nieznane
questionId.
Aplikacja złożona przez API wyzwala teraz to samo zdarzenie aplikacji co formularz webowy — kandydat otrzyma automatyczne wiadomości skonfigurowane w tenancie (np. podziękowanie za aplikację, akcje etapu aplikacyjnego). Wcześniej aplikacje z API nie uruchamiały tych wiadomości. Bez zmian w kontrakcie żądania i odpowiedzi; dotyczy aplikacji złożonych po wdrożeniu v1.4.
Imię, nazwisko, e-mail i telefon przekazane w POST /apply są zapisywane także w arkuszu odpowiedzi — rekruter widzi je w podglądzie formularza kandydata w Element (wcześniej sekcja danych podstawowych była w podglądzie pusta dla aplikacji z API). Kontrakt żądania i odpowiedzi pozostaje bez zmian. Dotyczy aplikacji złożonych po wdrożeniu v1.3 — wcześniejsze arkusze nie są uzupełniane wstecznie.
Przykład (kontakt + CV + załączniki + odpowiedzi + zgody + plik do pytania):
curl --user "api+voicebot@acme.local:<hasło>" \
-F "firstName=Anna" -F "lastName=Nowak" -F "email=anna.nowak@example.com" \
-F "source=voicebot-inbound" \
-F "cv=@./cv.pdf" \
-F "attachments[]=@./portfolio.pdf" -F "attachments[]=@./certyfikat.png" \
-F 'version=2026-04-09T12:55:57+00:00' \
-F 'answers={"9a2c7e44-…":"b7e1d2a3-…","cal-day-q-id":"2026-06-30"}' \
-F "consents[]=9f8e7d6c…" -F "consents[]=1a2b3c4d…" \
-F "answerFiles[3fa85f64-…][]=@./referencje.pdf" \
https://acme.elementapp.ai/api/v1-beta/projects/ff315ea1-…/apply
Przykład minimalny (bez e-maila, od v1.3):
curl --user "api+voicebot@acme.local:<hasło>" \
-F "firstName=Anna" -F "lastName=Nowak" -F "phoneNumber=+48 500 100 200" \
https://acme.elementapp.ai/api/v1-beta/projects/ff315ea1-…/apply
Błędy: 400 validation_failed, 400 invalid_answers, 400 invalid_consents, 400 invalid_answer_files, 401, 404 project_not_found, 409 no_application_stage, 409 stale_form_version, 429.
8.12 — Dodanie notatki do kandydata
Dodaje publiczną notatkę (autor: konto API, w UI jako API: <nazwa-systemu>). Content-Type: application/x-www-form-urlencoded. Pola: content (wymagane, do 10 000 znaków), projectId (opcjonalne). Odpowiedź 201: { "noteId": "…" }.
Błędy: 400 validation_failed, 401, 404 candidate_not_found, 429.
9Scenariusze integracji
9.1 — Voice-bot: zgłoszenie aplikacji
Bot dzwoni do kandydata, zbiera dane, odczytuje treści zgód RODO pobrane z GET …/application-form i rejestruje akceptację (consents[]), składa aplikację (kontakt + CV) i dodaje transkrypcję jako notatkę.
9.2 — Partner ATS: synchronizacja statusów
ATS cyklicznie pobiera statusy kandydatów w projektach; zachowaj odstęp ≥1 s między wywołaniami (limit 70/min).
9.3 — Pipeline danych: eksport odpowiedzi
System analityczny pobiera listę kandydatów, a dla każdego wypełniony formularz (z parametrem locale); odstęp ≥1 s.
10Bezpieczeństwo i higiena
- Poświadczenia: jeden zestaw na system; hasło w sejfie sekretów; nigdy w repo/czacie; rotacja przez „Wygeneruj nowe hasło" (stare unieważniane natychmiast).
- Idempotencja (po stronie integratora): API nie deduplikuje
POST /apply. Strategie: sprawdź kandydatów po e-mailu przed wysłaniem (jeśli go zbierasz — od v1.3 e-mail jest opcjonalny), logujcandidateIdprzed oznaczeniem operacji jako zakończonej, lub użyj wzorca outbox z kluczem idempotencji. - Backoff: wykładniczy od 1 s (limit 30 s) na 429; rozkładaj operacje wsadowe w czasie; unikaj równoległych żądań na jednym poświadczeniu.
- RODO/GDPR: dane kandydatów to dane osobowe (obowiązki po Twojej stronie). Element zwraca
404 candidate_not_founddla kandydatów usuniętych RODO — usuń też swoją kopię.
11Słownik
- Tenant — klient Element (firma); identyfikowany po subdomenie; poświadczenia zablokowane do jednego tenanta.
- Projekt — proces rekrutacyjny na jedno stanowisko; ma listę etapów.
- Etap — krok rekrutacji (Aplikacja, Rozmowa, Oferta…). Etap aplikacyjny (
isApplicationType: true) — miejsce lądowania nowych zgłoszeń, max jeden na projekt. - Kandydat — osoba w CRM Element; może uczestniczyć w wielu projektach.
- Podformularz (sub-form) — zagnieżdżony blok pytań w sekcji (np.
calendar-days,week-days). Od v1.2 zwracany rozwinięty wsubForms[]. - Zgoda RODO (consent) — definicja zgody na przetwarzanie danych zdefiniowana w projekcie; identyfikowana przez
hash(wersję treści). Typy m.in.recruitmentProcess(ta rekrutacja) ifutureRecruitmentProcess(przyszłe procesy). Od v1.4 zwracana wGET …/application-formi przyjmowana wPOST /apply. - Notatka publiczna / prywatna — publiczne widoczne dla konsultantów tenanta i dostępne przez API; prywatne nigdy nie eksponowane.
- RODO / zapomniany — kandydat zażądał usunięcia danych; zwraca 404.
12Zakres i roadmapa
Dostępne w v1-beta. Odczyt: projekty, etapy, kandydaci w projekcie, pełny schemat formularza (z rozwiniętymi podformularzami i definicjami zgód RODO), wypełnione odpowiedzi kandydata, profil kandydata, projekty kandydata, publiczne notatki. Zapis: zgłoszenie aplikacji (nowy kandydat; wymagane tylko imię i nazwisko — e-mail, telefon, CV, załączniki, odpowiedzi, zgody RODO i pliki do pytań plikowych opcjonalne), publiczna notatka.
Planowane (po v1-beta). Zmiana etapu kandydata, odrzucenie, aktualizacja scoringu, dodanie istniejącego kandydata do projektu, utworzenie projektu.
Celowo pominięte. Notatki prywatne (odczyt/zapis), wewnętrzny description CRM, wewnętrzne pola scoringu (obtainedScore, isDisqualified), odpowiedzi na pytania typu referral/languages w POST /apply (pytania plikowe od v1.4 obsługiwane przez answerFiles), deduplikacja kandydatów przy POST /apply.
Kontrakt może zmienić się niekompatybilnie w trakcie bety (~2–3 mies. użycia produkcyjnego); zmiany łamiące komunikowane z wyprzedzeniem. Dodatki minorowe (nowe opcjonalne pola, endpointy, kody błędów) nie są łamiące — Twój klient HTTP powinien tolerować dodatkowe pola.
13Kontakt i wsparcie
Zgłoszenia przez standardowy kanał wsparcia Element. Dołącz: subdomenę, login API, znacznik czasu UTC wywołania, metodę + ścieżkę, status HTTP, treść błędu (przynajmniej error.code i error.message) oraz własny identyfikator korelacji. Te dane pozwalają szybko odnaleźć żądanie w logu audytowym.