{"openapi":"3.1.0","info":{"title":"Partner API tview","version":"1.3.1","description":"Server-to-server API do integracji przepływów rekrutacyjnych tview z platformami partnerów i tablicami ogłoszeń.\n\n## Model danych\n\n- **Projekt** — nadrzędny kontener rekrutacyjny. Utwórz jeden projekt dla każdej roli lub rundy rekrutacyjnej, a nie dla każdego kandydata ani screeningu.\n- **Kroki potoku** — uporządkowane etapy w projekcie. Wartości `type` kroków utrwalone w API to teraz `screening`, `coding_task`, `video_interview`, `case_study`, `documents_upload` lub `custom`.\n- **Aplikacja** — ścieżka kandydata przez jeden projekt.\n- **Wynik kroku** — stan dla aplikacji i kroku: odpowiedzi, przesłany kod, oceny i nagrania.\n- **Sesja treningu rozmowy** — próbna rozmowa kandydata wygenerowana na podstawie projektu, oferty pracy lub surowego ogłoszenia. Nie jest częścią ocenianego pipeline rekrutacyjnego, chyba że partner mapuje ją do własnego przepływu.\n\n## Zalecany schemat integracji\n\n1. Utwórz projekt dla każdej odrębnej roli lub rundy rekrutacyjnej.\n2. Skonfiguruj jego pipeline z jednym lub większą liczbą kroków.\n3. Zaproś kandydatów do projektu. Każdy kandydat otrzymuje jedną aplikację na projekt.\n4. Pozwól kandydatom przejść kroki pipeline; wyniki i oceny pojawią się w wynikach kroków.\n\nUnikaj tworzenia nowego projektu dla każdego pojedynczego etapu selekcji — etapy selekcji są krokami potoku, a nie samodzielnymi obiektami.\n\n## Typy etapów procesu\n\n- `screening` — krok kwestionariusza/screeningu. Pytania znajdują się w `config.questions` albo można je utworzyć dla aplikacji przez `/api/v1/applications/{id}/screening-compose`.\n- `coding_task` — zadanie programistyczne lub techniczne. Główna treść zwykle znajduje się w `config.challenge`; opcjonalne pola to `config.language`, `config.difficulty` i `config.instructions`.\n- `video_interview` — krok rozmowy wideo. Pytania znajdują się w `config.questions`; `config.recordingEnabled=false` wyłącza nagrywanie sesji.\n- `case_study` — krok case study. Użyj `config.brief` i opcjonalnego `config.format` (`written`, `presentation` lub `both`).\n- `documents_upload` — krok przesyłania dokumentów. Użyj `config.requiredDocuments`, `config.maxFileSizeMb`, `config.allowMultiple` i `config.acceptedFormats`.\n- `custom` — punkt rozszerzeń dla niestandardowych kroków. Użyj `config.customType` dla maszynowo odczytywanego zachowania.\n\nKompatybilność wsteczna: dane ze starą reprezentacją `type: custom` i `config.subType: case_study` lub `config.subType: documents_upload` są nadal akceptowane i normalizowane do nowych typów.\n\n## Uwierzytelnianie\n\nKlucze API Bearer (`tv_live_*` / `tv_test_*`). Uwierzytelnione odpowiedzi zawierają `X-Request-Id`, `X-Correlation-Id`, `X-RateLimit-Limit`, `X-RateLimit-Remaining` i `X-RateLimit-Reset`.\n\n## Idempotencja\n\nPOST `/api/v1/projects`, `/api/v1/projects/{id}/generate-pipeline`, `/api/v1/projects/{id}/candidates`, `/api/v1/projects/{id}/candidates/bulk`, `/api/v1/applications/{id}/evaluate`, `/api/v1/interview-training/sessions`, `/api/v1/interview-training/sessions/{id}/answers`, `/api/v1/interview-training/sessions/{id}/summary` i `/api/v1/webhooks/test` obsługują nagłówek `Idempotency-Key`.\n\n## Przepływ aplikacji hostowany przez partnera\n\n- tworzenie tokenizowanych sesji aplikacji bez rejestracji/logowania kandydata\n- oznaczanie profili kandydatów jako dostarczonych przez partnera i pomijanie hostowanego zbierania profilu\n- przechowywanie zgody dostarczonej przez partnera\n- dostosowanie treści hostowanej strony aplikacji dla każdej aplikacji przez `applicationPage`\n- opcjonalne przełączenie hostowanego przepływu w tryb vanilla shadcn whitelabel z `hostedBranding` dla każdej aplikacji\n- zwracanie `externalCandidateId` i publicznych `metadata` w API aplikacji i webhookach\n\n## Komponowanie selekcji\n\n`POST /api/v1/applications/{id}/screening-compose` tworzy ręczne i wygenerowane pytania dla aplikacji. Użyj `stepId`, gdy aplikacja ma więcej niż jeden krok screeningu. Zgłoszenia screeningu przechowują migawkę pytań, aby późniejsze edycje nie zmieniały historii.\n\n## Trening rozmowy\n\n- tworzenie sesji treningowych na podstawie projektu, oferty pracy lub surowego tekstu ogłoszenia\n- udostępnianie kolejnego pytania bez odpowiedzi w osadzonych przepływach kandydata\n- przesyłanie odpowiedzi kandydata z treningu i zwracanie informacji coachingowych\n- generowanie końcowego raportu gotowości dla konkretnego ogłoszenia\n\n## Endpointy rozliczane według użycia\n\n- `POST /api/v1/projects/{id}/generate-pipeline` → kredyt generowania\n- `POST /api/v1/applications/{id}/evaluate` → kredyt oceny screeningu/kodu\n- `POST /api/v1/interview-training/sessions` → kredyt generowania po udanym generowaniu przez AI\n- `POST /api/v1/interview-training/sessions/{id}/answers` → kredyt oceny screeningu po udanym feedbacku AI\n- `POST /api/v1/interview-training/sessions/{id}/summary` → kredyt podsumowania po udanym podsumowaniu AI\n\n## Webhooks\n\nKontrakt danych: `{ event, timestamp, data }` z podpisem HMAC SHA-256 w `X-Tview-Signature`.\n\nAvailable application i usage events: `application.created`, `application.started`, `application.completed`, `application.decided`, `application.stage_changed`, `screening.submitted`, `screening.evaluated`, `code.submitted`, `code.evaluated`, `interview.started`, `interview.completed`, `balance.low`, `balance.depleted`.\n\n`application.decided` is sent when a recruiter moves a candidate forward, rejects them, records a withdrawal or reopens the application. `data.decision` carries `type` (`advanced`, `rejected`, `withdrawn`, `reopened`), the resulting `status`, `reason` i `decidedAt`. Internal recruiter notes are never included.\n\n`application.stage_changed` is sent when a candidate moves between hiring stages (for example from AI screening to Interview). `data.stage` carries `from` i `to`, each with `id`, `kind` (`new`, `screening`, `interview`, `offer`, `hired`) and `name`.\n\n## Metadane\n\n`metadata.__tview` jest zarezerwowane do użytku wewnętrznego i nie może być wysyłane przez partnerów."},"servers":[{"url":"https://tview.work","description":"Produkcyjne API (główne)"},{"url":"https://jobs.tview.work","description":"Produkcyjne API (host kandydata)"},{"url":"http://localhost:3000","description":"Środowisko lokalne"}],"externalDocs":{"description":"Dokumentacja towarzysząca i notatki wdrożeniowe","url":"https://tview.work/docs"},"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Klucz Partner API w formacie `tv_live_*` lub `tv_test_*`"}},"parameters":{"PageParam":{"name":"page","in":"query","schema":{"type":"integer","default":1,"minimum":1}},"LimitParam":{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},"ProjectId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"ApplicationId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"CandidateId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"WebhookId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"InterviewTrainingSessionId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":1,"maxLength":255}}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}},"PaginationMeta":{"type":"object","properties":{"total":{"type":"integer","example":42},"page":{"type":"integer","example":1},"limit":{"type":"integer","example":20}}},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"roleType":{"type":"string","nullable":true},"status":{"type":"string","enum":["draft","active","archived","closed"]},"isPublished":{"type":"boolean"},"defaultHostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"ProjectReadiness":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["draft","active","archived","closed"]},"isPublished":{"type":"boolean"},"hasScreeningStep":{"type":"boolean"},"hasDefaultHostedBranding":{"type":"boolean"},"defaultHostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"},"isWhitelabelActive":{"type":"boolean"},"effectiveHostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"},"hasActiveJobOffer":{"type":"boolean"},"issues":{"type":"array","items":{"type":"string"}}}},"PipelineStep":{"type":"object","description":"Zapisany krok potoku rekrutacyjnego. `case_study` i `documents_upload` to pełnoprawne typy kroków. Starsze ładunki `type: custom` z `config.subType` dla tych kroków są nadal akceptowane i normalizowane.","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["screening","coding_task","video_interview","case_study","documents_upload","custom"]},"title":{"type":"string"},"order":{"type":"integer"},"config":{"type":"object","additionalProperties":true,"description":"Konfiguracja właściwa dla kroku. Dla video_interview recordingEnabled domyślnie ma wartość true; ustaw recordingEnabled=false, aby wyłączyć nagrywanie sesji. W studiach przypadku użyj type=case_study z config.brief i opcjonalnym config.format. W przypadku przesyłania dokumentów użyj type=documents_upload z config.requiredDocuments, config.maxFileSizeMb, config.allowMultiple i config.acceptedFormats.","properties":{"recordingEnabled":{"type":"boolean","default":true},"subType":{"type":"string","enum":["case_study","documents_upload"],"deprecated":true,"description":"Wyłącznie zgodność ze starszą wersją. Preferuj pełnoprawne wartości typów kroków."},"customType":{"type":"string","example":"manual_review"},"brief":{"type":"string","description":"Opis studium przypadku dla type=case_study"},"format":{"type":"string","enum":["written","presentation","both"]},"requiredDocuments":{"type":"array","items":{"type":"string"},"description":"Wymagane nazwy dokumentów dla type=documents_upload"},"maxFileSizeMb":{"type":"integer"},"allowMultiple":{"type":"boolean"},"acceptedFormats":{"type":"string","example":".pdf,.doc,.docx,.txt,.zip"},"questions":{"type":"array","items":{},"description":"Pytania selekcyjne lub do rozmowy"},"challenge":{"type":"string","description":"Treść zadania programistycznego"},"instructions":{"type":"string"},"durationMinutes":{"type":"integer"}}},"isRequired":{"type":"boolean"}}},"GeneratedPipelineStep":{"type":"object","description":"Węzeł potoku wygenerowany przez AI. `type` to zapisany typ API/bazy danych. `nodeType` odzwierciedla wygenerowany węzeł semantyczny i jest zachowywany dla klientów rozróżniających kształty wygenerowane i zapisane.","properties":{"type":{"type":"string","enum":["screening","coding_task","video_interview","case_study","documents_upload","custom"]},"nodeType":{"type":"string","enum":["screening","coding_task","video_interview","case_study","documents_upload","custom"]},"title":{"type":"string"},"description":{"type":"string"},"isRequired":{"type":"boolean"},"config":{"type":"object","additionalProperties":true}}},"CandidateInvite":{"type":"object","required":["email","firstName","lastName"],"properties":{"email":{"type":"string","format":"email"},"firstName":{"type":"string"},"lastName":{"type":"string"},"phone":{"type":"string"},"cvText":{"type":"string"},"cvUrl":{"type":"string","format":"uri"},"externalCandidateId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"profileCollectionMode":{"type":"string","enum":["hosted","partner_provided"]},"partnerProvidedConsent":{"type":"object","additionalProperties":true,"properties":{"dataProcessing":{"type":"boolean"},"aiProcessing":{"type":"boolean"},"recording":{"type":"boolean"},"profileSharing":{"type":"boolean"},"source":{"type":"string"},"collectedAt":{"type":"string","format":"date-time"},"metadata":{"type":"object","additionalProperties":true}}},"profile":{"$ref":"#/components/schemas/CandidateProfileUpsert"},"applicationPage":{"$ref":"#/components/schemas/ApplicationPageInput"},"hostedBranding":{"$ref":"#/components/schemas/HostedBrandingInput"}}},"ApplicationPageInput":{"type":"object","description":"Nadpisania treści hostowanego ekranu aplikacji dla konkretnej aplikacji. Obsługuje surową treść lub szablony ze zmiennymi.","properties":{"locale":{"type":"string","enum":["en","pl"]},"title":{"type":"string"},"subtitle":{"type":"string"},"description":{"type":"string"},"profileNotice":{"type":"string"},"consentNotice":{"type":"string"},"ctaLabel":{"type":"string"},"titleTemplate":{"type":"string"},"subtitleTemplate":{"type":"string"},"descriptionTemplate":{"type":"string"},"profileNoticeTemplate":{"type":"string"},"consentNoticeTemplate":{"type":"string"},"variables":{"type":"object","additionalProperties":true},"labels":{"type":"object","properties":{"applicationHeader":{"type":"string"},"processHeader":{"type":"string"},"profileSectionTitle":{"type":"string"},"consentSectionTitle":{"type":"string"}}}}},"ApplicationPageResolved":{"type":"object","description":"Rozwiązana treść hostowanego ekranu aplikacji zwracana przez API aplikacji po zastosowaniu szablonów i wartości domyślnych.","properties":{"locale":{"type":"string","enum":["en","pl"]},"title":{"type":"string"},"subtitle":{"type":"string"},"description":{"type":"string"},"profileNotice":{"type":"string"},"consentNotice":{"type":"string"},"ctaLabel":{"type":"string"},"labels":{"type":"object","properties":{"applicationHeader":{"type":"string"},"processHeader":{"type":"string"},"profileSectionTitle":{"type":"string"},"consentSectionTitle":{"type":"string"}}}}},"HostedBrandingInput":{"type":"object","description":"Nadpisania hostowanego brandingu dla konkretnej aplikacji. Użyj `mode=whitelabel`, aby wyświetlić hostowany przepływ z neutralną powłoką w stylu shadcn oraz opcjonalnym logo i kolorami partnera.","properties":{"mode":{"type":"string","enum":["default","whitelabel"]},"logoUrl":{"type":"string","format":"uri"},"companyName":{"type":"string"},"primaryColor":{"type":"string","pattern":"^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"},"accentColor":{"type":"string","pattern":"^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$"}}},"HostedBrandingResolved":{"type":"object","description":"Rozwiązany branding hostowany zwracany przez API aplikacji po zastosowaniu wartości domyślnych i zapasowych.","properties":{"mode":{"type":"string","enum":["default","whitelabel"]},"logoUrl":{"type":"string","format":"uri","nullable":true},"companyName":{"type":"string","nullable":true},"primaryColor":{"type":"string","nullable":true},"accentColor":{"type":"string","nullable":true},"isWhitelabel":{"type":"boolean"}}},"ScreeningQuestionEntry":{"type":"object","description":"Wpis wyniku selekcji na poziomie pytania, używany w API aplikacji i webhookach selekcji.","properties":{"questionId":{"type":"string"},"source":{"type":"string","enum":["manual","generated"]},"externalQuestionId":{"type":"string","nullable":true},"text":{"type":"string"},"answer":{"nullable":true},"score":{"type":"number","nullable":true},"metadata":{"type":"object","additionalProperties":true,"nullable":true}}},"ScreeningComposeRequest":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"},"locale":{"type":"string","enum":["en","pl"]},"manualQuestions":{"type":"array","items":{"type":"object","properties":{"externalQuestionId":{"type":"string"},"text":{"type":"string"},"type":{"type":"string","enum":["scale","single_choice","multiple_choice","ordering","open"]},"options":{"type":"array","items":{"type":"string"}},"scaleMin":{"type":"integer"},"scaleMax":{"type":"integer"},"scaleMinLabel":{"type":"string"},"scaleMaxLabel":{"type":"string"},"isRequired":{"type":"boolean"},"metadata":{"type":"object","additionalProperties":true}}}},"generatedQuestions":{"type":"object","properties":{"enabled":{"type":"boolean"},"count":{"type":"integer"},"basedOn":{"type":"array","items":{"type":"string"}},"instructions":{"type":"string"}}},"mergeStrategy":{"type":"string","enum":["manual_first","generated_first","interleave"]},"deduplicate":{"type":"boolean"},"replaceExisting":{"type":"boolean"}}},"CandidateProfileUpsert":{"type":"object","properties":{"headline":{"type":"string","nullable":true},"bio":{"type":"string","nullable":true},"skills":{"type":"array","items":{"type":"string"}},"experienceYears":{"type":"integer","nullable":true},"cvUrl":{"type":"string","format":"uri","nullable":true},"linkedinUrl":{"type":"string","format":"uri","nullable":true},"githubUrl":{"type":"string","format":"uri","nullable":true}}},"InterviewTrainingSessionCreate":{"type":"object","description":"Podaj dokładnie jedno z: projectId, jobOfferId lub postingText.","properties":{"projectId":{"type":"string","format":"uuid"},"jobOfferId":{"type":"string","format":"uuid"},"postingText":{"type":"string","minLength":100,"maxLength":50000},"title":{"type":"string","maxLength":500},"roleType":{"type":"string","maxLength":100},"locale":{"type":"string","enum":["en","pl"],"default":"en"},"questionCount":{"type":"integer","minimum":3,"maximum":12,"default":6}}},"InterviewTrainingQuestion":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["hr","technical","experience","situational"]},"text":{"type":"string"},"expectedSignals":{"type":"array","items":{"type":"string"}}}},"InterviewTrainingFeedback":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"summary":{"type":"string"},"strengths":{"type":"array","items":{"type":"string"}},"improvements":{"type":"array","items":{"type":"string"}},"suggestedAnswer":{"type":"string"}}},"InterviewTrainingAnswerCreate":{"type":"object","required":["questionId","answerText"],"properties":{"questionId":{"type":"string"},"answerText":{"type":"string","maxLength":20000}}},"InterviewTrainingAnswer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sessionId":{"type":"string","format":"uuid"},"questionId":{"type":"string"},"questionIndex":{"type":"integer"},"questionText":{"type":"string"},"answerText":{"type":"string"},"feedback":{"$ref":"#/components/schemas/InterviewTrainingFeedback"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"InterviewTrainingSummary":{"type":"object","properties":{"score":{"type":"integer","minimum":0,"maximum":100},"readiness":{"type":"string","enum":["low","medium","high"]},"summary":{"type":"string"},"strengths":{"type":"array","items":{"type":"string"}},"gaps":{"type":"array","items":{"type":"string"}},"nextSteps":{"type":"array","items":{"type":"string"}}}},"InterviewTrainingProgress":{"type":"object","properties":{"answered":{"type":"integer"},"total":{"type":"integer"},"completed":{"type":"boolean"}}},"InterviewTrainingSession":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid","nullable":true},"jobOfferId":{"type":"string","format":"uuid","nullable":true},"sourceType":{"type":"string","enum":["project","job_offer","raw_text"]},"status":{"type":"string","enum":["active","completed"]},"title":{"type":"string"},"roleType":{"type":"string","nullable":true},"locale":{"type":"string","enum":["en","pl"]},"questions":{"type":"array","items":{"$ref":"#/components/schemas/InterviewTrainingQuestion"}},"summary":{"anyOf":[{"$ref":"#/components/schemas/InterviewTrainingSummary"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"ShortlistCandidate":{"type":"object","required":["applicationId","overall","overallLower","overallUpper","coverage","gateStatus","conflicts"],"properties":{"applicationId":{"type":"string","format":"uuid"},"overall":{"type":"number","example":71.25},"overallLower":{"type":"number","example":66.5},"overallUpper":{"type":"number","example":76},"coverage":{"type":"number","minimum":0,"maximum":1,"description":"Odsetek kompetencji ze skali oceny objętych dowodami"},"gateStatus":{"type":"string","enum":["pass","failed","insufficient_evidence"]},"conflicts":{"type":"array","items":{"type":"string"},"description":"Klucze kompetencji ze sprzecznymi dowodami"},"rank":{"type":"integer","minimum":1,"description":"Pozycja liczona od 1 wśród uszeregowanych kandydatów. Nie dotyczy przypiętych kandydatów, którzy zajmują początek listy."}}},"Webhook":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"secret":{"type":"string"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"HealthChecks":{"type":"object","properties":{"database":{"type":"boolean"},"blob":{"type":"boolean"},"ai":{"type":"boolean"},"tavus":{"type":"boolean"},"stripe":{"type":"boolean"},"workos":{"type":"boolean"}}}},"responses":{"Unauthorized":{"description":"Brak klucza API lub nieprawidłowy klucz API","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"ValidationError":{"description":"Weryfikacja żądania nie powiodła się","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"Forbidden":{"description":"Konto partnera jest zawieszone","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"NotFound":{"description":"Nie znaleziono zasobu","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}},"RateLimited":{"description":"Przekroczono limit zapytań","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid request payload"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","example":"title"},"message":{"type":"string","example":"Required"},"code":{"type":"string","example":"invalid_type"}}}}}}}}}}}}},"paths":{"/api/v1/health":{"get":{"summary":"Stan usługi","tags":["Health"],"security":[],"responses":{"200":{"description":"Wynik kontroli kondycji","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"checks":{"$ref":"#/components/schemas/HealthChecks"}}}}}},"503":{"description":"Usługa działa w ograniczonym zakresie","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"checks":{"$ref":"#/components/schemas/HealthChecks"}}}}}}}}},"/api/v1/ready":{"get":{"summary":"Status gotowości","tags":["Health"],"security":[],"responses":{"200":{"description":"Usługa jest gotowa","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ready"},"timestamp":{"type":"string","format":"date-time"},"checks":{"type":"object","properties":{"database":{"type":"boolean"},"env":{"type":"boolean"}}}}}}}},"503":{"description":"Usługa nie jest gotowa","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"not_ready"},"timestamp":{"type":"string","format":"date-time"},"checks":{"type":"object","properties":{"database":{"type":"boolean"},"env":{"type":"boolean"}}}}}}}}}}},"/api/v1/projects":{"get":{"summary":"Lista projektów","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","schema":{"type":"string","enum":["draft","active","archived","closed"]}}],"responses":{"200":{"description":"Lista projektów","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"summary":"Utwórz projekt","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"roleType":{"type":"string"},"defaultHostedBranding":{"$ref":"#/components/schemas/HostedBrandingInput"},"pipeline":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"responses":{"201":{"description":"Projekt utworzony","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/projects/{id}":{"get":{"summary":"Pobierz projekt","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Szczegóły projektu","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/Project"},{"type":"object","properties":{"pipeline":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}},"candidateCount":{"type":"integer"}}}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Zaktualizuj projekt","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string","nullable":true},"roleType":{"type":"string","nullable":true},"status":{"type":"string","enum":["draft","active","archived","closed"]},"isPublished":{"type":"boolean"},"defaultHostedBranding":{"anyOf":[{"$ref":"#/components/schemas/HostedBrandingInput"},{"type":"null"}]}}}}}},"responses":{"200":{"description":"Projekt zaktualizowany","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"summary":"Archiwizuj projekt","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Projekt zarchiwizowany","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"archived"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/readiness":{"get":{"summary":"Pobierz gotowość projektu","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Podsumowanie gotowości projektu","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ProjectReadiness"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/pipeline":{"get":{"summary":"Lista kroków potoku","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Etapy rekrutacji","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"summary":"Zastąp potok","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["steps"],"properties":{"steps":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"responses":{"200":{"description":"Potok zaktualizowany","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PipelineStep"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Usunięty krok potoku jest nadal używany przez aplikację","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/projects/{id}/generate-pipeline":{"post":{"summary":"Wygeneruj potok AI","description":"Generuje propozycję potoku. Zwracane kroki zawierają zapisane `type` oraz `nodeType`; `case_study` i `documents_upload` to pełnoprawne typy kroków.","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"roleType":{"type":"string"}}}}}},"responses":{"200":{"description":"Wygenerowana propozycja potoku","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"steps":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedPipelineStep"}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/projects/{id}/context":{"get":{"summary":"Lista dokumentów kontekstu projektu","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Rekordy kontekstu","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Prześlij kontekst projektu","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","name"],"properties":{"type":{"type":"string","enum":["job_spec","rubric","requirements","other"]},"name":{"type":"string"},"content":{"type":"string"},"fileUrl":{"type":"string","format":"uri"}}}},"multipart/form-data":{"schema":{"type":"object","required":["type","name"],"properties":{"type":{"type":"string","enum":["job_spec","rubric","requirements","other"]},"name":{"type":"string"},"content":{"type":"string"},"fileUrl":{"type":"string","format":"uri"},"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"Kontekst zapisany","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/apply-url":{"get":{"summary":"Pobierz publiczny odnośnik aplikowania do projektu","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"Publiczny odnośnik dla kandydata na hoście ofert","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"kind":{"type":"string","enum":["offer_permalink","marketplace_fallback"]}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/projects/{id}/candidates":{"get":{"summary":"Lista kandydatów projektu","description":"Lista kandydatów projektu","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","schema":{"type":"string","enum":["new","invited","in_progress","completed","rejected","accepted","withdrawn"]}}],"responses":{"200":{"description":"Lista kandydatów","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"summary":"Utwórz tokenizowaną sesję aplikacji kandydata","description":"Tworzy lub ponownie wykorzystuje parę kandydat/aplikacja i zwraca hostowany `applyUrl`. Obsługuje dane profilu przekazane przez partnera, zgody, metadane, nadpisania treści hostowanego ekranu aplikacji przez `applicationPage` oraz branding whitelabel przez `hostedBranding`.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateInvite"}}}},"responses":{"200":{"description":"Kandydat zaproszony","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"candidateId":{"type":"string","format":"uuid"},"applicationId":{"type":"string","format":"uuid"},"token":{"type":"string"},"applyUrl":{"type":"string","format":"uri"},"externalCandidateId":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"profileCollectionMode":{"type":"string","enum":["hosted","partner_provided"]},"partnerProvidedConsent":{"type":"object","additionalProperties":true},"applicationPage":{"$ref":"#/components/schemas/ApplicationPageResolved"},"hostedBranding":{"$ref":"#/components/schemas/HostedBrandingResolved"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}},"/api/v1/projects/{id}/candidates/bulk":{"post":{"summary":"Zaproś kandydatów zbiorczo","description":"Tworzy lub ponownie wykorzystuje zbiorczo pary kandydat/aplikacja. Każdy pomyślny wynik zawiera tokenizowany `applyUrl`, publiczne `metadata` oraz rozwiązane `applicationPage` i `hostedBranding` dla tej aplikacji.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["candidates"],"properties":{"candidates":{"type":"array","items":{"$ref":"#/components/schemas/CandidateInvite"}}}}}}},"responses":{"200":{"description":"Wynik importu zbiorczego","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}},"/api/v1/projects/{id}/shortlist":{"get":{"summary":"Pobierz krótką listę projektu","description":"Zwraca deterministyczną krótką listę projektu: najpierw przypiętych kandydatów, a następnie kandydatów uszeregowanych od 1. Kandydaci zablokowani przez nieudaną bramkę lub niewystarczające dowody nie są zwracani. Wyniki są w skali 0–100; `overallLower` i `overallUpper` wyznaczają przedział wyniku i nie są ograniczane do tego zakresu. Odpowiedzi nie zawierają tożsamości kandydata — należy połączyć je po `applicationId`.","tags":["Projects"],"parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"mode","in":"query","description":"Sygnał rankingu. `lcb` (domyślnie) sortuje według dolnej granicy ufności, więc pewny wynik wyprzedza spekulatywny; `mean` sortuje według wartości punktowej.","schema":{"type":"string","enum":["lcb","mean"],"default":"lcb"}}],"responses":{"200":{"description":"Krótka lista projektu","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","required":["mode","generatedAt","candidates"],"properties":{"mode":{"type":"string","enum":["lcb","mean"]},"generatedAt":{"type":"string","format":"date-time"},"candidates":{"type":"array","items":{"$ref":"#/components/schemas/ShortlistCandidate"}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/applications/{id}":{"get":{"summary":"Pobierz szczegóły aplikacji","description":"Zwraca status aplikacji, treść hostowanej strony aplikacji, branding hostowany w trybie whitelabel, wyniki na poziomie kroków oraz `questionEntries` selekcji zachowujące źródło pytania (`manual` lub `generated`). Ukończone aplikacje udostępniają także `recording`, `recordingUrl` i `transcript`, gdy dostępne jest nagranie lub transkrypcja rozmowy wideo. Adresy URL nagrań są podpisane, wygasają po godzinie i można je otworzyć w przeglądarce bez nagłówków Partner API.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"responses":{"200":{"description":"Szczegóły aplikacji","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/screening-compose":{"post":{"summary":"Skomponuj pytania selekcyjne zależne od kroku dla aplikacji","description":"Tworzy zestaw pytań selekcyjnych z ręcznych pytań partnera i opcjonalnych pytań wygenerowanych przez tview z uwzględnieniem profilu. Jeśli aplikacja ma wiele etapów selekcji, przekaż `stepId`, aby wskazać właściwy etap. Migawki wysłanych selekcji są niezmienne i zachowywane w późniejszych odczytach oraz webhookach.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreeningComposeRequest"}}}},"responses":{"200":{"description":"Skomponowany zestaw pytań","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"stepId":{"type":"string","format":"uuid"},"questionSetId":{"type":"string"},"generationVersion":{"type":"integer"},"questions":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}},"/api/v1/applications/{id}/recording":{"get":{"summary":"Skomponowany zestaw pytań","description":"Zwraca podpisany adres URL, który można otworzyć w przeglądarce, dla ukończonych nagrań aplikacji. Podpisany adres wygasa po godzinie i po otwarciu w przeglądarce nie wymaga nagłówków Partner API.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"responses":{"200":{"description":"Adres URL nagrania","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"source":{"type":"string","enum":["tavus","browser"]},"contentType":{"type":"string","enum":["video/mp4","video/webm"]},"expiresAt":{"type":"string","format":"date-time"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/recording/browser":{"get":{"summary":"Odtwórz ukończone nagranie z przeglądarki","description":"Przesyła najnowsze ukończone nagranie rozmowy wideo z prywatnego magazynu. Ten endpoint wymaga klucza Partner API typu bearer i uprawnień do aplikacji; mimo nazwy nie jest nieuwierzytelnionym adresem przeglądarkowym. Przekieruj go przez własny serwer albo pobierz krótkotrwały podpisany adres z endpointu nagrania do bezpośredniego odtwarzania w przeglądarce. Zwraca video/webm (lub zarejestrowany typ MIME) z Cache-Control: private, no-store. Jeśli sfinalizowane nagranie jest niedostępne, zapisane fragmenty są przesyłane w kolejności.","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"}],"responses":{"200":{"description":"Prywatny strumień nagrania","content":{"video/webm":{"schema":{"type":"string","format":"binary"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/recording/signed":{"get":{"summary":"Otwórz podpisane nagranie rozmowy","description":"Publiczny, krótkotrwały cel podpisanego adresu URL nagrania. Partnerzy powinni pobierać ten adres przez `GET /api/v1/applications/{id}` lub `GET /api/v1/applications/{id}/recording`; nie należy konstruować go ręcznie.","tags":["Applications"],"security":[],"parameters":[{"$ref":"#/components/parameters/ApplicationId"},{"name":"expires","in":"query","required":true,"schema":{"type":"integer"}},{"name":"signature","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Strumień nagrania w przeglądarce","content":{"video/webm":{"schema":{"type":"string","format":"binary"}}}},"302":{"description":"Przekieruj do hostowanego nagrania"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/applications/{id}/evaluate":{"post":{"summary":"Oceń etap aplikacji","tags":["Applications"],"parameters":[{"$ref":"#/components/parameters/ApplicationId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stepId"],"properties":{"stepId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Wynik oceny","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"score":{"type":"number"},"evaluation":{"type":"object","description":"Always carries summary, strengths, weaknesses i recommendation, plus correctness and codeQuality for coding steps. A project scored against a rubric additionally returns mode=\"two_stage\" with rubric, competencies and criterionScores; single-shot evaluations omit those keys.","additionalProperties":true,"properties":{"mode":{"type":"string","enum":["two_stage"]},"summary":{"type":"string"},"recommendation":{"type":"string"}}}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/candidates/{id}":{"get":{"summary":"Pobierz profil kandydata","description":"Zwraca rekord kandydata, opcjonalny profil przekazany przez partnera oraz wszystkie aplikacje widoczne dla partnera. Każda aplikacja zawiera publiczne `metadata` oraz rozwiązane wartości `applicationPage` i `hostedBranding`.","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/CandidateId"}],"responses":{"200":{"description":"Profil kandydata i aplikacje","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/candidates/{id}/profile":{"put":{"summary":"Utwórz lub zaktualizuj profil kandydata przekazany przez partnera","tags":["Candidates"],"parameters":[{"$ref":"#/components/parameters/CandidateId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateProfileUpsert"}}}},"responses":{"200":{"description":"Profil kandydata zaktualizowany","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/usage":{"get":{"summary":"Bieżące podsumowanie użycia","tags":["Usage"],"responses":{"200":{"description":"Użycie w bieżącym miesiącu","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/usage/history":{"get":{"summary":"Historia użycia","tags":["Usage"],"parameters":[{"name":"months","in":"query","schema":{"type":"integer","default":6,"minimum":1,"maximum":24}}],"responses":{"200":{"description":"Historia użycia","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/balance":{"get":{"summary":"Bieżące saldo","tags":["Usage"],"responses":{"200":{"description":"Ustawienia salda i automatycznych doładowań","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/interview-training/sessions":{"post":{"summary":"Utwórz sesję treningową rozmowy","description":"Tworzy sesję treningową rozmowy opartą na ogłoszeniu o pracę na podstawie projektu, oferty pracy lub surowego tekstu ogłoszenia.","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTrainingSessionCreate"}}}},"responses":{"201":{"description":"Sesja treningowa rozmowy utworzona","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/InterviewTrainingSession"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/interview-training/sessions/{id}":{"get":{"summary":"Pobierz sesję treningową rozmowy","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"}],"responses":{"200":{"description":"Sesja treningowa rozmowy","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/InterviewTrainingSession"},{"type":"object","properties":{"answers":{"type":"array","items":{"$ref":"#/components/schemas/InterviewTrainingAnswer"}},"progress":{"$ref":"#/components/schemas/InterviewTrainingProgress"}}}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/interview-training/sessions/{id}/next-question":{"get":{"summary":"Pobierz następne pytanie treningowe rozmowy","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"}],"responses":{"200":{"description":"Następne pytanie bez odpowiedzi","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"question":{"anyOf":[{"$ref":"#/components/schemas/InterviewTrainingQuestion"},{"type":"null"}]},"progress":{"$ref":"#/components/schemas/InterviewTrainingProgress"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/interview-training/sessions/{id}/answers":{"post":{"summary":"Wyślij odpowiedź treningową z rozmowy","description":"Zapisuje odpowiedź treningową kandydata i zwraca informacje zwrotne trenera.","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTrainingAnswerCreate"}}}},"responses":{"200":{"description":"Informacja zwrotna do odpowiedzi","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"answer":{"$ref":"#/components/schemas/InterviewTrainingAnswer"},"feedback":{"$ref":"#/components/schemas/InterviewTrainingFeedback"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/interview-training/sessions/{id}/summary":{"post":{"summary":"Wygeneruj podsumowanie treningu rozmowy","description":"Generuje lub zwraca zapisany końcowy raport gotowości do sesji treningowej.","tags":["Interview Training"],"parameters":[{"$ref":"#/components/parameters/InterviewTrainingSessionId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Podsumowanie treningu","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"$ref":"#/components/schemas/InterviewTrainingSummary"},"cached":{"type":"boolean"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/webhooks":{"get":{"summary":"Lista webhooków","tags":["Webhooks"],"responses":{"200":{"description":"Rejestracje webhooków","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"summary":"Utwórz webhook","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri","description":"Publiczny adres URL webhooka HTTPS. Cele localhost oraz prywatne, link-local i zarezerwowane adresy IP są odrzucane."},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"secret":{"type":"string"}}}}}},"responses":{"200":{"description":"Webhook utworzony","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Webhook"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/webhooks/{id}":{"put":{"summary":"Zaktualizuj webhook","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Publiczny adres URL webhooka HTTPS. Cele localhost oraz prywatne, link-local i zarezerwowane adresy IP są odrzucane."},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Webhook zaktualizowany","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["application.created","application.started","application.completed","application.decided","application.stage_changed","screening.submitted","screening.evaluated","interview.started","interview.completed","code.submitted","code.evaluated","balance.low","balance.depleted","test.ping"]}},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"summary":"Usuń webhook","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"}],"responses":{"200":{"description":"Webhook usunięty","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/webhooks/{id}/deliveries":{"get":{"summary":"Lista dostaw webhooków","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"Dziennik dostarczania webhooków","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"meta":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/webhooks/test":{"post":{"summary":"Wyślij testowy webhook","tags":["Webhooks"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["webhookId"],"properties":{"webhookId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Wynik testowego dostarczenia","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"statusCode":{"type":"integer"},"response":{"type":"string","nullable":true},"deliveredAt":{"type":"string","format":"date-time","nullable":true}}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/ValidationError"}}}}},"tags":[{"name":"Health","description":"Stan operacyjny i gotowość zależności","x-displayName":"Stan API"},{"name":"Projects","description":"Projekty rekrutacyjne i potoki wygenerowane przez AI","x-displayName":"Rekrutacje"},{"name":"Candidates","description":"Zaproszenia i profile kandydatów","x-displayName":"Kandydaci"},{"name":"Applications","description":"Status aplikacji, nagrania i oceny","x-displayName":"Aplikacje"},{"name":"Usage","description":"Użycie, rozliczenia i informacje o saldzie","x-displayName":"Użycie"},{"name":"Interview Training","description":"Rozmowy treningowe oparte na ogłoszeniach dla osadzonych przepływów partnera","x-displayName":"Trening rozmowy"},{"name":"Webhooks","description":"Rejestracja webhooków i śledzenie dostaw","x-displayName":"Webhooki"}]}