{"openapi":"3.1.0","info":{"title":"Resumera","version":"0.1.0"},"paths":{"/api/v1/accounts":{"post":{"tags":["accounts"],"summary":"Create HH account","operationId":"create_account_api_v1_accounts_post","parameters":[{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HhAccountCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HhAccountRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["accounts"],"summary":"List HH accounts","operationId":"list_accounts_api_v1_accounts_get","parameters":[{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HhAccountRead"},"title":"Response List Accounts Api V1 Accounts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/accounts/{account_id}":{"get":{"tags":["accounts"],"summary":"Get HH account by id","operationId":"get_account_api_v1_accounts__account_id__get","parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HhAccountRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["accounts"],"summary":"Update HH account","operationId":"update_account_api_v1_accounts__account_id__patch","parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}},{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HhAccountUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HhAccountRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workers":{"post":{"tags":["workers"],"summary":"Register worker (returns API key once)","operationId":"create_worker_api_v1_workers_post","parameters":[{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["workers"],"summary":"List workers","operationId":"list_workers_api_v1_workers_get","parameters":[{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WorkerRead"},"title":"Response List Workers Api V1 Workers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/workers/{worker_id}":{"patch":{"tags":["workers"],"summary":"Update worker","operationId":"update_worker_api_v1_workers__worker_id__patch","parameters":[{"name":"worker_id","in":"path","required":true,"schema":{"type":"string","title":"Worker Id"}},{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkerRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/negotiations":{"post":{"tags":["webhooks"],"summary":"Ingest one negotiation event from a worker","description":"Called by an edge worker (same server or remote VPS) when a new HH negotiation is discovered. Auth: `X-Worker-Key`.","operationId":"post_negotiation_api_v1_webhooks_negotiations_post","parameters":[{"name":"X-Worker-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Worker-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NegotiationWebhookIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NegotiationWebhookResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/negotiations/batch":{"post":{"tags":["webhooks"],"summary":"Ingest a batch of negotiation events (retro-sync)","operationId":"post_negotiation_batch_api_v1_webhooks_negotiations_batch_post","parameters":[{"name":"X-Worker-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Worker-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NegotiationWebhookBatchIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NegotiationWebhookBatchResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/webhooks/resumes":{"post":{"tags":["webhooks"],"summary":"Ingest mirrored HH resume JSON (debug / prod duplicate)","description":"Accepts the raw body of HH `GET /resumes/{id}` without calling HH. Parses contacts into `candidates` and stores the full JSON in `candidates.extra.hh_resume_raw`. Auth: `X-Worker-Key`.","operationId":"post_resume_api_v1_webhooks_resumes_post","parameters":[{"name":"X-Worker-Key","in":"header","required":true,"schema":{"type":"string","title":"X-Worker-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeWebhookIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeWebhookResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/stats":{"get":{"tags":["admin"],"summary":"Admin Stats","operationId":"admin_stats_api_v1_admin_stats_get","parameters":[{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/negotiations":{"get":{"tags":["admin"],"summary":"List Negotiations","operationId":"list_negotiations_api_v1_admin_negotiations_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search topic/resume/vacancy id","title":"Q"},"description":"Search topic/resume/vacancy id"},{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNegotiationsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/candidates":{"get":{"tags":["admin"],"summary":"List Candidates","operationId":"list_candidates_api_v1_admin_candidates_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search name/phone/email/resume id","title":"Q"},"description":"Search name/phone/email/resume id"},{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCandidatesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/candidates/{candidate_id}":{"get":{"tags":["admin"],"summary":"Get Candidate","operationId":"get_candidate_api_v1_admin_candidates__candidate_id__get","parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}},{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCandidateRow"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/export/sheets":{"post":{"tags":["admin"],"summary":"Export To Sheets","description":"Export all candidates into the configured Google Spreadsheet.","operationId":"export_to_sheets_api_v1_admin_export_sheets_post","parameters":[{"name":"X-Admin-Token","in":"header","required":true,"schema":{"type":"string","title":"X-Admin-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SheetsExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["system"],"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}}},"components":{"schemas":{"AccountStatus":{"type":"string","enum":["active","disabled","error"],"title":"AccountStatus","description":"Lifecycle of an HH employer account in our system."},"AdminCandidateRow":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"account_id":{"type":"string","format":"uuid","title":"Account Id"},"hh_resume_id":{"type":"string","title":"Hh Resume Id"},"hh_topic_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hh Topic Id"},"hh_vacancy_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hh Vacancy Id"},"vacancy_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vacancy Name"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"phone_original":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Original"},"phone_normalized":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Normalized"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age"},"salary_from":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary From"},"salary_to":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary To"},"salary_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Salary Currency"},"disposition":{"type":"string","title":"Disposition"},"source":{"type":"string","title":"Source"},"has_raw_resume":{"type":"boolean","title":"Has Raw Resume","default":false},"pdf_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pdf Url"},"response_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Response Date"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"extra":{"additionalProperties":true,"type":"object","title":"Extra"}},"type":"object","required":["id","account_id","hh_resume_id","hh_topic_id","first_name","last_name","phone_original","phone_normalized","email","title","city","age","salary_from","salary_to","salary_currency","disposition","source","response_date","created_at","updated_at"],"title":"AdminCandidateRow"},"AdminCandidatesResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AdminCandidateRow"},"type":"array","title":"Items"},"meta":{"$ref":"#/components/schemas/AdminListMeta"}},"type":"object","required":["items","meta"],"title":"AdminCandidatesResponse"},"AdminListMeta":{"properties":{"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["total","limit","offset"],"title":"AdminListMeta"},"AdminNegotiationRow":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"account_id":{"type":"string","format":"uuid","title":"Account Id"},"hh_topic_id":{"type":"string","title":"Hh Topic Id"},"hh_resume_id":{"type":"string","title":"Hh Resume Id"},"hh_vacancy_id":{"type":"integer","title":"Hh Vacancy Id"},"vacancy_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vacancy Name"},"action_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Type"},"status":{"type":"string","title":"Status"},"response_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Response Date"},"received_at":{"type":"string","format":"date-time","title":"Received At"},"processed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processed At"},"payload":{"additionalProperties":true,"type":"object","title":"Payload"}},"type":"object","required":["id","account_id","hh_topic_id","hh_resume_id","hh_vacancy_id","action_type","status","response_date","received_at","processed_at"],"title":"AdminNegotiationRow"},"AdminNegotiationsResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AdminNegotiationRow"},"type":"array","title":"Items"},"meta":{"$ref":"#/components/schemas/AdminListMeta"}},"type":"object","required":["items","meta"],"title":"AdminNegotiationsResponse"},"AdminStatsResponse":{"properties":{"negotiations_total":{"type":"integer","title":"Negotiations Total"},"candidates_total":{"type":"integer","title":"Candidates Total"},"candidates_with_raw_resume":{"type":"integer","title":"Candidates With Raw Resume"}},"type":"object","required":["negotiations_total","candidates_total","candidates_with_raw_resume"],"title":"AdminStatsResponse"},"CandidateBriefRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"hh_resume_id":{"type":"string","title":"Hh Resume Id"},"hh_topic_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hh Topic Id"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"phone_original":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Original"},"phone_normalized":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone Normalized"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age"},"salary_from":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary From"},"salary_to":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary To"},"salary_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Salary Currency"},"disposition":{"type":"string","title":"Disposition"},"source":{"type":"string","title":"Source"}},"type":"object","required":["id","hh_resume_id","hh_topic_id","first_name","last_name","phone_original","phone_normalized","email","title","city","age","salary_from","salary_to","salary_currency","disposition","source"],"title":"CandidateBriefRead"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status","examples":["ok"]},"app":{"type":"string","title":"App"},"env":{"type":"string","title":"Env"}},"type":"object","required":["status","app","env"],"title":"HealthResponse"},"HhAccountCreate":{"properties":{"code":{"type":"string","maxLength":64,"minLength":2,"title":"Code","description":"Stable internal code used in configs and worker env, e.g. `account_a`.","examples":["account_a"]},"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","description":"Human-readable name, e.g. company / cabinet label.","examples":["HH Cabinet A"]},"hh_employer_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Hh Employer Id","description":"Optional employer id from HH API `/me` (can be filled after OAuth)."},"worker_base_url":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Worker Base Url","description":"Optional base URL of the edge worker serving this account.","examples":["https://worker-a.example.com"]},"settings":{"additionalProperties":true,"type":"object","title":"Settings","description":"Free-form account settings (filters, sheet mapping overrides, etc.)."},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Internal notes."},"status":{"$ref":"#/components/schemas/AccountStatus","description":"Account lifecycle status.","default":"active"}},"type":"object","required":["code","name"],"title":"HhAccountCreate","description":"Create a logical HH employer account in the central DB."},"HhAccountRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"code":{"type":"string","title":"Code"},"name":{"type":"string","title":"Name"},"hh_employer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hh Employer Id"},"status":{"$ref":"#/components/schemas/AccountStatus"},"worker_base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Worker Base Url"},"settings":{"additionalProperties":true,"type":"object","title":"Settings"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","code","name","hh_employer_id","status","worker_base_url","settings","notes","created_at","updated_at"],"title":"HhAccountRead","description":"Public representation of an HH account."},"HhAccountUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"hh_employer_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Hh Employer Id"},"worker_base_url":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Worker Base Url"},"settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Settings"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"status":{"anyOf":[{"$ref":"#/components/schemas/AccountStatus"},{"type":"null"}]}},"type":"object","title":"HhAccountUpdate","description":"Partial update for an HH account."},"NegotiationCandidateSnapshot":{"properties":{"first_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Last Name"},"phone":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Phone","description":"Phone as received from HH (any format)."},"email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Email"},"title":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Title"},"city":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"City"},"age":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":14.0},{"type":"null"}],"title":"Age"},"salary_from":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Salary From"},"salary_to":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Salary To"},"salary_currency":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Salary Currency"}},"type":"object","title":"NegotiationCandidateSnapshot","description":"Optional pre-parsed candidate fields from the worker.\n\nIf omitted, the central API (or a later job) may fetch/parse the resume itself.\nFor stage-1 foundation we accept either raw-only or enriched payloads."},"NegotiationEventRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"account_id":{"type":"string","format":"uuid","title":"Account Id"},"worker_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Worker Id"},"vacancy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Vacancy Id"},"hh_topic_id":{"type":"string","title":"Hh Topic Id"},"hh_resume_id":{"type":"string","title":"Hh Resume Id"},"hh_vacancy_id":{"type":"integer","title":"Hh Vacancy Id"},"action_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Type"},"response_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Response Date"},"status":{"$ref":"#/components/schemas/NegotiationEventStatus"},"attempts":{"type":"integer","title":"Attempts"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"payload":{"additionalProperties":true,"type":"object","title":"Payload"},"received_at":{"type":"string","format":"date-time","title":"Received At"},"processed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processed At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","account_id","worker_id","vacancy_id","hh_topic_id","hh_resume_id","hh_vacancy_id","action_type","response_date","status","attempts","last_error","payload","received_at","processed_at","created_at","updated_at"],"title":"NegotiationEventRead"},"NegotiationEventStatus":{"type":"string","enum":["received","processing","processed","duplicate","failed","skipped"],"title":"NegotiationEventStatus","description":"Processing pipeline status for an inbound negotiation event from a worker."},"NegotiationWebhookBatchIn":{"properties":{"items":{"items":{"$ref":"#/components/schemas/NegotiationWebhookIn"},"type":"array","maxItems":200,"minItems":1,"title":"Items","description":"Up to 200 negotiation events per request."}},"type":"object","required":["items"],"title":"NegotiationWebhookBatchIn","description":"Batch ingest for retro-sync workers (same auth as single webhook)."},"NegotiationWebhookBatchResult":{"properties":{"results":{"items":{"$ref":"#/components/schemas/NegotiationWebhookResult"},"type":"array","title":"Results"},"created":{"type":"integer","title":"Created"},"duplicates":{"type":"integer","title":"Duplicates"},"rejected":{"type":"integer","title":"Rejected"}},"type":"object","required":["results","created","duplicates","rejected"],"title":"NegotiationWebhookBatchResult"},"NegotiationWebhookIn":{"properties":{"hh_topic_id":{"type":"string","maxLength":128,"minLength":1,"title":"Hh Topic Id","description":"HH negotiation/topic id. For retro-sync without topic use synthetic id.","examples":["123456789","retro_sync_a54eaacb000e0d77"]},"hh_resume_id":{"type":"string","maxLength":128,"minLength":1,"title":"Hh Resume Id","description":"HH resume id linked to the negotiation."},"hh_vacancy_id":{"type":"integer","minimum":1.0,"title":"Hh Vacancy Id","description":"HH vacancy id."},"vacancy_name":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Vacancy Name","description":"Optional vacancy title; used to upsert local vacancy row."},"action_type":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Action Type","description":"HH action, e.g. NEW_NEGOTIATION_VACANCY.","examples":["NEW_NEGOTIATION_VACANCY"]},"response_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Response Date","description":"When the applicant responded (ISO 8601, timezone-aware preferred)."},"account_code":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Account Code","description":"Optional account code; if set must match the authenticated worker's account."},"candidate":{"anyOf":[{"$ref":"#/components/schemas/NegotiationCandidateSnapshot"},{"type":"null"}],"description":"Optional parsed candidate snapshot from the worker."},"raw":{"additionalProperties":true,"type":"object","title":"Raw","description":"Original HH payload fragment for audit/reprocessing."}},"type":"object","required":["hh_topic_id","hh_resume_id","hh_vacancy_id"],"title":"NegotiationWebhookIn","description":"Body of `POST /api/v1/webhooks/negotiations`.\n\nAuth: header `X-Worker-Key` (worker API key). The worker is bound to one\n`account_id`; the event is stored under that account. Optional `account_code`\nmay be sent for extra safety checks (must match worker's account)."},"NegotiationWebhookResult":{"properties":{"status":{"type":"string","title":"Status","description":"`created` | `duplicate` | `rejected`","examples":["created"]},"event":{"anyOf":[{"$ref":"#/components/schemas/NegotiationEventRead"},{"type":"null"}]},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["status"],"title":"NegotiationWebhookResult","description":"Per-item result for single or batch webhook handling."},"ResumeWebhookIn":{"properties":{"hh_resume_id":{"type":"string","maxLength":128,"minLength":1,"title":"Hh Resume Id"},"hh_vacancy_id":{"type":"integer","minimum":1.0,"title":"Hh Vacancy Id"},"hh_topic_id":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Hh Topic Id","description":"Negotiation/topic id when known; used to link to negotiation_events."},"vacancy_name":{"anyOf":[{"type":"string","maxLength":512},{"type":"null"}],"title":"Vacancy Name","description":"Optional vacancy title (шапка). Not required by TZ."},"fetched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Fetched At","description":"When the producer fetched the resume from HH."},"account_code":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Account Code"},"resume":{"additionalProperties":true,"type":"object","title":"Resume","description":"Raw HH resume JSON (same shape as GET /resumes/{id})."}},"type":"object","required":["hh_resume_id","hh_vacancy_id","resume"],"title":"ResumeWebhookIn","description":"Body of `POST /api/v1/webhooks/resumes`.\n\nDebug / mirror path: accept the raw HH GET /resumes/{id} JSON without\ncalling HH from this server. Auth: `X-Worker-Key`."},"ResumeWebhookResult":{"properties":{"status":{"type":"string","title":"Status","description":"`created` | `updated` | `rejected`","examples":["created"]},"candidate":{"anyOf":[{"$ref":"#/components/schemas/CandidateBriefRead"},{"type":"null"}]},"negotiation_event_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Negotiation Event Id"},"vacancy_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Vacancy Id"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["status"],"title":"ResumeWebhookResult"},"SheetsExportResponse":{"properties":{"spreadsheet_id":{"type":"string","title":"Spreadsheet Id"},"spreadsheet_url":{"type":"string","title":"Spreadsheet Url"},"sheet_title":{"type":"string","title":"Sheet Title"},"exported_rows":{"type":"integer","title":"Exported Rows"},"skipped_duplicates":{"type":"integer","title":"Skipped Duplicates","default":0},"candidates_with_resume":{"type":"integer","title":"Candidates With Resume","default":0},"exported_at":{"type":"string","format":"date-time","title":"Exported At"}},"type":"object","required":["spreadsheet_id","spreadsheet_url","sheet_title","exported_rows","exported_at"],"title":"SheetsExportResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WorkerCreate":{"properties":{"account_id":{"type":"string","format":"uuid","title":"Account Id","description":"UUID of the HhAccount this worker serves."},"name":{"type":"string","maxLength":255,"minLength":1,"title":"Name","description":"Worker label, e.g. `worker-account-a`."},"host_hint":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Host Hint","description":"Optional hostname or public IP of the worker host.","examples":["188.225.10.111"]},"meta":{"additionalProperties":true,"type":"object","title":"Meta","description":"Optional metadata (region, deploy version, etc.)."},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"api_key":{"anyOf":[{"type":"string","maxLength":128,"minLength":16},{"type":"null"}],"title":"Api Key","description":"Optional predetermined plaintext key (e.g. shared with Laravel mirror). If omitted, a random `whk_…` key is generated.","examples":["whk_G9yDpGbBlsItBs0FfZSI2qk_o0X0w5GzUYS28b5A1l0"]}},"type":"object","required":["account_id","name"],"title":"WorkerCreate","description":"Register a worker that will push negotiation webhooks to the central API.\n\nThe worker may run on the same machine as the API or on a dedicated VPS\n(1 HH account = 1 worker IP/domain, per customer architecture)."},"WorkerCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"account_id":{"type":"string","format":"uuid","title":"Account Id"},"name":{"type":"string","title":"Name"},"api_key_prefix":{"type":"string","title":"Api Key Prefix","description":"Non-secret prefix of the API key for identification."},"status":{"$ref":"#/components/schemas/WorkerStatus"},"host_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host Hint"},"last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen At"},"meta":{"additionalProperties":true,"type":"object","title":"Meta"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"api_key":{"type":"string","title":"Api Key","description":"Plaintext worker API key. Shown once. Send as `X-Worker-Key` header."}},"type":"object","required":["id","account_id","name","api_key_prefix","status","host_hint","last_seen_at","meta","notes","created_at","updated_at","api_key"],"title":"WorkerCreated","description":"Returned only once at registration.\n\nStore `api_key` in the worker's environment (`WORKER_API_KEY`).\nIt cannot be recovered later — only rotated."},"WorkerRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"account_id":{"type":"string","format":"uuid","title":"Account Id"},"name":{"type":"string","title":"Name"},"api_key_prefix":{"type":"string","title":"Api Key Prefix","description":"Non-secret prefix of the API key for identification."},"status":{"$ref":"#/components/schemas/WorkerStatus"},"host_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host Hint"},"last_seen_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen At"},"meta":{"additionalProperties":true,"type":"object","title":"Meta"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","account_id","name","api_key_prefix","status","host_hint","last_seen_at","meta","notes","created_at","updated_at"],"title":"WorkerRead","description":"Worker without the secret API key."},"WorkerStatus":{"type":"string","enum":["active","disabled"],"title":"WorkerStatus"},"WorkerUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255,"minLength":1},{"type":"null"}],"title":"Name"},"host_hint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Host Hint"},"status":{"anyOf":[{"$ref":"#/components/schemas/WorkerStatus"},{"type":"null"}]},"meta":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Meta"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"WorkerUpdate"}}}}