API contract v1¶
Este contrato descreve a FastAPI local em /api/v1 consumida pelo frontend moderno em apps/web.
Base local padrao:
http://127.0.0.1:8787/api/v1
OpenAPI:
http://127.0.0.1:8787/openapi.json
http://127.0.0.1:8787/docs
Convencoes¶
- Formato: JSON.
- Envelope de sucesso:
{
"ok": true,
"data": {},
"warnings": [],
"request_id": ""
}
- Envelope de erro:
{
"ok": false,
"error": {
"code": "invalid_payload",
"message": "Payload invalido para o contrato da API.",
"details": {}
},
"request_id": ""
}
- CORS e restrito por default. Configure origens com
SOTUHIRE_API_ALLOWED_ORIGINS. - A API e local-first. Nao coloque Gemini key, GitHub token ou secrets no frontend.
- Curriculo bruto entra somente no request necessario; respostas de extracao removem
raw_textpor default. - Regras de Análise de Compatibilidade, ATS, Resume Tailor, GitHub Analyzer e Application Intelligence ficam no backend.
GET /api/v1/health¶
Verifica se a API local esta ativa.
Response data:
{
"status": "ok",
"service": "sotuhire-api",
"version": "1.5.0",
"local_first": true,
"openapi_url": "/openapi.json",
"docs_url": "/docs",
"capabilities": [
"resume_extract",
"job_extract",
"match_analyze",
"ats_analyze",
"resume_tailor",
"github_repo_analyze",
"tracker_jobs",
"application_intelligence",
"ai_settings",
"extension_bridge"
]
}
GET /api/v1/settings/ai¶
Retorna a configuração segura de IA. Nunca retorna a chave.
Response data:
{
"provider": "gemini",
"model": "gemini-2.5-flash",
"configured": true,
"status": "configured",
"use_ai": true,
"allow_match": true,
"allow_ats": true,
"allow_tailor": true,
"allow_github": true,
"allow_memory_context": false,
"updated_at": "2026-06-22T23:00:00+00:00",
"warnings": []
}
GET /api/v1/settings/ai/status¶
Mesmo payload seguro de GET /settings/ai, usado para atualização de status.
POST /api/v1/settings/ai¶
Salva provider, modelo, toggles e, opcionalmente, uma chave no backend local.
Request:
{
"provider": "gemini",
"model": "gemini-2.5-flash",
"api_key": "NAO_USE_CHAVE_REAL_EM_DOCS",
"use_ai": true,
"allow_match": true,
"allow_ats": true,
"allow_tailor": true,
"allow_github": true,
"allow_memory_context": false
}
Response: mesmo payload seguro de GET /settings/ai, sem api_key.
POST /api/v1/settings/ai/test¶
Testa o provider selecionado.
local: retorna sucesso sem chamada externa.gemini: usa chave recém-enviada ou chave local já salva.openai: usa chave recém-enviada ou chave local já salva.openai_future: alias legado normalizado paraopenai.
Response data:
{
"provider": "gemini",
"model": "gemini-2.5-flash",
"success": true,
"configured": true,
"status": "configured",
"message": "Provider configurado com sucesso."
}
DELETE /api/v1/settings/ai¶
Remove a chave local do backend. Não remove o frontend nem retorna segredo.
POST /api/v1/resume/extract¶
Extrai ResumeProfileSchema a partir de texto colado.
Request:
{
"resume_text": "Texto ficticio do curriculo",
"source_type": "text",
"include_raw_text": false,
"request_id": "ui_001"
}
Response data:
{
"profile": {
"name": "Pessoa Ficticia",
"email": "pessoa@example.invalid",
"skills": ["Python", "FastAPI"],
"experiences": [],
"projects": [],
"raw_text": ""
},
"confidence": 0.85,
"provider_used": "local",
"requested_provider": "local",
"analysis_mode": "local",
"fallback_used": false,
"low_confidence_fields": []
}
POST /api/v1/job/extract¶
Extrai JobPostingSchema a partir de descricao de vaga.
Request:
{
"job_text": "Cargo: Backend Python\nRequisitos: Python, FastAPI, SQL",
"source_url": "https://example.invalid/jobs/backend",
"include_raw_text": false
}
Response data:
{
"job": {
"title": "Backend Python",
"company": "",
"modality": "unknown",
"required_skills": ["Python", "SQL", "FastAPI"],
"desired_skills": [],
"ats_keywords": ["backend", "python"],
"raw_text": ""
},
"confidence": 0.75,
"provider_used": "local",
"requested_provider": "local",
"analysis_mode": "local",
"fallback_used": false,
"low_confidence_fields": []
}
Warnings podem incluir dados ausentes como salario, empresa ou modalidade.
POST /api/v1/match/analyze¶
Calcula a Análise de Compatibilidade usando o fluxo local estruturado do backend/core.
Request minimo:
{
"resume_text": "Texto ficticio do curriculo",
"job_text": "Descricao ficticia da vaga",
"preferences": null,
"github_evidence": [],
"portfolio_evidence": []
}
Tambem aceita profile e job ja estruturados quando o frontend executou as extracoes antes.
Response data:
{
"provider_used": "local",
"requested_provider": "local",
"analysis_mode": "local",
"fallback_used": false,
"local_first": true,
"analysis": {
"match_score": 78,
"ats_score": 74,
"opportunity_fit_score": 70,
"risk_score": 20,
"recommendation": "apply_with_adjustments",
"analysis_version": "compatibility_backend",
"confidence_score": 0.66,
"evidence_score": 72,
"matched_requirements": [],
"partial_requirements": [],
"missing_requirements": [],
"critical_gaps": [],
"safe_actions": []
}
}
POST /api/v1/ats/analyze¶
Classifica keywords ATS usando evidências da análise de compatibilidade.
Request:
{
"resume_text": "Texto ficticio do curriculo",
"job_text": "Descricao ficticia da vaga",
"job_keywords": ["Python", "Docker"],
"match_analysis": null
}
Response data:
{
"ats_score": 74,
"present": ["Python"],
"missing_but_safe_to_add_if_true": ["Docker"],
"missing_without_evidence": []
}
POST /api/v1/resume/tailor¶
Gera sugestoes seguras de ajuste do curriculo sem inventar experiencia.
Request:
{
"target_role": "Backend Python",
"target_company": "Empresa Ficticia",
"job_text": "Descricao ficticia da vaga",
"evidence_text": "Evidencias fornecidas pela pessoa usuaria",
"match_analysis": null
}
Response data:
{
"safe_to_export": true,
"tailor": {
"target_role": "Backend Python",
"target_company": "Empresa Ficticia",
"section_order": ["Resumo", "Projetos", "Skills"],
"improved_bullets": [],
"keywords_added": ["Python"],
"evidence_used": [],
"warnings": []
}
}
POST /api/v1/github/repo/analyze¶
Analisa repositorio publico como evidencia tecnica.
Request:
{
"repo_url": "https://github.com/example/fictitious-api",
"mode": "full",
"target_role": "Backend Python",
"target_job": {},
"candidate_profile": {},
"career_domains": ["software"],
"language": "pt-BR",
"fallback_payload": null
}
Response data:
{
"report": {
"repository_identity": {
"owner": "example",
"name": "fictitious-api",
"url": "https://github.com/example/fictitious-api",
"project_type": "api"
},
"scores": {
"overall_score": 81,
"grade": "B"
},
"provider_used": "local",
"fallback_used": false
}
}
fallback_payload aceita sinais publicos capturados pela extensao quando a GitHub API falha.
GET /api/v1/tracker/jobs¶
Lista registros locais do tracker.
Response data:
{
"jobs": [
{
"id": "job_demo_001",
"job_title": "Backend Python",
"company": "Empresa Ficticia",
"status": "applied",
"requirements": ["Python", "Docker"],
"analysis": {
"match_score": 82,
"ats_score": 74
}
}
]
}
POST /api/v1/tracker/jobs¶
Cria ou atualiza um card do tracker local.
Request:
{
"title": "Backend Python",
"company": "Empresa Ficticia",
"source_url": "https://linkedin.com/jobs/123",
"requirements": ["Python", "Docker"],
"status": "applied",
"match_score": 82,
"ats_score": 74,
"privacy_acknowledged": true
}
Response data:
{
"job": {
"id": "generated_id",
"job_title": "Backend Python",
"status": "applied"
}
}
PATCH /api/v1/tracker/jobs/{id}¶
Atualiza status e/ou notas.
Request:
{
"status": "interview",
"notes": "Entrevista tecnica marcada."
}
GET /api/v1/tracker/metrics¶
Retorna KPIs do tracker.
Response data:
{
"total_saved": 18,
"total_applied": 9,
"by_status": {
"applied": 9,
"interview": 2,
"offer": 1
},
"average_match_by_status": {
"applied": 75
},
"response_rate": 0.33,
"interview_rate": 0.22,
"offer_rate": 0.05
}
GET /api/v1/tracker/requirements¶
Retorna rankings de requisitos e gaps para Application Intelligence.
Response data:
{
"top_requirements": [
{
"name": "Python",
"count": 12,
"status_scope": "all",
"sources": ["linkedin.com"],
"candidate_has_evidence": true
}
],
"missing_requirements": [],
"critical_gaps": [],
"requirements_by_source": [
{"source": "linkedin.com", "requirement": "Python", "count": 6}
]
}
GET /api/v1/tracker/funnel¶
Retorna funil salvo -> aplicado -> resposta -> entrevista -> oferta.
Response data:
{
"stages": [
{"status": "saved", "label": "Salvas", "count": 18},
{"status": "applied", "label": "Aplicadas", "count": 9},
{"status": "response", "label": "Com resposta", "count": 3},
{"status": "interview", "label": "Entrevistas", "count": 2},
{"status": "offer", "label": "Oferta", "count": 1}
],
"conversion_rates": [
{"from": "saved", "to": "applied", "rate": 0.5}
]
}
GET /api/v1/tracker/sources¶
Compara fontes/domains de vagas.
Response data:
{
"sources": [
{
"name": "linkedin.com",
"saved": 8,
"applied": 4,
"interviews": 1,
"average_match": 76,
"top_requirements": ["Python", "Docker"]
}
]
}
GET /api/v1/sources/authenticated-browser/status¶
Testa o Chromium dedicado via CDP local.
Query:
browser_cdp_url=http://127.0.0.1:9222
Response data:
{
"available": true,
"endpoint": "http://127.0.0.1:9222",
"browser": "Chrome/...",
"message": "Navegador autenticado conectado e pronto."
}
POST /api/v1/sources/authenticated-browser/launch¶
Abre ou reutiliza um Chromium dedicado para login manual.
Request:
{
"start_url": "https://www.linkedin.com/jobs/",
"browser_cdp_url": "http://127.0.0.1:9222"
}
POST /api/v1/sources/authenticated-browser/collect¶
Coleta uma fonte autenticada autorizada usando o conector existente. Requer confirmacao explicita.
Request:
{
"name": "LinkedIn autorizado",
"url": "https://www.linkedin.com/jobs/",
"browser_cdp_url": "http://127.0.0.1:9222",
"max_items": 20,
"max_pages": 3,
"authorized_use": true,
"authorization_reference": "uso pessoal autorizado"
}
Response data:
{
"new_count": 2,
"duplicate_count": 0,
"updated_count": 0,
"failures": [],
"opportunities": [
{
"title": "Backend Developer Python",
"company": "Empresa",
"source_url": "https://www.linkedin.com/jobs/...",
"confidence": 0.86
}
]
}
O endpoint nao automatiza login, nao contorna CAPTCHA/checkpoint e nao envia candidatura.
GET /api/v1/extension/status¶
Retorna status seguro da ponte FastAPI com a Local Companion API.
{
"available": true,
"companion_url": "http://127.0.0.1:8765",
"capture_count": 2,
"last_capture_at": "2026-06-23T12:00:00+00:00",
"message": "Local Companion conectado ao backend FastAPI."
}
GET /api/v1/extension/captures¶
Lista capturas locais recentes salvas pela extensao assistiva.
{
"captures": [
{
"id": "capture_demo",
"title": "Backend Python Demo",
"company": "Empresa Ficticia",
"url": "https://example.invalid/jobs/backend",
"domain": "example.invalid",
"status": "captured"
}
]
}
POST /api/v1/extension/import/job¶
Importa uma captura local para o formato de Vaga. Tambem existem:
POST /api/v1/extension/import/github
POST /api/v1/extension/import/tracker
Esses endpoints nao abrem navegador, nao fazem login e nao automatizam sites de terceiros.
Variaveis de ambiente¶
| Variavel | Default | Uso |
|---|---|---|
SOTUHIRE_API_HOST |
127.0.0.1 |
Host usado por scripts/run_api.py. |
SOTUHIRE_API_PORT |
8787 |
Porta local usada por scripts/run_api.py. |
SOTUHIRE_API_ALLOWED_ORIGINS |
origens locais + GitHub Pages | Lista CSV para CORS. |
GITHUB_TOKEN |
vazio | Token opcional usado pelo GitHub Analyzer core. |