Pro vývojáře
Dokumentace API.
Napojte Evaluro na svůj ATS: zakládejte uchazeče a screeningy, stahujte výsledky a dostávejte je webhookem.
Aktualizováno 29. 9. 2026
Rychlý start.
- V HR portálu → Integrace vytvořte API klíč (smí vlastník nebo správce firmy) a zkopírujte si ID pozice z
GET /positions. - Vyzkoušejte napojení nanečisto:
POST /intakes"dryRun": trueprojde všechny kontroly a řekne, co by se stalo – nic nezaloží ani neodešle. - Přidejte adresu webhooku a stiskněte Odeslat test. Každý pokus o doručení uvidíte v přehledu „Doručení webhooků“ i s důvodem případné chyby.
curl https://hireup.inflexion.cz/api/v1/intake \
-H "x-api-key: hu_…" -H "content-type: application/json" \
-d '{ "positionId": "…", "dryRun": true,
"candidate": { "fullName": "Eva Nováková", "email": "eva@example.com", "externalRef": "ats-123" },
"cvText": "…text CV, aspoň 100 znaků…" }'
200 { "dryRun": true, "wouldCreate": "candidate_and_screening", "cv": "text",
"candidate": { "existing": false, "candidateId": null, "profileReady": false },
"warnings": [] }Základy.
- Základní adresa:
https://hireup.inflexion.cz/api/v1, JSON přes HTTPS. Strojově čitelná specifikace: OpenAPI 3.1. - Autentizace hlavičkou
x-api-key. Klíč vydává vlastník nebo správce firmy v HR portálu (Integrace) a patří firmě, ne osobě. Každý klíč vidí jen data své firmy. - Limit: 10 000 požadavků za 24 hodin na klíč (pak
429). Na výsledky nečekejte dotazováním – použijte webhook. - Chyby vrací JSON
{ "error": "kód" }se stavem 400/401/404/409.
curl https://hireup.inflexion.cz/api/v1/positions \
-H "x-api-key: hu_…"Nejrychlejší napojení: jedno volání.
Webhook vašeho ATS zavolá POST /intake hned, jak uchazeč přijde z inzerátu. Pošlete pozici, uchazeče a CV – právě jedno z cvText, cvPdfBase64 (PDF do 3 MB) a cvDocxBase64 (Word .docx do 3 MB; použijeme jen text, soubor neukládáme). Vše ostatní uděláme my: profil z CV, screening a pozvánku e-mailem ("sendInvite": false ji vypne).
POST https://hireup.inflexion.cz/api/v1/intake
{ "positionId": "…",
"candidate": { "fullName": "Eva Nováková", "email": "eva@example.com", "externalRef": "ID v ATS" },
"cvPdfBase64": "JVBERi0x…" }
202 { "candidateId": "…", "status": "waiting_for_profile", "existingCandidate": false }
// nebo "screening_created" + screeningId (+ inviteUrl při novém založení)- Profil z CV trvá obvykle do 30 s. Do té doby je stav
waiting_for_profile; screening založíme, jakmile bude hotový, a dáme vám vědět webhookemscreening.created. - Opakované volání se stejným
externalRefnezaloží duplicitu – vrátí existujícího uchazeče (a jeho živý screening).inviteUrlse vrací jen při novém založení. - Celý požadavek smí mít nejvýš 4,5 MB, proto PDF a Word posílejte do 3 MB; větší CV pošlete jako
cvText. "dryRun": true= zkušební režim: stejné kontroly (klíč, pozice, rubrika, CV) a odpověď200s tím, co by se stalo (wouldCreate,warnings). Nic se neuloží ani neodešle – vhodné pro ladění napojení z ATS.
Bez programování: Make, Zapier, n8n.
Pokud váš ATS umí poslat webhook nebo má aplikaci v Make či Zapieru, napojení zvládnete bez vývojáře:
- Spouštěč v ATS: nový uchazeč nebo přesun do fáze „Screening“ (Recruitis: webhook
answer.add/answer.flow_change; Datacruit: Zapier „New/Updated Status“; Teamtailor, Workable: webhook nebo aplikace). - HTTP modul:
POST https://hireup.inflexion.cz/api/v1/intake, hlavičkax-api-key, tělo jako výše. JakoexternalRefpoužijte ID reakce v ATS – opakované spuštění pak nezaloží duplicitu. - Výsledek zpět: v Make/Zapieru založte „custom webhook“, jeho adresu přidejte v HR portálu a z události
screening.completedzapište do ATS poznámku s doporučením, shrnutím a odkazemreportUrl.
Když nástroj neumí ověřit podpis HMAC, ověřte zprávu aspoň dotazem GET /screenings/{screeningId} s vaším klíčem – podvrženou zprávu tak odhalíte. Do ATS zapisujte doporučení, ne automatické zamítnutí: o uchazeči rozhoduje člověk.
Podrobný postup po krocích.
GET /positions– aktivní pozice se schválenou rubrikou. Každá nese ivisualMode(avatar= AI avatar,orb= animovaný asistent bez tváře): podobu rozhovoru, kterou nový screening na pozici dostane. Přes API se nenastavuje; mění se v HR portálu u pozice, a to jen dokud na pozici nejsou pozvaní uchazeči (všichni uchazeči na pozici mají stejné podmínky).POST /candidates– uchazeč s textem CV; profil je hotový obvykle do 30 s (profileReady).POST /screenings– screening a odkaz pro uchazeče (inviteUrl, jen v této odpovědi). S"sendInvite": truepošleme pozvánku e-mailem my.- Po dokončení přijde webhook
screening.completeds doporučením a odkazem na report. Rozhoduje personalista v Evaluru.
Endpointy.
get/api/v1/me
200 Firma, ke které API klíč patří
get/api/v1/positions
Aktivní pozice firmy (se schválenou rubrikou)
200 Seznam pozic
post/api/v1/candidates
Založit uchazeče (z textu CV se připraví profil, obvykle do 30 s)
| Pole | Typ | Popis |
|---|---|---|
| fullName* | string | |
| email* | string (email) | |
| cvText* | string | Text CV (min. 100 znaků). PDF nebo Word pošlete v base64 přes POST /intake. |
| externalRef | string |
201 Uchazeč založen409 Uchazeč se stejným externalRef už existuje
post/api/v1/intake
Jednokrokový vstup z ATS: uchazeč + CV → screening a pozvánka
Jedno volání pro webhook ATS. Založí uchazeče (nebo najde podle `externalRef`), z CV připraví profil a založí screening s pozvánkou e-mailem. Když je profil hotový, screening vznikne hned (odpověď obsahuje `inviteUrl`); jinak `waiting_for_profile` a screening vznikne do několika minut – ATS se to dozví webhookem `screening.created`. Pozice musí být aktivní se schválenou rubrikou.
| Pole | Typ | Popis |
|---|---|---|
| positionId* | string (uuid) | |
| candidate* | object | |
| cvText | string | Text CV. Pošlete právě jedno z `cvText`, `cvPdfBase64` a `cvDocxBase64`. |
| cvPdfBase64 | string | CV jako PDF v base64 (max. 5 MB po dekódování; uložíme do šifrovaného úložiště). |
| cvDocxBase64 | string | CV ve Wordu (.docx) v base64, max. 5 MB. Použijeme jen jeho text, soubor neukládáme. Starý formát .doc nepodporujeme. |
| variant | demo | short | medium | long | |
| language | cs | en | |
| sendInvite | boolean | Pozvánku pošleme uchazeči e-mailem (výchozí). Jinak ji z API odkaz získáte jen při synchronním založení. |
| dryRun | boolean | Zkušební režim: projde všechny kontroly a vrátí, co by se stalo (200), ale nic nezaloží ani neodešle. Pro ladění napojení. |
200 Zkušební režim (`dryRun`): co by se stalo202 Přijato400 Neplatný vstup nebo soubor (invalid_pdf, pdf_too_large, invalid_docx, docx_too_large, docx_empty)403 Délka screeningu (`variant`) není v tarifu firmy (variant_not_in_tariff)404 Pozice neexistuje409 Pozice není aktivní nebo nemá schválenou rubriku503 Nahrávání PDF není dostupné (pdf_unavailable), pošlete cvText
get/api/v1/candidates/{id}
Uchazeč a stav jeho profilu
Parametry cesty: id
200 Uchazeč404 Uchazeč neexistuje
delete/api/v1/candidates/{id}
Smazat uchazeče a všechna jeho data (CV, screeningy, záznamy, hodnocení)
Pro žádosti uchazečů o výmaz (GDPR čl. 17) a úklid ve vašem ATS. Nevratné. Data se jinak mažou automaticky po lhůtě uchování nastavené firmou.
Parametry cesty: id
204 Smazáno404 Uchazeč neexistuje
post/api/v1/screenings
Založit screening a získat odkaz pro uchazeče
Odkaz `inviteUrl` se vrací jen v této odpovědi (ukládáme jen jeho otisk). Pošlete ho uchazeči. Po dokončení přijde webhook `screening.completed`.
| Pole | Typ | Popis |
|---|---|---|
| positionId* | string (uuid) | |
| candidateId* | string (uuid) | |
| variant | demo | short | medium | long | |
| language | cs | en | |
| reportLanguage | cs | en | |
| answerMode | voice | text | voice = rozhovor s AI avatarem (výchozí), text = písemné odpovědi (přiměřená úprava) |
| extendedTime | boolean | Přiměřená úprava: dvojnásobný čas na odpovědi (max. 180 s na odpověď) |
| sendInvite | boolean | Pošleme uchazeči pozvánku e-mailem (v jazyce rozhovoru). Jinak ji pošlete sami. |
201 Screening založen403 Délka screeningu (`variant`) není v tarifu firmy (variant_not_in_tariff)404 Pozice nebo uchazeč neexistuje409 Pozice nemá schválenou rubriku nebo uchazeč nemá hotový profil503 Přípravu rozhovoru se nepodařilo zařadit (plan_not_queued) – zkuste volání zopakovat
get/api/v1/screenings
Seznam screeningů firmy (nejnovější první, stránkování přes before)
Pro synchronizaci s ATS, když webhook nedorazil. Filtry: stav, uchazeč, dokončené od. Další stránku získáte parametrem before = nextBefore z předchozí odpovědi.
200 Screeningy
get/api/v1/screenings/{id}
Stav screeningu, doporučení a praktické informace uchazeče
Parametry cesty: id
200 Screening404 Screening neexistuje
post/api/v1/screenings/{id}/decision
Zapsat rozhodnutí personalisty z ATS
Pipeline uchazeče řídí ATS: rozhodnutí z ATS se zapíše do Evalura (zdroj `ats`). Stejné rozhodnutí jako poslední se nezapíše (`changed: false`), takže zpětný zápis vlastního webhooku nic nezdvojí. Zamítnutí před začátkem rozhovoru zruší pozvánku. Rozhodnutí s `changed: true` odejde webhookem `screening.decided` se `source: "ats"`.
Parametry cesty: id
| Pole | Typ | Popis |
|---|---|---|
| decision* | advance | hold | reject | |
| note | string | Důvod (interní). Povinný, když je `decision` = `reject`; jinak volitelný. |
| decidedBy* | string | Povinné. Kdo v ATS rozhodl (jméno nebo e-mail oprávněné osoby). |
200 Rozhodnutí zapsané (nebo beze změny)400 Neplatný vstup; u `reject` chybí `note` (invalid_request, issues[].path = note)404 Screening neexistuje
post/api/v1/screenings/{id}/cancel
Zrušit pozvánku (jen než uchazeč začne)
Parametry cesty: id
204 Zrušeno404 Screening neexistuje409 Rozhovor už začal nebo skončil
post/api/v1/screenings/{id}/invite
Nový odkaz pro uchazeče (starý přestane platit, platnost 7 dní)
Pro vypršelé pozvánky nebo ztracený odkaz. Jde jen před začátkem rozhovoru. Volitelné tělo `{ "sendInvite": true }` pošle uchazeči nový odkaz e-mailem.
Parametry cesty: id
200 Nový odkaz404 Screening neexistuje409 Rozhovor už začal nebo skončil
Webhooky.
Adresu webhooku (https) přidá správce v HR portálu → Integrace. Posíláme tyto události: screening.created (screening založený přes /intake; v data jen screeningId, candidate a position s ID, status a inviteSent), screening.completed, screening.decided, screening.expired, screening.failed a screening.accommodation_requested (níže). Adresa odebírá události, které existovaly při jejím přidání – pro novou událost přidejte adresu znovu. Po dokončení hodnocení pošleme POST s tělem:
{
"id": "…", // ID doručení (pro deduplikaci)
"type": "screening.completed",
"createdAt": "2026-09-26T10:00:00.000Z",
"data": {
"screeningId": "…",
"candidate": { "id": "…", "externalRef": "ID ve vašem ATS" },
"position": { "id": "…", "title": "…" },
"recommendation": "advance" | "consider" | "reject" | "insufficient",
"summary": "…",
"competencies": [{ "key": "…", "name": "…", "score": 1–5 | null, "confidence": "…" }],
"logistics": { "salary": { "min", "max", "currency" } | null, "start": { "kind", "date" } | null,
"employment", "note", "skipped", "answeredAt" } | null, // od uchazeče, mimo hodnocení AI
"reportUrl": "https://hireup.inflexion.cz/dashboard/screenings/…",
"decisionRequired": true
}
}Každá zpráva má hlavičku Evaluro-Signature: t=<unix>,v1=<hex>, kde v1 = HMAC-SHA256(tajemství, "t.tělo"). Ověřte podpis a odmítněte zprávy starší než 5 minut. Neúspěšné doručení (jiný stav než 2xx, timeout 10 s) opakujeme až 5×.
Rozhodnutí personalisty – pipeline řídí ATS
Rozhodnutí z HR portálu (pozvat, odložit, zamítnout) pošleme událostí screening.decided; vaše integrace podle něj posune uchazeče v ATS. Rozhodnutí v ATS zapište do Evalura přes POST /screenings/{id}/decision – v reportu se ukáže jako rozhodnutí v ATS a zamítnutí před začátkem rozhovoru zruší pozvánku. Stejné rozhodnutí jako poslední se nezapíše (changed: false). Pole decidedBy (jméno nebo e-mail osoby, která v ATS rozhodla) je povinné, aby šlo doložit lidský přezkum. Webhook se source: "ats" vznikl z vašeho zápisu – do ATS ho znovu nezapisujte. note je interní důvod pro personalisty, ne text pro uchazeče. Pokud uchazeči po zamítnutí píše e-mail vaše ATS, v Evaluru e-mail o výsledku neposílejte.
{
"id": "…",
"type": "screening.decided",
"createdAt": "2026-09-30T10:00:00.000Z",
"data": {
"screeningId": "…",
"decisionId": "…",
"candidate": { "id": "…", "externalRef": "ID ve vašem ATS" },
"position": { "id": "…", "title": "…" },
"status": "completed",
"decision": "advance" | "hold" | "reject",
"note": "…" | null,
"source": "hireup" | "ats",
"decidedBy": "Jméno personalisty" | null,
"decidedAt": "2026-09-30T10:00:00.000Z",
"reportUrl": "https://hireup.inflexion.cz/dashboard/screenings/…"
}
}Uchazeč rozhovor neudělal
screening.expired přijde, když pozvánka vyprší bez rozhovoru (pozvánku jde obnovit přes POST /screenings/{id}/invite). screening.failed přijde, když rozhovor nebo jeho příprava selhaly – založte nový screening. Technický důvod selhání je jen v reportu.
"data": {
"screeningId": "…",
"candidate": { "id": "…", "externalRef": "ID ve vašem ATS" },
"position": { "id": "…", "title": "…" },
"status": "expired" | "failed",
"started": false, // uchazeč rozhovor začal
"expiresAt": "…",
"renewable": true, // jen u expired
"reportUrl": "…"
}Žádost o jinou formu rozhovoru
screening.accommodation_requested přijde, když uchazeč požádá o delší čas, písemné odpovědi nebo rozhovor s člověkem. Posíláme jen druhy úprav – vlastní text uchazeče může obsahovat údaje o zdraví, proto zůstává v reportu (hasNote řekne, že tam je). V ATS z toho udělejte úkol pro personalistu.
"data": {
"screeningId": "…",
"requestId": "…",
"candidate": { "id": "…", "externalRef": "ID ve vašem ATS" },
"position": { "id": "…", "title": "…" },
"kinds": ["more_time" | "text_answers" | "human_interview" | "other" | "new_link"],
"hasNote": true,
"requestedAt": "…",
"reportUrl": "…"
}import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyEvaluro(secret, rawBody, header, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const t = Number(parts.t);
if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(parts.v1 ?? "", "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
}Verzování a změny.
- Verze
v1je stabilní. Bez ohlášení jen přidáváme: nová pole v odpovědích a webhoocích, nové volitelné parametry, nové události a endpointy. Neznámá pole proto ignorujte. - Změnu, která by rozbila existující napojení (odebrání nebo přejmenování pole, jiný význam), vydáme jen jako
v2.v1pak poběží souběžně nejméně 6 měsíců a vlastníky firem s aktivním klíčem upozorníme e-mailem.
- 30. 9. 2026 (večer)
- Rozhodnutí personalisty oběma směry: webhook
screening.decided,POST /screenings/{id}/decision(rozhodnutí z ATS) a poledecisionvGET /screenings/{id}. Webhookyscreening.expired,screening.failedascreening.accommodation_requested. - 30. 9. 2026
POST /intake: CV ve Wordu (cvDocxBase64) a zkušební režim (dryRun). V HR portálu přehled doručení webhooků.- 29. 9. 2026
POST /intake(jedno volání z ATS), webhookscreening.created, praktické informace od uchazeče vscreening.completed(polelogistics).- 26. 9. 2026
GET /screeningsse stránkováním,POST /screenings/{id}/cancela/invite,DELETE /candidates/{id}, jednotné chyby, limit 10 000 požadavků za den.- 24. 9. 2026
- První verze API v1 a webhooku
screening.completed.
Osobní údaje přes API.
- Na žádost uchazeče o výmaz zavolejte
DELETE /candidates/{id}– smaže CV, screeningy, záznamy i hodnocení. - Jinak se data smažou automaticky po lhůtě uchování nastavené firmou.
- Webhook nenese přepis ani citace – ty zůstávají v reportu v Evaluru.