Guia de Integração — Interviews API
Versão da API: 2.1.0 · Última atualização: Setembro de 2026
Audiência: desenvolvedores de empresas parceiras
Base URL de produção: https://apisophia-632e2671412f.herokuapp.com
Bem-vindo. Este guia é destinado a desenvolvedores de empresas parceiras que vão consumir a Interviews API para receber, em seus próprios sistemas (ATS, CRM de RH, painéis internos, BI), os dados de entrevistas e vagas de candidatos.
A API é somente leitura: você consulta dados, não envia. As entrevistas e vagas são criadas pelo nosso ecossistema de produtos e ficam disponíveis para consulta logo após o processamento.
Migrando da 2.0.0? Leia a seção O que mudou na 2.1.0 antes de qualquer coisa. A ordenação de entrevistas foi corrigida e o campo de data recomendado mudou.
Integração com assistentes de IA: o capítulo 15 — MCP explica como conectar a SophIA ao ChatGPT, Claude e clientes compatíveis, com consultas e ações autorizadas. Os capítulos anteriores continuam dedicados à Interviews API de leitura.
Sumário
- O que mudou na 2.1.0
- Antes de começar
- Autenticação
- Convenções gerais
- Rate limiting
- Endpoints
- Dicionário de dados
- Tratamento de erros
- Exemplos de código
- Boas práticas
- LGPD e proteção de dados
- Versionamento e changelog
- Suporte
- Glossário
- MCP — SophIA nos assistentes de IA
O que mudou na 2.1.0
Três pontos afetam diretamente quem já está integrado:
1. A ordenação de entrevistas foi corrigida.
Até a 2.0.0, /interviews e /interviews/latest ordenavam pelo campo interview.date, que é uma string no formato "M/D/YYYY, h:mm:ss AM/PM". A ordenação era textual, não cronológica — "9/9/2025" vinha antes de "9/3/2026", e "11:51 AM" vinha depois de "11:40 PM". O efeito prático era /interviews/latest devolvendo uma entrevista antiga como "última" e a paginação de /interviews fora de ordem. A partir da 2.1.0 a ordenação usa created_at (timestamp real). Se o seu polling do /latest parecia "travado" numa mesma entrevista, era isso.
2. Novo campo interview.created_at.
ISO 8601 com timezone (ex: "2026-09-03T21:14:21.959Z"). Use este campo para qualquer lógica de data: ordenação, sincronização incremental, exibição. É o campo pelo qual a API ordena.
3. interview.date está em UTC, não em horário de Brasília.
A documentação anterior afirmava que o campo estava em America/Sao_Paulo. Estava errado: o valor é o horário UTC formatado em en-US. Se você fazia parsing de interview.date como horário de Brasília, suas datas estão 3 horas adiantadas. Corrija usando interview.created_at. O campo date é mantido apenas para compatibilidade e pode ser removido numa futura major.
Nenhuma mudança é breaking no contrato: nada foi removido ou renomeado.
Antes de começar
O que você vai precisar
- Uma API key, fornecida pelo nosso time. O formato é
sk_seguido de 32 caracteres hexadecimais (ex:sk_a1b2c3d4e5f67890abcdef1234567890). Chaves fora desse formato são rejeitadas antes mesmo de consultar o banco. - A URL base da API:
https://apisophia-632e2671412f.herokuapp.com - Um cliente HTTP capaz de fazer requisições GET com header
Authorization. Qualquer linguagem moderna serve.
O que você vai receber
A API expõe três famílias de dados:
- Vagas (
/api/v1/jobs) — descrições das posições abertas no seu cadastro, com requisitos, responsabilidades e configurações de processo. - Entrevistas (
/api/v1/interviews) — relatórios consolidados de candidatos avaliados, incluindo dados de contato, endereço, score, pontos fortes/fracos e avaliação por IA. - Última entrevista (
/api/v1/interviews/latest) — atalho para obter rapidamente o último relatório recebido, útil para integração em tempo quase-real via polling leve.
Isolamento de dados
Sua API key está vinculada a um codigo_cliente exclusivo. Você só enxerga vagas e entrevistas associadas à sua empresa — em nenhuma circunstância dados de outros clientes serão retornados.
Identificadores: id da entrevista vs codigo da vaga
Uma confusão comum que vale esclarecer logo:
id(UUID, ex:"4802144f-d42c-479b-bc54-9f02c1417da1") identifica uma entrevista. É único, imutável e é a chave que você deve usar para correlacionar, deduplicar e reportar problemas.job.codigo(ex:"RHIN-1875") identifica uma vaga. Uma vaga tem várias entrevistas — vários candidatos, e às vezes o mesmo candidato mais de uma vez. Nunca usecodigocomo identificador de entrevista.
Autenticação
Todas as rotas sob /api/v1/* exigem autenticação. Envie sua API key no header Authorization, no esquema Bearer:
GET /api/v1/interviews HTTP/1.1
Host: apisophia-632e2671412f.herokuapp.com
Authorization: Bearer sk_a1b2c3d4e5f67890abcdef1234567890
Cuidados com a chave
- Nunca exponha a API key em código frontend (browser, app mobile, GitHub público). A chave concede acesso a todos os dados de candidatos da sua empresa.
- Armazene em variável de ambiente ou em um secret manager (AWS Secrets Manager, Vault, etc.).
- Em caso de suspeita de vazamento, entre em contato imediatamente para rotação. A chave anterior será invalidada na hora.
- Não compartilhe a mesma chave entre ambientes (dev/staging/prod) se possível — solicite chaves separadas.
O que pode dar errado
| Status | Causa |
|---|---|
401 Unauthorized |
Header Authorization ausente ou não começa com Bearer |
403 Forbidden |
Chave com formato inválido (não é sk_ + 32 hex), inexistente ou revogada |
Exemplo de erro 401:
{ "error": "Não autorizado: Token de autenticação não fornecido." }
Exemplo de erro 403:
{ "error": "Proibido: Chave de API inválida." }
Dica: um
403inesperado com a chave "certa" quase sempre é um caractere a mais copiado junto — espaço, quebra de linha, aspas. Confira o comprimento: são exatamente 35 caracteres (sk_+ 32).
Convenções gerais
Base URL
https://apisophia-632e2671412f.herokuapp.com
Todos os exemplos deste guia usam essa URL.
Formato
- Request: método GET, sem body. Parâmetros vão em query string.
- Response: sempre JSON (
Content-Type: application/json) em UTF-8. - Charset: UTF-8 em tudo (atenção a campos com acentos como
logradouro,cidade).
Datas e fuso horário
Cada entrevista traz dois campos temporais:
| Campo | Formato | Fuso | Uso recomendado |
|---|---|---|---|
interview.created_at |
ISO 8601, ex: "2026-09-03T21:14:21.959Z" |
UTC (com Z explícito) |
Use este. Ordenação, sync incremental, exibição (converta para o fuso do usuário). |
interview.date |
string en-US, ex: "9/3/2026, 9:14:21 PM" |
UTC (sem indicador) | Legado. Só exibição, se tanto. Não ordene por ele. |
Os dois representam o mesmo instante. created_at é simplesmente a versão parseável e sem ambiguidade.
Envelope de resposta
Todas as respostas bem-sucedidas seguem o padrão:
{ "data": ... }
ou, para endpoints paginados:
{ "data": [...], "pagination": { ... } }
Todas as respostas de erro seguem:
{ "error": "Mensagem descritiva em português." }
Rate limiting
A API aplica dois limites para proteger a estabilidade do serviço:
| Escopo | Limite padrão | Janela |
|---|---|---|
| Por IP de origem | 300 requisições | 15 minutos |
| Por API key autenticada | 120 requisições | 1 minuto |
Cada resposta inclui headers padrão de rate limit (RFC draft 7):
RateLimit-Limit: 120
RateLimit-Remaining: 118
RateLimit-Reset: 47
RateLimit-Reset indica em quantos segundos a janela atual zera.
Ao exceder o limite, você recebe:
HTTP/1.1 429 Too Many Requests
Retry-After: 47
{ "error": "Limite de requisições do cliente atingido." }
Recomendações
- Implemente backoff exponencial ao receber
429. Comece com 1s e dobre a cada tentativa, com teto de 60s. - Espace suas chamadas. Se você só consulta
/interviews/latestpara detectar novos relatórios, um polling a cada 30–60 segundos é mais que suficiente. Polling agressivo (a cada segundo) só consome seu rate limit sem ganho real. - Não tente acelerar paginação fazendo várias páginas em paralelo com a mesma chave — ainda vai bater no limite de 120/min, só que mais rápido.
Endpoints
GET / — Informações da API
Endpoint público (sem autenticação) que retorna informações básicas da API. Útil para verificar que a URL base está correta.
Request:
curl https://apisophia-632e2671412f.herokuapp.com/
Response 200:
{
"message": "Bem-vindo à API de Integração de Entrevistas!",
"status": "online",
"version": "2.1.0"
}
GET /health — Verificação de saúde
Endpoint público que verifica a conectividade com o banco de dados. Use em monitoramento de uptime (intervalo de 1 minuto é suficiente).
Request:
curl https://apisophia-632e2671412f.herokuapp.com/health
Response 200 (saudável):
{ "status": "ok", "database": "ok", "auth_mode": "service_role", "version": "2.1.0" }
Response 503 (degradado):
{ "status": "degraded", "database": "error", "auth_mode": "service_role" }
O campo auth_mode é informativo e destinado à nossa operação; você pode ignorá-lo.
GET /api/v1/interviews — Listar entrevistas
Retorna a lista paginada de relatórios de entrevista do seu cliente, ordenados da mais recente para a mais antiga por interview.created_at. A ordem é determinística (desempate por id), então a paginação é estável entre requisições.
Query parameters:
| Parâmetro | Tipo | Default | Restrições |
|---|---|---|---|
page |
inteiro | 1 | >= 1 |
limit |
inteiro | 20 | entre 1 e 100 |
Request:
curl -H "Authorization: Bearer sk_a1b2c3..." \
"https://apisophia-632e2671412f.herokuapp.com/api/v1/interviews?page=1&limit=20"
Response 200:
{
"data": [
{
"id": "8ecb88bf-d1e8-4f43-bf5f-9c4c62461183",
"candidate": {
"name": "Ramon Clemente",
"email": "[email protected]",
"phone": "31994301901",
"cpf": "06390483660",
"video_url": null,
"address": {
"cep": "38182670",
"logradouro": "Avenida Lorena Simeão Vale",
"numero": "70 C",
"complemento": null,
"bairro": "Loteamento Residencial Dona Adélia II",
"cidade": "Araxá",
"estado": "MG"
}
},
"job": {
"position": "Diretor de Operações",
"codigo": "STAR-DIROP"
},
"interview": {
"created_at": "2026-05-29T17:12:36.481Z",
"date": "5/29/2026, 5:12:36 PM",
"overall_score": null,
"core10_link": null
},
"results": {
"strengths": null,
"development_points": null,
"ai_summary": null
}
}
],
"pagination": {
"currentPage": 1,
"pageSize": 1,
"totalPages": 1,
"totalRecords": 1
}
}
Notas:
- O
idretornado é ointerview_uuid— use-o como chave única para correlacionar com seus próprios registros. - Campos
nullsão comuns em entrevistas ainda em processamento pela IA. Veja Status de processamento. pageSizeindica quantos itens efetivamente vieram nesta página (pode ser menor quelimitna última página).
Possíveis erros:
| Status | Quando ocorre |
|---|---|
400 |
page ou limit inválidos (não inteiros, fora do range permitido) |
401 / 403 |
Problema de autenticação |
429 |
Rate limit excedido |
500 |
Erro interno |
Exemplo de erro 400:
{ "error": "Parâmetro `limit` inválido. Deve ser inteiro entre 1 e 100." }
GET /api/v1/interviews/latest — Última entrevista
Atalho para obter apenas a entrevista mais recente por created_at (mesmo formato de objeto que cada item de /interviews).
Request:
curl -H "Authorization: Bearer sk_a1b2c3..." \
https://apisophia-632e2671412f.herokuapp.com/api/v1/interviews/latest
Response 200:
{
"data": {
"id": "8ecb88bf-d1e8-4f43-bf5f-9c4c62461183",
"candidate": { "...": "mesmo formato de /interviews" },
"job": { "position": "Diretor de Operações", "codigo": "STAR-DIROP" },
"interview": {
"created_at": "2026-05-29T17:12:36.481Z",
"date": "5/29/2026, 5:12:36 PM",
"overall_score": null,
"core10_link": null
},
"results": { "strengths": null, "development_points": null, "ai_summary": null }
}
}
Response 404 (nenhuma entrevista cadastrada):
{ "error": "Nenhuma entrevista encontrada." }
Quando usar este endpoint vs /interviews:
- Use
/interviews/latestse você só precisa detectar a entrada da entrevista mais recente (polling leve) e o volume de entrevistas é baixo o bastante para que duas nunca cheguem entre dois polls. - Use
/interviewsse você precisa de histórico, sincronização incremental ou processamento em lote. Se duas entrevistas puderem entrar dentro do seu intervalo de polling,/latestvai perder a primeira — nesse caso, use/interviews?limit=10e compare pelocreated_at. Veja Sincronização incremental.
GET /api/v1/jobs — Listar vagas
Retorna todas as vagas cadastradas pelo seu cliente, ordenadas por id decrescente (mais recente primeiro).
Não há paginação neste endpoint — o volume de vagas por cliente costuma ser pequeno (dezenas a poucas centenas).
Request:
curl -H "Authorization: Bearer sk_a1b2c3..." \
https://apisophia-632e2671412f.herokuapp.com/api/v1/jobs
Response 200:
{
"data": [
{
"id": 1705,
"title": "Área de Produção",
"company": "Tramontina Multi",
"work_model": "Presencial",
"status": "active",
"description": "Profissional responsável por atuar na produção industrial...",
"responsibilities": [
"Montar peças, componentes e jogos utilizando dispositivos, ferramentas manuais ou automáticas",
"Embalar as peças e acondicioná-las nas respectivas embalagens",
"Operar máquinas do processo produtivo"
],
"requirements": [
"No mínimo Ensino fundamental incompleto",
"Atenção aos detalhes"
],
"nice_to_have": [],
"codigo": "TRAM-PROD01",
"testecomportamental": true,
"anexar_curriculo_obrigatorio": false,
"divulgar": false,
"perguntavideo": null,
"video": false,
"log_cargos": "[email protected]"
}
]
}
Dicionário de dados
Status de processamento de uma entrevista
Uma entrevista passa por etapas. Os campos abaixo refletem o estágio:
| Estágio | interview.overall_score |
results.strengths, development_points, ai_summary |
interview.core10_link |
candidate.video_url |
|---|---|---|---|---|
| Em coleta | null |
null |
null |
null |
| Coletada, IA processando | null ou parcial |
null |
pode estar disponível | pode estar disponível |
| Concluída | preenchido | preenchido | preenchido | preenchido |
Trate null graciosamente em todos esses campos. Se você precisa esperar a IA terminar, faça polling pelo id da entrevista até overall_score deixar de ser null.
Campos de candidate
| Campo | Tipo | Formato | Exemplo | Observações |
|---|---|---|---|---|
name |
string | null | nome completo | "João Silva" |
— |
email |
string | null | RFC 5322 | "[email protected]" |
— |
phone |
string | null | dígitos + DDD, sem máscara | "11987654321" |
10 ou 11 dígitos. Aplique máscara no seu sistema se for exibir. |
cpf |
string | null | 11 dígitos, sem máscara | "12345678901" |
Dígitos verificadores incluídos. Dado sensível — veja LGPD. |
video_url |
string | null | URL HTTPS | "https://.../video.mp4" |
URL pública para o vídeo da entrevista. null se não gerado. |
Campos de candidate.address
Endereço residencial do candidato, capturado durante a entrevista.
| Campo | Tipo | Formato | Exemplo | Observações |
|---|---|---|---|---|
cep |
string | null | 8 dígitos, sem máscara | "01310100" |
Aplique máscara 00000-000 no seu sistema se for exibir. |
logradouro |
string | null | livre | "Avenida Paulista" |
Geralmente preenchido via lookup de CEP. |
numero |
string | null | livre | "1578" |
Tipo string, não número — aceita "S/N", "100 A", "70 C". |
complemento |
string | null | livre | "Apto 42", null |
Frequentemente null. |
bairro |
string | null | livre | "Bela Vista" |
— |
cidade |
string | null | livre | "São Paulo" |
— |
estado |
string | null | sigla UF de 2 letras | "SP" |
Maiúsculas. |
Campos de job (dentro da entrevista)
| Campo | Tipo | Exemplo | Observações |
|---|---|---|---|
position |
string | null | "Diretor de Operações" |
Título da vaga no momento da entrevista. |
codigo |
string | null | "STAR-DIROP" |
Código interno da vaga. Use este campo para juntar (JOIN) com o codigo de /api/v1/jobs. Não é identificador de entrevista — uma vaga tem N entrevistas. |
Campos de interview
| Campo | Tipo | Formato | Exemplo | Observações |
|---|---|---|---|---|
created_at |
string | ISO 8601 com timezone (UTC) | "2026-09-03T21:14:21.959Z" |
Campo de data recomendado. Instante em que a entrevista foi registrada. É o campo pelo qual a API ordena. |
date |
string | null | locale en-US, "M/D/YYYY, h:mm:ss AM/PM" |
"9/3/2026, 9:14:21 PM" |
Legado. Mesmo instante de created_at, formatado em UTC. Ver nota abaixo. |
overall_score |
número | null | decimal | 7.5, null |
Score consolidado de 0 a 10. null até a IA terminar. |
core10_link |
string | null | URL HTTPS | "https://.../core10/..." |
Link para o relatório detalhado do teste comportamental Core10. |
⚠ Sobre interview.date
Este campo é uma string sem indicador de fuso, gerada em UTC. Ele foi documentado até a 2.0.0 como horário de Brasília — isso estava errado. Se você fez parsing dele assumindo America/Sao_Paulo, suas datas estão 3 horas adiantadas.
A recomendação é não usar date e trabalhar com created_at:
JavaScript:
const when = new Date(interview.created_at); // instante correto, sem ambiguidade
// Exibir em horário de Brasília:
when.toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' });
Python:
from datetime import datetime
from zoneinfo import ZoneInfo
when = datetime.fromisoformat(interview["created_at"].replace("Z", "+00:00"))
when_brt = when.astimezone(ZoneInfo("America/Sao_Paulo"))
Se por algum motivo precisar parsear date, trate-o como UTC explicitamente:
import { parse } from 'date-fns';
import { fromZonedTime } from 'date-fns-tz';
const local = parse("9/3/2026, 9:14:21 PM", "M/d/yyyy, h:mm:ss a", new Date());
const utc = fromZonedTime(local, 'UTC');
Nunca ordene comparando as strings de date — "10/01/2026" vem antes de "5/29/2026" em ordenação textual. Confie na ordem que a API já entrega ou ordene por created_at.
Campos de results
| Campo | Tipo | Conteúdo | Observações |
|---|---|---|---|
strengths |
string | null | texto livre | Pontos fortes identificados pela IA. Pode conter quebras de linha e formatação leve. |
development_points |
string | null | texto livre | Pontos a desenvolver / áreas de atenção. |
ai_summary |
string | null | texto livre | Avaliação geral consolidada pela IA. |
⚠ Decisões automatizadas (LGPD Art. 20): os campos
overall_score,strengths,development_pointseai_summarysão gerados por IA. Sob a LGPD, o candidato tem direito a solicitar revisão por pessoa natural. Veja LGPD.
Campos de vagas (/api/v1/jobs)
| Campo | Tipo | Exemplo | Observações |
|---|---|---|---|
id |
inteiro | 1705 |
ID interno da vaga. Único por vaga. |
title |
string | "Diretor de Operações" |
Título exibível. |
company |
string | null | "Tramontina Multi" |
Pode ser diferente do nome do cliente em casos de holding. |
work_model |
string | null | "Presencial", "Remoto", "Híbrido" |
— |
status |
string | null | "active" |
Outros valores possíveis incluem variantes de inativo/encerrado conforme cadastro do cliente. |
description |
string | null | texto livre, pode conter \n |
Descrição da vaga. |
responsibilities |
array de strings | ["Responsabilidade 1", ...] |
Pode vir vazio ([]). |
requirements |
array de strings | ["Requisito 1", ...] |
Requisitos obrigatórios. |
nice_to_have |
array de strings | ["Diferencial 1", ...] |
Diferenciais. Frequentemente vazio. |
codigo |
string | null | "STAR-DIROP" |
Use para juntar com job.codigo das entrevistas. |
testecomportamental |
boolean | true |
Indica se a vaga aplica o teste Core10. |
anexar_curriculo_obrigatorio |
boolean | true |
Indica se o anexo de currículo é obrigatório no fluxo de aplicação. |
divulgar |
boolean | true |
Indica se a vaga deve ser divulgada publicamente. |
perguntavideo |
string | null | texto livre | Pergunta enviada em formato vídeo durante a entrevista (quando aplicável). |
video |
boolean | false |
Indica se a vaga inclui resposta em vídeo do candidato. |
log_cargos |
string | null | Email do recrutador responsável pela vaga. |
Tratamento de erros
Todos os erros retornam status HTTP apropriado e payload JSON { "error": "..." }.
| Status | Significado | Ação recomendada |
|---|---|---|
200 |
Sucesso | Processe data. |
400 |
Parâmetro inválido | Corrija o request. Mensagem indica qual parâmetro está errado. |
401 |
Autenticação ausente | Adicione o header Authorization: Bearer .... |
403 |
Chave inválida, malformada ou revogada | Verifique a chave (35 caracteres, sk_ + 32 hex). Se estiver correta, contate suporte. |
404 |
Recurso não encontrado | Em /interviews/latest: ainda não há entrevistas. Em outros: rota inexistente. |
413 |
Payload muito grande | Não deveria ocorrer em GETs. Verifique se não está enviando body. |
429 |
Rate limit excedido | Aplique backoff exponencial. Veja header Retry-After. |
500 |
Erro interno do servidor | Retentar com backoff. Se persistir, contate suporte. |
502 / 503 / 504 |
Indisponibilidade da plataforma de hospedagem, ou (em /health) banco indisponível |
Retentar com backoff. Indica problema temporário de infraestrutura. |
Estratégia de retry
Retente automaticamente apenas em 429, 500, 502, 503, 504. Nunca retente em 400, 401, 403, 404 — esses indicam problema no seu request que não vai se resolver com retry.
tentativa 1: imediata
tentativa 2: após 1s
tentativa 3: após 2s
tentativa 4: após 4s
tentativa 5: após 8s (desistir após esta)
Para 429, respeite o header Retry-After se presente.
Exemplos de código
cURL
# Listar primeira página de entrevistas
curl -H "Authorization: Bearer sk_a1b2c3d4e5f67890abcdef1234567890" \
"https://apisophia-632e2671412f.herokuapp.com/api/v1/interviews?page=1&limit=50"
# Obter última entrevista
curl -H "Authorization: Bearer sk_a1b2c3d4e5f67890abcdef1234567890" \
"https://apisophia-632e2671412f.herokuapp.com/api/v1/interviews/latest"
# Listar todas as vagas
curl -H "Authorization: Bearer sk_a1b2c3d4e5f67890abcdef1234567890" \
"https://apisophia-632e2671412f.herokuapp.com/api/v1/jobs"
Node.js (fetch nativo, Node 18+)
const API_BASE = 'https://apisophia-632e2671412f.herokuapp.com';
const API_KEY = process.env.INTERVIEWS_API_KEY;
async function fetchInterviews(page = 1, limit = 20) {
const res = await fetch(
`${API_BASE}/api/v1/interviews?page=${page}&limit=${limit}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(`HTTP ${res.status}: ${err.error || 'erro desconhecido'}`);
}
return res.json();
}
// Uso
const { data, pagination } = await fetchInterviews(1, 50);
console.log(`Página ${pagination.currentPage}/${pagination.totalPages}`);
data.forEach((interview) => {
const when = new Date(interview.interview.created_at);
console.log(
`${when.toISOString()} — ${interview.candidate.name} — ${interview.job.position}`
);
});
Node.js — sincronização completa com paginação
async function syncAllInterviews() {
const results = [];
let page = 1;
const limit = 100; // máximo permitido
while (true) {
const { data, pagination } = await fetchInterviews(page, limit);
results.push(...data);
if (page >= pagination.totalPages) break;
page++;
// Respeitar rate limit: 120/min = ~500ms entre requests
await new Promise((r) => setTimeout(r, 600));
}
return results;
}
Node.js — polling para detectar novas entrevistas (recomendado)
Esta versão usa /interviews?limit=10 em vez de /latest, e compara por created_at. Assim ela não perde entrevistas quando duas chegam entre dois polls.
let lastSeenCreatedAt = null; // persista isso no seu banco entre reinícios
async function pollNewInterviews() {
try {
const { data } = await fetchInterviews(1, 10);
// data já vem da mais recente para a mais antiga
const novas = lastSeenCreatedAt
? data.filter((i) => i.interview.created_at > lastSeenCreatedAt)
: data.slice(0, 1);
// processar da mais antiga para a mais recente
for (const interview of novas.reverse()) {
console.log('Nova entrevista:', interview.id, interview.job.codigo);
// ... processar
lastSeenCreatedAt = interview.interview.created_at;
}
} catch (err) {
console.error('Erro no polling:', err.message);
}
}
// Polling a cada 60 segundos
setInterval(pollNewInterviews, 60_000);
pollNewInterviews();
Comparar strings ISO 8601 em UTC com
>funciona porque o formato é lexicograficamente ordenável. Senovas.length === 10, chegaram mais de 10 desde o último poll — puxe a página 2 ou aumente olimit.
Node.js — polling simples com /latest
Adequado apenas quando o volume é baixo (uma entrevista a cada vários minutos, no máximo).
let lastSeenId = null;
async function pollLatest() {
try {
const res = await fetch(`${API_BASE}/api/v1/interviews/latest`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
if (res.status === 404) return; // nenhuma entrevista ainda
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { data } = await res.json();
if (data.id !== lastSeenId) {
lastSeenId = data.id;
console.log('Nova entrevista detectada:', data.id);
// ... processar
}
} catch (err) {
console.error('Erro no polling:', err.message);
}
}
setInterval(pollLatest, 60_000);
pollLatest();
Python (requests)
import os
import requests
API_BASE = "https://apisophia-632e2671412f.herokuapp.com"
API_KEY = os.environ["INTERVIEWS_API_KEY"]
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def fetch_interviews(page=1, limit=20):
r = requests.get(
f"{API_BASE}/api/v1/interviews",
params={"page": page, "limit": limit},
headers=HEADERS,
timeout=30,
)
r.raise_for_status()
return r.json()
def fetch_all_interviews():
results = []
page = 1
while True:
payload = fetch_interviews(page=page, limit=100)
results.extend(payload["data"])
if page >= payload["pagination"]["totalPages"]:
break
page += 1
return results
def fetch_latest():
r = requests.get(f"{API_BASE}/api/v1/interviews/latest", headers=HEADERS, timeout=30)
if r.status_code == 404:
return None
r.raise_for_status()
return r.json()["data"]
def fetch_jobs():
r = requests.get(f"{API_BASE}/api/v1/jobs", headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()["data"]
def fetch_new_since(last_seen_created_at, limit=10):
"""Entrevistas mais novas que last_seen_created_at (ISO 8601 UTC)."""
payload = fetch_interviews(page=1, limit=limit)
novas = [i for i in payload["data"] if i["interview"]["created_at"] > last_seen_created_at]
return list(reversed(novas)) # da mais antiga para a mais recente
Python — retry com backoff exponencial
import time
from requests.exceptions import HTTPError
RETRYABLE = {429, 500, 502, 503, 504}
def get_with_retry(url, max_attempts=5):
delay = 1
for attempt in range(1, max_attempts + 1):
try:
r = requests.get(url, headers=HEADERS, timeout=30)
if r.status_code in RETRYABLE:
retry_after = int(r.headers.get("Retry-After", delay))
time.sleep(retry_after)
delay = min(delay * 2, 60)
continue
r.raise_for_status()
return r.json()
except HTTPError:
if attempt == max_attempts:
raise
time.sleep(delay)
delay = min(delay * 2, 60)
raise RuntimeError("Esgotadas as tentativas de retry")
Boas práticas
Sincronização incremental vs completa
- Sincronização completa (puxar tudo de novo): use para a carga inicial e para reconciliação semanal/mensal de auditoria.
- Sincronização incremental (apenas o novo): use no dia-a-dia. Guarde o
created_atda entrevista mais recente que você processou e pare a paginação ao encontrar uma entrevista comcreated_atmenor ou igual.
async function syncIncremental(lastKnownCreatedAt) {
let page = 1;
const novas = [];
while (true) {
const { data, pagination } = await fetchInterviews(page, 100);
for (const item of data) {
if (item.interview.created_at <= lastKnownCreatedAt) return novas.reverse();
novas.push(item);
}
if (page >= pagination.totalPages) return novas.reverse();
page++;
await new Promise((r) => setTimeout(r, 600));
}
}
Comparar por created_at em vez de por id é mais robusto: funciona mesmo que a entrevista de referência seja apagada.
Cache de vagas
A lista de vagas (/api/v1/jobs) muda com baixa frequência. Cacheie por 5–15 minutos localmente para reduzir requisições.
Aguardando o processamento da IA
Uma entrevista recém-coletada pode aparecer com overall_score, strengths, development_points e ai_summary como null. O processamento pela IA leva alguns minutos. Estratégias:
- Polling pelo ID: depois de detectar uma entrevista nova, refaça a busca periodicamente até
overall_scoredeixar de sernull. (Hoje não há endpoint por ID; use/interviews?limit=Ne filtre peloid.) - Reprocessamento assíncrono no seu lado: marque a entrevista como "pendente" no seu sistema e reprocesse quando os campos preencherem.
Charset e encoding
Garanta que seu cliente HTTP e seu banco de destino estejam em UTF-8. Os campos cidade, logradouro, etc. contêm acentos e cedilhas. Configurações de locale latin1/iso-8859-1 vão corromper esses dados.
Logs e privacidade
Não logue payload completo de entrevistas em arquivos de log persistentes. Campos como CPF, email e telefone caem sob LGPD. Logue apenas o id da entrevista e métricas agregadas.
LGPD e proteção de dados
A API retorna dados pessoais e sensíveis de candidatos. Ao consumir esta API, você assume responsabilidades como operador (ou controlador, dependendo da relação contratual) sob a Lei Geral de Proteção de Dados (LGPD — Lei 13.709/2018).
Dados pessoais expostos
- Identificação: nome, e-mail, telefone, CPF.
- Localização: CEP, endereço completo.
- Avaliação: score, pontos fortes/fracos, resumo de IA.
- Multimídia: link para vídeo da entrevista.
Suas responsabilidades
- Base legal: garanta que existe base legal válida para tratar esses dados (geralmente consentimento ou execução de contrato).
- Finalidade: use os dados apenas para a finalidade prevista (avaliação de candidatos para processos seletivos).
- Minimização: não copie dados que você não vai usar.
- Retenção: defina prazo de retenção no seu sistema e expurgue dados após o término do processo seletivo (ou conforme política da sua empresa).
- Segurança: criptografe em repouso, restrinja acesso, mantenha logs de auditoria.
- Direitos do titular: implemente processo para atender solicitações dos candidatos (acesso, correção, exclusão, portabilidade).
- Revisão de decisões automatizadas (Art. 20): o score e a avaliação por IA são decisões automatizadas. O candidato tem direito a solicitar revisão por pessoa natural. Garanta esse processo no seu fluxo.
Recomendações técnicas
- Mascare CPF, email e telefone em interfaces que não exijam o dado completo.
- Acesso por papel: nem todo usuário do seu sistema precisa ver dados de candidato. Aplique RBAC.
- Audit log: registre quem acessou qual entrevista.
- DPA / contrato: formalize o tratamento de dados em contrato com o operador da API.
- Ao pedir suporte, nunca envie prints ou payloads com dados de candidato (por email, WhatsApp, tickets). Envie apenas o
idda entrevista — com ele localizamos tudo.
Versionamento e changelog
Política de versionamento
A API segue SemVer. O caminho da URL inclui a major version (/api/v1/).
- Patch (2.1.x) — correções de bug sem alteração de contrato. Não exige ação do cliente.
- Minor (2.x.0) — novos campos opcionais nas respostas, novos endpoints. Não quebra clientes existentes.
- Major (x.0.0) — mudanças incompatíveis. Quando ocorrer, será lançada como
/api/v2/e a v1 ficará disponível por período mínimo de transição de 6 meses, com aviso prévio.
Changelog
2.1.0 (atual) — Setembro/2026
Corrigido:
/interviewse/interviews/latestordenavam porinterview.date(string), produzindo ordem textual em vez de cronológica./latestpodia devolver uma entrevista antiga como "última" e a paginação vinha fora de ordem. Ambos passam a ordenar porcreated_at, com desempate determinístico porid.
Adicionado:
- Campo
interview.created_at(ISO 8601, UTC) em/interviewse/interviews/latest. /healthretornaversioneauth_mode.
Documentação:
interview.dateestava documentado como horário deAmerica/Sao_Paulo. É UTC. Corrigido, e o campo passa a ser considerado legado.- URL de produção incluída.
- Esclarecimento sobre
id(entrevista) vsjob.codigo(vaga). - Exemplos de polling e sync incremental reescritos sobre
created_at.
Segurança:
- Validação de formato da API key (
sk_+ 32 hex) antes de consultar o banco.
2.0.0 — Maio/2026
Adicionado:
- Em
/interviewse/interviews/latest: camposcandidate.phone,candidate.cpf,candidate.video_url, endereço completo (candidate.address.*),job.codigo,interview.core10_link. - Em
/jobs: camposnice_to_have,codigo,testecomportamental,anexar_curriculo_obrigatorio,divulgar,perguntavideo,video,log_cargos. - Endpoint
/healthreal (pinga o banco). - Headers de rate limit nas respostas (RFC draft 7).
Alterado (breaking):
/interviews/latestagora envelopa em{ "data": {...} }(antes: objeto cru)./jobsagora envelopa em{ "data": [...] }(antes: array cru)./interviews/latestretorna404quando não há entrevistas (antes:500)./interviewsretorna400quandopageoulimitsão inválidos (antes: comportamento indefinido).limitmáximo é agora 100 (antes: ilimitado).
Segurança:
- Rate limiting habilitado.
- Headers HTTP de segurança (helmet).
- CORS configurável por whitelist.
1.1.0
- Adicionada paginação em
/interviews. - Adicionado endpoint
/interviews/latest.
1.0.0
- Versão inicial.
Suporte
Canais
Reportar bug ou comportamento inesperado: envie email para o contato técnico da sua conta com:
- Endpoint chamado
- Timestamp aproximado (com timezone)
- Status HTTP recebido
idda entrevista envolvida (não envie o payload — ele contém dados pessoais)- Não inclua sua API key no email.
Rotação de API key: solicite via canal oficial. A rotação é imediata; a chave antiga deixa de funcionar.
Aumento de rate limit: rate limits podem ser ajustados sob demanda mediante justificativa.
Antes de abrir um chamado
Verifique:
- A URL base está correta? Faça
GET https://apisophia-632e2671412f.herokuapp.com/e confirme questatus: "online"é retornado. - O banco está saudável? Faça
GET /health. - A API key está válida? O retorno
403em todas as rotas confirma problema de credencial. Confira o comprimento (35 caracteres). - O
codigo_clienteestá correto? Listas vazias podem indicar que a chave pertence a um cliente sem dados, não a um bug. - A "última entrevista" parece errada? Confirme que está na 2.1.0 (
GET /mostraversion). Compareinterview.created_atdo que recebeu com o que esperava.
SLA e disponibilidade
A API depende do Supabase e da plataforma de hospedagem (Heroku). Em caso de incidente do provedor, podem ocorrer indisponibilidades. Acompanhe o status pelas páginas oficiais:
- Supabase: https://status.supabase.com
- Heroku: https://status.heroku.com
Glossário
| Termo | Definição |
|---|---|
| API key | Chave secreta no formato sk_<32 chars hex> usada para autenticar requisições. |
| codigo_cliente | Identificador único da sua empresa no nosso sistema. Sua chave está vinculada a um único codigo_cliente. |
| codigo (de vaga) | Identificador legível da vaga, no formato <PREFIXO>-<NUMERO> (ex: STAR-DIROP). Uma vaga tem várias entrevistas. |
| interview_uuid / id | Identificador único universal de uma entrevista. Use como chave de correlação. |
| created_at | Instante de registro da entrevista, ISO 8601 em UTC. Campo de referência para ordenação e sincronização. |
| Core10 | Sistema de avaliação comportamental aplicado durante a entrevista. O core10_link aponta para o relatório detalhado. |
| Polling | Técnica de consultar periodicamente um endpoint para detectar mudanças. |
| Rate limit | Limite de requisições permitidas em uma janela de tempo. |
MCP — SophIA nos assistentes de IA
Servidor: SophIA MCP 1.0.0 · Atualização deste módulo: 30 de setembro de 2026
Audiência: usuários da SophIA, administradores de integrações e desenvolvedores de clientes MCP.
O Model Context Protocol (MCP) conecta assistentes como ChatGPT e Claude às ferramentas da SophIA. Você pode consultar entrevistas, criar vagas, preparar relatórios e realizar operações do painel pela conversa, dentro dos acessos da sua empresa e do seu usuário.
Comece por aqui: solicite seu convite individual, abra o e-mail de ativação e leia os termos. Após concordar, copie a URL do MCP, o ID e o segredo exibidos na página. Siga o passo a passo do ChatGPT ou do Claude e escolha os acessos na autorização da SophIA. Não é necessário programar nem executar comandos no Heroku para receber e utilizar sua credencial.
Quando usar a API e quando usar o MCP
Os capítulos 01 a 14 continuam documentando a Interviews API. Este capítulo trata de uma conexão com endereço, autenticação e contratos próprios. Uma chave da API não autentica o MCP.
| Aspecto | Interviews API | SophIA MCP |
|---|---|---|
| Uso principal | Integrar sistemas, ATS, CRM e BI por requisições REST. | Operar ferramentas do painel em assistentes de IA e clientes MCP. |
| Ações | Consulta de entrevistas e vagas, somente leitura. | Consultas, criação, alterações, arquivos, envios e ações administrativas permitidas. |
| Autenticação | API key no cabeçalho Bearer. | OAuth com consentimento no navegador; o cliente recebe tokens temporários. |
| Identidade | Empresa vinculada à chave da API. | Empresa e usuário vinculados à credencial individual, com perfil e módulos atuais. |
| Contrato | Endpoints e envelopes JSON dos capítulos anteriores. | Ferramentas e schemas descobertos por tools/list; chamadas via tools/call. |
| Resultado | Resposta da consulta REST. | Ferramentas auxiliares diretas e operações de negócio acompanhadas por tarefa. |
O MCP utiliza os serviços de negócio incorporados ao seu próprio aplicativo e o banco configurado para a implantação. Quando MCP e painel apontam para o mesmo ambiente, uma alteração concluída na conversa aparece no painel. Ele não abre nem lê as telas do painel antes de executar: o assistente recebe dados e resultados das ferramentas. Alterar o código ou a interface do painel não atualiza automaticamente o servidor MCP; mudanças de regras precisam ser avaliadas também nessa implantação.
Antes de começar: endereço e requisitos
Use a URL do MCP exibida após o aceite no campo de URL do servidor/conector. Esse é o endereço oficial da implantação que emitiu sua credencial. Um exemplo de endereço no Heroku é:
https://sophiamcp-29749696c578.herokuapp.com/mcp
- Credencial individual ativada: ID e segredo revelados ao destinatário após o aceite dos termos, vinculados ao seu usuário e à sua empresa. Credenciais anteriores ainda válidas continuam utilizáveis.
- Cadastro válido: usuário ativo no painel e troca da senha temporária concluída, quando exigida.
- Cliente compatível: conta com acesso a conectores MCP remotos e autorização da organização, quando aplicável. Disponibilidade e nomes dos menus podem variar por conta e versão.
- Recursos da empresa: módulos como Currículo Match, PJ e Redes Sociais precisam estar habilitados. Serviços de e-mail, análise de currículos e LinkedIn dependem das respectivas integrações.
O caminho importa: cadastre a URL terminada em
/mcp. A raiz do aplicativo e/adminsão páginas administrativas; não são o endpoint da conexão. Use o ambiente informado pela equipe: um servidor ligado a uma base espelho retorna os dados desse espelho.
Domínio próprio: a URL pode usar o domínio Heroku ou um domínio personalizado configurado pela equipe com DNS e HTTPS válidos. Por exemplo, se a origem configurada for https://integracao.starmindai.ai, a conexão usará https://integracao.starmindai.ai/mcp. Esse domínio é um exemplo; use o endereço que aparecer no seu aceite.
Para a equipe técnica: a tela calcula a URL a partir de PUBLIC_BASE_URL, que deve conter somente a origem HTTPS, sem /mcp. Mantenha uma origem oficial por vez. Trocar essa origem altera a identidade OAuth do serviço e exige atualizar a URL e reconectar os clientes; não exige, por si só, gerar outro ID ou segredo.
Credenciais por usuário e isolamento da empresa
Cada integração vincula um ID, um segredo e um conjunto de acessos a um usuário do painel e um codigo_cliente. Pessoas da mesma empresa devem receber credenciais individuais para permitir atribuição e revogação do acesso de cada uma.
A equipe autorizada acessa /admin na origem oficial do aplicativo, escolhe a empresa, o usuário existente, as permissões e a validade e envia um convite. O e-mail de destino vem do cadastro do usuário na SophIA. O administrador não recebe nem visualiza o segredo. A credencial fica inativa até o destinatário aceitar os termos pelo link pessoal.
A área de gestão é restrita aos operadores internos com cadastro ERP ativo e super=true. Esse acesso é diferente do perfil administrador do painel do cliente. Receber uma credencial MCP não libera acesso à gestão de integrações.
| Dado | Para que serve | Onde usar |
|---|---|---|
| URL do MCP | Endereço oficial do servidor, terminado em /mcp. | Cadastro da SophIA como plugin/conector no assistente. Copie da tela após o aceite. |
| ID da integração | Identifica a credencial individual SophIA. | Formulário de autorização da SophIA, junto com o segredo. |
| Segredo da integração | Comprova o acesso àquela credencial. | Somente no formulário SophIA. Nunca em prompts, código público ou chamados. |
| OAuth Client ID | Identifica o cliente MCP, como ChatGPT ou Claude. | Registrado pelo próprio cliente no fluxo OAuth. Não é o ID da integração. |
| Token OAuth | Autoriza chamadas temporárias ao MCP. | Gerenciado pelo cliente, enviado no cabeçalho Bearer. |
Não preencha campos “OAuth Client ID” ou “OAuth Client Secret” com sua credencial SophIA. Esta implantação usa registro dinâmico de cliente público com PKCE. Os campos avançados opcionais de credenciais OAuth podem ficar vazios nesse fluxo.
A identidade é resolvida no servidor. Pedir na conversa “use outra empresa” ou enviar outro codigo_cliente não muda a empresa autenticada. As consultas e ações continuam sujeitas ao usuário, à visibilidade dos registros e aos módulos habilitados. Para uma segunda empresa, é necessária uma credencial autorizada daquela empresa.
Empresa e usuário não podem ser trocados na edição de uma credencial. Para outro destinatário ou empresa, emita uma nova. Se quiser revogar separadamente o acesso no ChatGPT e no Claude, emita credenciais distintas para o mesmo usuário, identificando cada aplicativo no nome da conexão.
Receber o e-mail, aceitar os termos e guardar a credencial
- Solicite o acesso à equipe responsável, informando o usuário e a empresa já cadastrados na SophIA.
- Localize o e-mail Ative seu acesso pessoal à SophIA MCP. Ele contém o link pessoal, o prazo, o contato de segurança e a indicação desta documentação em devsophia.starmindai.ai. O e-mail não contém o ID nem o segredo.
- Abra o link e confira destinatário, empresa, permissões, prazo do convite e eventual validade do acesso. Leia a versão dos termos apresentada.
- Se concordar, informe seu nome completo, marque a concordância e clique em Concordar e revelar minha credencial. Se não concordar, use Não aceito os termos; o convite será revogado e nenhum segredo será revelado.
- Após o aceite, a tela apresenta URL do MCP, ID da integração e Segredo da integração. Use Copiar URL, Copiar ID, Copiar segredo ou Copiar todos os dados.
- Guarde os dados em um gerenciador de senhas antes de sair. O segredo é exibido uma única vez e não pode ser consultado novamente. Depois de salvar, use Já guardei. Ocultar credencial e limpe a área de transferência.
- Use a URL para cadastrar o conector e informe o ID e o segredo somente na página oficial de autorização da SophIA aberta pelo assistente. Nunca cole o segredo na conversa.
Dois prazos diferentes: o convite vale duas horas por padrão, ajustáveis pela administração. É preciso concluir o aceite nesse prazo; abrir o link não o prorroga. A validade do acesso após a ativação, quando definida, é independente e pode reduzir o prazo disponível para aceitar. Sem aceite, não há acesso. Se perder o segredo após ativar, solicite a renovação à equipe.
Se o e-mail não chegar, confira o spam e peça à equipe para verificar a entrega. A indicação Enviado significa que o provedor aceitou o envio, não que a mensagem chegou à caixa de entrada. Um reenvio invalida o link anterior; use sempre o convite mais recente.
Gestão interna: filtros, edição, renovação e arquivamento
Esta seção é destinada à equipe interna autorizada. Entre em /admin com o e-mail e a senha do ERP; é necessário cadastro ativo e super=true. O perfil ADM de um cliente da SophIA não concede esse acesso.
Em Nova credencial, selecione empresa, usuário, nome da conexão, permissões e validade opcional. Clique em Criar e enviar convite. A emissão e a renovação usam o fluxo de e-mail e aceite; não é necessário gerar segredos pelo terminal.
Na lista, combine a busca por nome, e-mail, empresa ou ID com os filtros Empresa (código exato de quatro letras), Situação, Permissão e Arquivo. O padrão oculta as arquivadas; é possível mostrar somente as arquivadas ou incluí-las na lista. Limpar filtros restaura a consulta padrão.
| Ação | Quando usar | Efeito |
|---|---|---|
| Editar | Credencial ativa. | Altera nome, permissões e validade. Alterar apenas o nome preserva as conexões; mudanças nas permissões ou na validade exigem nova autorização OAuth. |
| Editar nome | Credencial pendente ou vencida. | Altera somente o nome, sem ativar o acesso, reenviar o convite, mudar permissões ou prorrogar prazos. |
| Reenviar convite | Convite pendente ou expirado, enquanto a validade final do acesso ainda permitir a ativação. | Invalida o link anterior e envia outro ao mesmo destinatário, com os termos e o prazo atuais. Não se aplica a credenciais já ativadas cuja validade terminou. |
| Novo segredo | Credencial ativa; por exemplo, quando o usuário perdeu o segredo. | Ao confirmar Renovar e enviar convite, o acesso anterior é revogado imediatamente. O ID permanece; outro segredo será gerado e revelado somente após um novo aceite. |
| Revogar | Encerrar o acesso. | Invalida a credencial, as conexões OAuth e os convites pendentes. Para conceder novo acesso, crie outra credencial. |
| Arquivar | Retirar uma credencial da lista padrão, preservando os registros. | Exige confirmar Arquivar e revogar. Encerra o acesso e os convites, preserva o histórico e deixa a credencial somente para consulta. Não permite editar, renovar, reenviar ou reativar a credencial arquivada. |
O histórico registra o operador responsável e a integração/empresa envolvida. Arquivar uma credencial não exclui o usuário, os dados de negócio ou os registros de aceite e não revoga as credenciais de outras pessoas.
Para a equipe técnica: envios dependem de SENDGRID_API_KEY e SENDGRID_FROM válidos. O recurso de arquivamento exige a migração 2026-10-01_mcp_credential_archive.sql; a listagem e os procedimentos anteriores continuam disponíveis antes dela. As estruturas de controle ficam no schema privado mcp_app, que não deve ser exposto pela API pública do Supabase.
Termos, versões e responsabilidade pelos dados compartilhados
Em Termos e entrega, a equipe interna pode editar razão social, CNPJ, contato de segurança, prazo do convite e texto dos termos. O prazo pode variar de 15 a 1.440 minutos, com padrão de 120 minutos. A configuração inicial identifica Starmind S/A, CNPJ 41.233.730/0001-10 e [email protected]; prevalecem os dados e condições apresentados no convite.
Salvar nova versão vale para os próximos convites. Não substitui o texto nem o prazo de convites já emitidos e não exige novo aceite de credenciais ativas. Para que um convite pendente utilize as condições atuais, reenvie-o. O aceite registra a versão e o conteúdo correspondente, o destinatário, o nome informado, a empresa, a data e dados técnicos de segurança. É um aceite eletrônico, sem certificado ICP-Brasil.
Conectar um assistente permite que ele receba as informações retornadas pelas ferramentas. Outros aplicativos, como e-mail, agenda ou armazenamento, podem receber dados quando o usuário solicita ou autoriza essas ações. Utilize somente serviços autorizados pela sua empresa, compartilhe o mínimo necessário e confira destinatários e políticas de privacidade, retenção e eventual treinamento de modelos.
Revogar a conexão não apaga automaticamente cópias já transmitidas a serviços externos. Leia a versão exibida no seu convite: este manual explica o funcionamento e não substitui os termos apresentados para aceite.
Permissões e consentimento
O aceite da credencial e a autorização do aplicativo são etapas distintas. Aceitar os termos ativa a credencial; o consentimento OAuth define quais acessos o ChatGPT, Claude ou outro cliente poderá utilizar. Uma etapa não substitui a outra.
O acesso efetivo combina permissões da credencial, escopos consentidos no token, perfil atual do usuário e módulos da empresa. Ser administrador no painel não concede automaticamente todos os escopos ao ChatGPT ou ao Claude.
| Escopo | Na tela SophIA | Finalidade |
|---|---|---|
sophia:read | Consultar dados | Base para consultar as ferramentas e os registros permitidos. |
sophia:write | Criar e alterar dados | Adicional à leitura para criar vagas, editar registros e preparar uploads. |
sophia:send | Enviar comunicações | Adicional à leitura e escrita para envios, convites e publicações externas. |
sophia:admin | Executar ações administrativas | Ações que exigem perfil ADM, além dos demais escopos necessários à ferramenta. |
Na página de autorização, a seção Acessos adicionais (opcional) permite selecionar os acessos ainda não pedidos pelo cliente. As caixas começam desmarcadas. Para criar uma vaga, autorize leitura e escrita; para publicar no LinkedIn, leitura, escrita e envio. Administração deve ser selecionada somente quando necessária e permitida.
Quando sua credencial já está lembrada no navegador, as opções refletem os acessos atuais. Antes da identificação, a página pode mostrar as categorias conhecidas; o servidor valida a seleção ao confirmar. Marcar uma opção não amplia o perfil nem habilita um módulo contratado separadamente.
Depois de selecionar, marque a confirmação geral e clique em Autorizar conexão. A nova conexão recebe os acessos aprovados. Tokens antigos não são ampliados por essa seleção; uma conexão que continua apenas com leitura precisa concluir um novo consentimento.
Acesso e execução são etapas diferentes. Autorizar escrita não cria uma vaga. Autorizar envio não publica no LinkedIn. O usuário ainda precisa solicitar a operação; envios e ações destrutivas exigem aprovação explícita do conteúdo, destinatário ou registro afetado.
Como conectar no ChatGPT
Tenha a credencial já ativada e a URL copiada da tela de aceite. Se ainda não recebeu o segredo, conclua primeiro o convite por e-mail.
- Abra Configurações → Segurança e login e habilite o Modo de desenvolvedor, quando disponível para sua conta. Em ambientes corporativos, confirme a liberação pelo administrador.
- Abra a área de Plugins, clique em + e cadastre o nome SophIA, uma descrição e a URL do MCP copiada após o aceite, terminada em
/mcp. - Utilize OAuth quando houver escolha de autenticação. A descoberta e o registro do cliente são feitos pelo fluxo da conexão. Deixe vazios os campos opcionais OAuth Client ID e OAuth Client Secret; eles não recebem o ID e o segredo da integração SophIA.
- Na página de autorização da SophIA, informe o ID e o segredo da integração, se solicitados. Confira a empresa e o usuário quando forem exibidos.
- Revise os acessos solicitados e selecione os adicionais necessários. Confirme em Autorizar conexão e aguarde o retorno ao ChatGPT.
- Revise as ferramentas disponibilizadas, abra uma conversa e selecione a SophIA no menu de ferramentas. Comece com a consulta de contexto sugerida em Primeiro uso.
Se a opção de conexão personalizada não aparecer, verifique as regras e os recursos da conta/workspace. Após uma atualização do catálogo, use Atualizar/Refresh na conexão e inicie uma conversa nova para carregar as ferramentas atuais.
Quando faltar um acesso permitido à sua credencial, o ChatGPT pode apresentar uma nova autorização. Confirme os escopos na página SophIA e depois retome a tarefa. O login lembrado pode dispensar redigitar o ID e o segredo, mas não substitui o consentimento.
Como conectar no Claude e no Claude Desktop
Conclua primeiro o aceite do convite e tenha em mãos a URL, o ID e o segredo da integração.
- No Claude, abra Personalizar/Customize → Conectores/Connectors.
- Clique em + → Adicionar conector personalizado/Add custom connector. Informe o nome SophIA e a URL copiada da tela de aceite, terminada em
/mcp. - Mantenha vazios os campos avançados opcionais OAuth Client ID e OAuth Client Secret para usar o registro dinâmico desta implantação.
- Clique em Adicionar/Add e, se solicitado, em Conectar/Connect. Conclua a identificação na página de autorização da SophIA.
- Mesmo se o Claude pedir somente leitura, selecione Criar e alterar dados em Acessos adicionais (opcional) para criar vagas. Para publicar ou enviar, selecione também Enviar comunicações; selecione administração apenas se necessário.
- Marque a confirmação geral, clique em Autorizar conexão e retorne ao Claude. Na conversa, use + → Conectores/Connectors para habilitar a SophIA, quando necessário, e consulte o contexto antes de alterar dados.
Em uma organização, um proprietário (Owner/Primary Owner) pode precisar cadastrar o conector em Organization settings → Connectors → Add → Custom → Web antes de disponibilizá-lo. Cada usuário autentica sua própria credencial. No Claude Desktop, use o conector remoto associado à conta; este passo a passo não requer editar um arquivo de configuração de servidor local.
Se o token continuar apenas com leitura: reconecte e selecione os acessos na página SophIA. Se a reconexão não abrir essa página, remova e adicione o conector novamente. Não dependa de o Claude abrir automaticamente um novo consentimento ao receber um erro de escopo. Dizer “você está autorizado” na conversa não altera o token OAuth.
Depois de retornar, abra uma conversa nova caso a anterior mantenha o estado antigo. Não é necessário gerar outro segredo apenas para autorizar escrita. Se o problema persistir após o consentimento, consulte o diagnóstico de permissões.
Outros clientes MCP: requisitos de compatibilidade
Um cliente adicional precisa suportar MCP remoto sobre Streamable HTTP, descoberta OAuth, authorization code com PKCE S256, registro dinâmico e renovação de tokens. O endereço de retorno OAuth deve ser HTTPS e estar permitido na configuração do servidor SophIA.
Informe a mesma URL /mcp e use o fluxo de autorização do cliente. Não utilize a chave da Interviews API nem o segredo de integração como token Bearer. Um cliente que só suporta servidores locais por stdio, SSE legado ou um token estático não está coberto por esse procedimento.
Claude Code e clientes com callback local: clientes de terminal podem exigir retorno para http://localhost:PORT/callback. A implantação atual da SophIA rejeita retornos loopback em produção. Por isso, adicionar apenas a URL nesses clientes não comprova uma conexão funcional; valide o fluxo com a equipe técnica antes de anunciá-lo como suportado. O conector remoto do Claude web/Desktop é o caminho documentado acima.
Primeiro uso e exemplos de conversa
Ative a conexão na conversa e comece por uma consulta sem efeitos de negócio:
Consulte meu contexto na SophIA. Informe a empresa, o usuário,
as permissões desta conexão e os módulos disponíveis.
Não altere nenhum dado.
O campo scopes informa o acesso do token atual. scopes_disponiveis informa os acessos que podem ser solicitados conforme a credencial, o perfil e os módulos. Ter escrita disponível não significa que ela já foi consentida.
Liste as cinco entrevistas concluídas mais recentes da minha empresa.
Mostre nome, cargo, nota, data e se o teste comportamental foi realizado.
Informe quando algum dado não estiver disponível.
Prepare uma vaga de Analista de Inteligência Artificial.
Empresa confidencial, trabalho remoto, sem divulgar no portal,
sem vídeo, sem currículo obrigatório e sem data de vencimento.
Sugira um código ainda não utilizado e escreva descrição,
responsabilidades, requisitos e diferenciais.
Mostre a proposta e tire as dúvidas antes de salvar.
Localize a vaga pelo código que informei e confira a conta LinkedIn
conectada à minha empresa. Prepare uma publicação somente em texto,
sem imagem, e mostre a prévia. Aguarde minha aprovação para publicar.
Depois de aprovar uma ação, peça o acompanhamento até o resultado final. Para evitar duplicações, consulte a existência de vagas e publicações antes de criar novamente. Criar uma vaga pode iniciar as automações de análise habilitadas no painel; isso é diferente de publicar a vaga no portal ou no LinkedIn.
Para solicitar acesso a uma ferramenta sem executá-la, o cliente pode chamar sophia_contexto com solicitar_acesso_para, por exemplo vaga_criar ou linkedin_publicar. A resposta acesso_solicitado.autorizado=true confirma apenas o acesso. Esse comando é um recurso de diagnóstico/autorização, não uma etapa obrigatória a cada conexão. No Claude, prefira selecionar os escopos no consentimento inicial se o cliente não abrir a autorização adicional.
Combinar a SophIA com outros aplicativos
Quando o assistente também tiver outro aplicativo conectado e autorizado, pode combinar consultas da SophIA com as ferramentas desse aplicativo. Por exemplo, consultar candidatos e preparar convites na sua agenda. O acesso à agenda depende da outra conexão; a SophIA MCP não ganha acesso automático a ela.
Na SophIA, consulte os candidatos da vaga que informei e sugira os dez
mais bem classificados, explicando os critérios e os dados disponíveis.
Usando minha agenda conectada, proponha horários de entrevista.
Mostre nomes, e-mails, horários e texto dos convites para minha aprovação.
Não envie convites antes de eu confirmar.
Confira as informações e autorizações em cada etapa. A disponibilidade desse fluxo depende das ferramentas oferecidas pelo assistente e pela agenda conectada; não significa compatibilidade automática com qualquer aplicativo.
Catálogo completo de ferramentas MCP
O catálogo desta versão contém 95 ferramentas: 90 operações de negócio e 5 auxiliares. As cinco auxiliares respondem diretamente; todas as operações de negócio, inclusive consultas, retornam operation_id para acompanhamento. O cliente recebe somente as ferramentas permitidas à credencial, ao perfil e aos módulos da empresa. Uma ferramenta aparecer na lista não significa que o token atual já tenha todos os escopos necessários.
Legenda dos escopos: R = sophia:read; W = sophia:write; E = sophia:send; A = sophia:admin. As letras de cada linha são cumulativas: R + W + E exige as três permissões. ADM é o administrador do painel da empresa; todas as vagas é a visibilidade all. Recursos contratados, acesso aos registros e configurações dos provedores continuam sendo verificados.
Consulte tools/list no cliente MCP para obter os parâmetros, tipos, campos obrigatórios, valores aceitos e descrições vigentes. Esse schema é a referência para chamadas programáticas; os nomes abaixo não são endpoints REST.
Contexto, operações e arquivos · 5 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso | Parâmetros e resultado |
|---|---|---|---|---|
sophia_contexto | Consultar ou solicitar meu acesso | R | Visibilidade do usuário | solicitar_acesso_para opcional, com o nome exato da ferramenta.Empresa, usuário, perfil, módulos, escopos do token e acessos disponíveis. Se o token já tiver o acesso, confirma a autorização. Se a credencial, o perfil e os módulos permitirem, pode solicitar consentimento adicional; caso contrário, recusa o pedido. Não executa essa ferramenta. |
sophia_tarefa | Consultar resultado de operação MCP | R | Visibilidade do usuário | operation_id (UUID).Estado e resultado de uma operação desta integração. |
sophia_operacoes | Listar minhas operações MCP | R | Visibilidade do usuário | Objeto vazio {}.Até 30 operações recentes e acessíveis desta integração. |
sophia_preparar_upload | Preparar envio privado de arquivo | R + W | Visibilidade do usuário | nome e tamanho_bytes exatos.upload_id e upload_url temporária. O usuário ainda precisa enviar o arquivo no navegador. |
sophia_arquivo | Consultar arquivo da integração | R | Visibilidade do usuário | file_id (UUID).Metadados do arquivo e, para uma saída disponível, link temporário de download. |
Entrevistas, etapas e relatórios · 13 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
entrevistas_listar | Listar entrevistas e indicadores | R | Visibilidade do usuário |
entrevistas_opcoes_filtros | Consultar opções dos filtros | R | Visibilidade do usuário |
entrevistas_kanban | Consultar Kanban | R | Visibilidade do usuário |
entrevista_consultar | Consultar detalhes da entrevista | R | Visibilidade do usuário |
entrevista_relatorio | Obter dossiê consolidado | R | Visibilidade do usuário |
entrevista_documento | Obter documento do candidato | R | Visibilidade do usuário |
entrevista_editar | Editar entrevista | R + W | Visibilidade do usuário |
entrevista_alterar_etapa | Alterar etapa de uma entrevista | R + W | Visibilidade do usuário |
entrevistas_alterar_etapa | Alterar etapas em lote | R + W | Visibilidade do usuário |
entrevista_excluir | Excluir entrevista | R + W + A | ADM do painel |
entrevistas_excluir | Excluir entrevistas em lote | R + W + A | ADM do painel |
entrevistas_exportar | Exportar relatórios de entrevistas | R | Visibilidade do usuário |
entrevistas_exportar_anexos | Preparar ZIP de anexos | R + W | Visibilidade do usuário |
Vagas e convites · 16 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
vagas_listar | Listar vagas | R | Visibilidade do usuário |
vaga_consultar | Consultar vaga | R | Visibilidade do usuário |
vaga_convite_consultar | Consultar convite de vaga | R | Visibilidade do usuário |
vaga_criar | Criar vaga | R + W | Visibilidade do usuário |
vaga_editar | Editar vaga | R + W | Visibilidade do usuário |
vaga_arquivar | Arquivar vaga | R + W | Visibilidade do usuário |
vagas_arquivar | Arquivar vagas em lote | R + W | Visibilidade do usuário |
vaga_reativar | Reativar vaga | R + W | Visibilidade do usuário |
vaga_excluir | Excluir vaga | R + W + A | ADM do painel |
vagas_excluir | Excluir vagas em lote | R + W + A | ADM do painel |
vaga_gerar_rascunho_ia | Gerar descrição com IA | R + W | Visibilidade do usuário |
vaga_enviar_convites_planilha | Enviar convites por planilha | R + W + E | Visibilidade do usuário |
vagas_exportar | Exportar vagas | R | Todas as vagas ou ADM |
vaga_whatsapp_consultar | Consultar convite e saldo WhatsApp | R | Todas as vagas ou ADM |
vaga_whatsapp_previa | Prévia de destinatários WhatsApp | R | Todas as vagas ou ADM |
vaga_whatsapp_enviar | Confirmar envio WhatsApp | R + W + E | Todas as vagas ou ADM |
Feedback e rascunhos de comunicação · 5 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
feedback_consultar | Consultar composição de feedback | R | Visibilidade do usuário |
feedback_preparar_lote | Preparar feedback em lote | R | Visibilidade do usuário |
feedback_enviar | Enviar feedback individual | R + W + E | Visibilidade do usuário |
feedback_enviar_lote | Enviar feedback em lote | R + W + E | Visibilidade do usuário |
template_gerar_rascunho_ia | Gerar rascunho de template com IA | R + W | Visibilidade do usuário |
Configurações da empresa · 9 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
configuracoes_consultar | Consultar configurações da empresa | R | Visibilidade do usuário |
configuracoes_email | Alterar endereço de resposta | R + W | Visibilidade do usuário |
configuracoes_relatorios | Personalizar cabeçalho e rodapé | R + W | Visibilidade do usuário |
configuracoes_logo | Alterar logo dos relatórios | R + W | Visibilidade do usuário |
configuracoes_logo_remover | Remover logo dos relatórios | R + W | Visibilidade do usuário |
configuracoes_portal_logo | Alterar logo do portal público | R + W | Visibilidade do usuário |
configuracoes_portal_logo_remover | Remover logo do portal | R + W | Visibilidade do usuário |
configuracoes_portal | Editar redes e contato do portal | R + W | Visibilidade do usuário |
configuracoes_template | Salvar modelo de comunicação | R + W | Visibilidade do usuário |
Usuários do painel · 4 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
usuarios_listar | Listar usuários da empresa | R + A | ADM do painel |
usuario_criar | Criar usuário da empresa | R + W + E + A | ADM do painel |
usuario_alterar_perfil | Alterar perfil de usuário | R + W + A | ADM do painel |
usuario_excluir | Excluir usuário | R + W + A | ADM do painel |
Notificações, tarefas, exportações e conta · 10 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
notificacoes_listar | Consultar últimas notificações | R | Visibilidade do usuário |
notificacoes_contar | Contar notificações não lidas | R | Visibilidade do usuário |
notificacoes_historico | Consultar histórico de notificações | R | Visibilidade do usuário |
notificacao_marcar_lida | Marcar notificação como lida | R + W | Visibilidade do usuário |
notificacoes_marcar_todas_lidas | Marcar todas as notificações como lidas | R + W | Visibilidade do usuário |
tarefas_painel_status | Consultar status de tarefa | R | Visibilidade do usuário |
tarefas_painel_pagina | Consultar página da tarefa | R | Visibilidade do usuário |
conta_alterar_senha_no_navegador | Abrir fluxo seguro de troca de senha | R | Visibilidade do usuário |
exportacoes_listar | Consultar pacotes de exportação | R | Visibilidade do usuário |
exportacoes_obter | Obter pacote de exportação | R | Visibilidade do usuário |
Currículo Match · 16 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
cv_listar | Pesquisar currículos analisados | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_envios | Consultar envio de currículos | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_lote_status | Consultar status do lote | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_lote_diagnostico | Baixar diagnóstico do lote | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_enviar_arquivos | Enviar currículos PDF ou DOCX | R + W + E | Todas as vagas ou ADM; Currículo Match habilitado |
cv_enviar_zip | Enviar ZIP de currículos | R + W + E | Todas as vagas ou ADM; Currículo Match habilitado |
cv_candidato_obter | Consultar candidato do Currículo Match | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_candidato_editar | Editar dados extraídos do candidato | R + W | Todas as vagas ou ADM; Currículo Match habilitado |
cv_candidato_dossie | Gerar dossiê PDF do currículo | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_convite_previa | Consultar dados para convite | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_convidar | Enviar convite individual | R + W + E | Todas as vagas ou ADM; Currículo Match habilitado |
cv_convidar_massa | Enviar convites de currículos em lote | R + W + E | Todas as vagas ou ADM; Currículo Match habilitado |
cv_excluir | Excluir candidatos do Currículo Match | R + W + A | ADM do painel; Currículo Match habilitado |
cv_exportar_filtrados | Exportar currículos filtrados para Excel | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_exportar_selecionados | Exportar currículos selecionados para Excel | R | Todas as vagas ou ADM; Currículo Match habilitado |
cv_recalcular_vaga | Recalcular currículos para uma vaga | R + W + A | ADM do painel; Currículo Match habilitado |
Banco de Talentos · 4 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
talentos_listar | Consultar Banco de Talentos | R | Todas as vagas ou ADM |
talentos_analisar | Analisar Banco de Talentos para vaga | R + W | Todas as vagas ou ADM |
talentos_status | Consultar andamento da análise de talentos | R | Todas as vagas ou ADM |
talentos_convidar | Convidar candidatos do Banco de Talentos | R + W + E | Todas as vagas ou ADM |
Redes Sociais / LinkedIn · 12 ferramentas
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
linkedin_configuracao | Consultar conexão e templates do LinkedIn | R | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_conectar | Iniciar conexão do LinkedIn no navegador | R + W + E + A | ADM do painel; Redes Sociais / LinkedIn habilitado |
linkedin_sincronizar | Sincronizar conexão do LinkedIn | R + W + A | ADM do painel; Redes Sociais / LinkedIn habilitado |
linkedin_desconectar | Desconectar conta LinkedIn | R + W + A | ADM do painel; Redes Sociais / LinkedIn habilitado |
linkedin_template_criar | Criar template de publicação | R + W | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_template_editar | Editar template de publicação | R + W | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_template_excluir | Excluir template do LinkedIn | R + W | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_imagem | Consultar imagem de template ou publicação | R | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_gerar_rascunho | Gerar rascunho de publicação com IA | R + W | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_publicacao_previa | Consultar prévia e histórico de publicação | R | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_publicar | Publicar vaga no LinkedIn | R + W + E | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
linkedin_publicacao_status | Consultar status da publicação | R | Todas as vagas ou ADM; Redes Sociais / LinkedIn habilitado |
People Analytics · 1 ferramenta
| Ferramenta | Função | Escopos | Perfil e recurso |
|---|---|---|---|
analytics_perguntar | Consultar People Analytics | R | Todas as vagas ou ADM; People Analytics habilitado |
Exclusões e envios: excluir entrevistas, vagas, candidatos do Currículo Match ou usuários exige ADM e os escopos correspondentes. Outras remoções, como logos e templates do LinkedIn, seguem as permissões específicas da tabela. Ferramentas destrutivas ou de efeito externo exigem
confirmar: truee autorização explícita para o conteúdo, destinatários ou registros envolvidos. Uma permissão de envio também pode ser necessária para encaminhar currículos a um serviço externo de análise.
People Analytics: analytics_perguntar faz análises somente de leitura. Envie uma pergunta completa, com o contexto necessário: a ferramenta não recupera conversas de outros logins nem mantém o histórico de chamadas. A disponibilidade depende do módulo e do serviço de IA configurados.
Contrato técnico e exemplos de chamadas
O cliente MCP inicia a conexão, descobre as ferramentas por tools/list e envia chamadas tools/call com argumentos validados pelo schema de cada ferramenta. O transporte usa POST HTTPS com JSON-RPC; o cliente gerencia a negociação de versão e os cabeçalhos. Esta implantação não exige uma sessão MCP persistente por conexão.
O exemplo abaixo representa o corpo de uma chamada após autenticação e inicialização. Ele não é um endpoint REST novo:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "sophia_contexto",
"arguments": {}
}
}
Para listar vagas com paginação explícita:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "vagas_listar",
"arguments": {
"pagina": 1,
"por_pagina": 25,
"situacao": "active",
"modalidade": "all"
}
}
}
Essa consulta é assíncrona. Use o operation_id retornado em uma chamada a sophia_tarefa. Depois percorra as páginas conforme a paginação retornada; a primeira página não representa necessariamente todas as vagas.
Criar uma vaga após aprovação
Exemplo de argumentos de vaga_criar, usando somente dados ilustrativos. Gere um novo UUID em request_id para cada operação lógica; preserve-o apenas para repetir exatamente a mesma solicitação após falha de comunicação.
{
"request_id": "11111111-1111-4111-8111-111111111111",
"titulo": "Analista de Inteligência Artificial",
"empresa": "Confidencial",
"modelo_trabalho": "Remoto",
"sufixo": "ANALISTAIA01",
"pj": false,
"descricao": "Atuar na construção e avaliação de soluções de IA.",
"responsabilidades": ["Desenvolver e avaliar prompts e fluxos de IA."],
"requisitos": ["Experiência com análise de dados e aplicações de IA."],
"diferenciais": ["Conhecimento de RAG e integração de ferramentas."],
"solicitar_video": false,
"teste_comportamental": false,
"curriculo_obrigatorio": false,
"divulgar_portal": false,
"validade": null,
"maximo_entrevistas": 50,
"preparar_linkedin": false
}
sufixo aceita de 1 a 40 letras maiúsculas ou números, sem prefixo da empresa nem hífen. O servidor utiliza a empresa autenticada para compor o código. Consulte códigos existentes e históricos antes de escolher. validade: null significa sem vencimento; preparar_linkedin não publica automaticamente.
| Campo | Formato e uso |
|---|---|
id / job_id | Nas ferramentas de entrevistas e vagas do MCP, ID numérico positivo ou sua representação em string. Use o valor retornado pela consulta MCP. |
| IDs do Currículo Match | UUID do registro de currículo, diferente do identificador de entrevista ou vaga. |
operation_id | UUID da operação MCP. Não é o mesmo identificador de uma tarefa interna do painel. |
request_id | UUID de idempotência, obrigatório nas mutações de negócio. É diferente do id de correlação JSON-RPC. |
upload_id / file_id | UUID emitido pelo fluxo de arquivos; não aceita caminho local ou URL arbitrária como substituto. |
| Datas | Filtros e validade usam AAAA-MM-DD quando previsto no schema. Filtros de entrevistas seguem o recorte UTC; informe o período desejado e converta horários para exibição. |
IDs da API e do MCP não são intercambiáveis. O UUID de entrevista documentado na Interviews API não deve ser enviado como ID numérico às ferramentas do painel MCP. Consulte o registro pelo módulo correspondente e use o identificador devolvido por ele.
Descoberta e endpoints de autenticação
| Método e caminho | Finalidade |
|---|---|
POST /mcp | Mensagens MCP com token OAuth Bearer; cabeçalhos e negociação gerenciados pelo cliente MCP. |
GET /health | Verifica resposta do aplicativo e conexão com o banco; não comprova a saúde de todos os serviços externos. |
GET /.well-known/oauth-protected-resource/mcp | Metadados do recurso protegido. Também disponíveis em /.well-known/oauth-protected-resource. |
GET /.well-known/oauth-authorization-server | Emissor, escopos, registro e endpoints OAuth. |
POST /oauth/register | Registro dinâmico de cliente público, com callback validado. |
GET/POST /oauth/authorize | Autenticação e consentimento no navegador, vinculados à solicitação original. |
POST /oauth/token | Troca de código e renovação com rotação do refresh token. |
POST /oauth/revoke | Revogação de uma família de tokens vinculada ao cliente OAuth. |
Consulta de metadados, sem credenciais:
curl --fail --silent --show-error \
https://sophiamcp-29749696c578.herokuapp.com/.well-known/oauth-authorization-server
O fluxo usa response_type=code, code_challenge_method=S256 e resource igual à URL completa /mcp. O cliente deve preservar state, conferir o emissor e usar exatamente o callback registrado. ID e segredo SophIA autenticam o formulário, não as chamadas Bearer.
Para quem administra uma implantação, PUBLIC_BASE_URL identifica o emissor e precisa corresponder à origem pública HTTPS. OAUTH_REDIRECT_ORIGINS e, quando configurado, OAUTH_REDIRECT_URIS limitam os callbacks; MCP_ALLOWED_ORIGINS trata origens adicionais das chamadas MCP. São controles diferentes. Cadastre apenas os endereços efetivamente usados pelo cliente autorizado, sem curingas. Usuários finais não precisam alterar essas configurações.
Tarefas, resultados e repetição segura
As 90 ferramentas de negócio, inclusive consultas, retornam inicialmente um operation_id. As cinco auxiliares respondem diretamente. O assistente deve acompanhar a operação com sophia_tarefa, respeitando um intervalo entre consultas.
| Estado | Interpretação | Próximo passo |
|---|---|---|
queued | Aceita e aguardando execução. | Aguardar e consultar o mesmo operation_id. |
running | Em execução. | Continuar o acompanhamento sem reenviar a ação. |
succeeded | A etapa MCP terminou. | Ler o resultado. Se houver task_id interno, acompanhar também a tarefa do painel. |
failed | Falha conhecida. | Examinar a mensagem e corrigir a causa antes de decidir uma nova solicitação. |
uncertain | A execução foi interrompida ou o efeito não pôde ser confirmado. | Verificar o painel e o provedor antes de repetir. Não criar automaticamente outra solicitação. |
Quando o resultado contiver um task_id de exportação, análise ou envio, use tarefas_painel_status. Essa consulta também gera uma operação MCP, cujo resultado é obtido por sophia_tarefa. Para LinkedIn, confira ainda linkedin_publicacao_status e o link da publicação quando disponível.
“Recebido” ou “enfileirado” não comprova entrega de e-mail nem publicação. sophia_operacoes recupera as últimas 30 operações visíveis da integração. Os resultados ficam disponíveis por sete dias; depois, consulte o painel.
As mutações de negócio usam request_id para evitar duplicação: repetir a mesma ferramenta e os mesmos argumentos com o mesmo UUID recupera a solicitação existente. Reutilizar o UUID com outro conteúdo produz conflito. Gere outro UUID somente para uma operação realmente nova, depois de verificar o resultado anterior.
Uploads, relatórios e downloads
- O assistente chama
sophia_preparar_uploadcomnomeetamanho_bytesexatos do arquivo. - A SophIA retorna
upload_ideupload_url. Abra o link, selecione o arquivo e conclua o envio no navegador. - Volte à conversa e informe que enviou. A ferramenta de destino recebe o
upload_id; preparar o link não inicia a análise nem a publicação. - Para arquivos gerados, use
sophia_arquivocomfile_idpara obter metadados e um link temporário de download.
Anexar na conversa não basta: um arquivo enviado ao ChatGPT ou Claude não é automaticamente transferido para a SophIA. Utilize o fluxo de upload retornado pelo MCP. O mesmo vale para uma imagem criada pelo assistente para o LinkedIn.
| Fluxo | Formatos e limites |
|---|---|
| Convites por planilha | CSV ou XLSX, até 5 MiB, com os cabeçalhos exigidos pelo fluxo de e-mail ou WhatsApp. |
| Currículos individuais | De 1 a 10 arquivos PDF/DOCX por chamada, sujeitos aos limites do painel e do extrator. |
| Lote de currículos | ZIP preparado pelo fluxo de upload; acompanhar o lote e o processamento. |
| Logo de relatórios | PNG, JPEG ou GIF, até 5 MiB. |
| Logo do portal | PNG, JPEG ou WebP, até 5 MiB. |
| Imagem para LinkedIn | Upload autorizado e validação de imagem/tamanho pelo fluxo do painel. Para texto puro, use imagem_origem: "nenhuma". |
| Relatórios de entrevistas | CSV/XLSX; PDF combinado até 50; DOCX combinado até 1.000; ZIP com PDFs individuais até 25 ou DOCX individuais até 50. |
| Seleção explícita de entrevistas | Até 500 IDs por chamada; use filtros quando o formato permitir uma exportação maior. |
| Excel do Currículo Match | Até 5.000 candidatos por filtro ou seleção. |
| ZIP de anexos | Padrão de até 500 registros; pode ser reduzido pela configuração ou pelo tamanho total. |
O preparo do upload vale duas horas. O registro de um artefato gerado vale 24 horas; os links assinados são mais curtos, normalmente dez minutos. Se um link de saída expirar e o artefato ainda estiver válido, solicite outro por sophia_arquivo.
O limite padrão de preparo é 200 MiB e o de arquivo gerado é 160 MiB, ambos sujeitos à configuração do servidor, com teto de 200 MiB. Sempre prevalece o menor limite entre MCP, ferramenta, painel e provedor. Links temporários dão acesso ao arquivo: compartilhe somente com destinatários autorizados.
Publicar no LinkedIn pela integração do painel
A conexão MCP utiliza a integração LinkedIn já vinculada à empresa. É necessário ter o módulo de Redes Sociais habilitado, a conta conectada e o serviço externo configurado, além dos escopos sophia:read, sophia:write e sophia:send. A publicação exige perfil com acesso a todos os registros ou ADM.
- Consulte a vaga e confirme código, conteúdo e situação. Consulte
linkedin_configuracaopara verificar a conta de destino. - Prepare o texto e consulte a prévia/histórico com
linkedin_publicacao_previa. Não reutilize automaticamente um template de outra vaga. - Para texto puro, indique
imagem_origem: "nenhuma". Para imagem personalizada, conclua primeiro o upload e use o respectivo ID. - Apresente a prévia e obtenha aprovação explícita. Só então chame
linkedin_publicarcom texto, vaga,request_ideconfirmar: true. - Acompanhe a operação, a tarefa interna quando houver e o status de publicação. Informe o link efetivamente retornado pelo serviço.
Conectar ou trocar a conta LinkedIn pode abrir um consentimento próprio no navegador. Essa autorização da rede social é diferente do consentimento entre SophIA e ChatGPT/Claude. Reconectar o MCP não corrige, por si só, uma conta LinkedIn expirada ou um módulo desabilitado.
Segurança, sessões e limites de uso
O vínculo com a empresa é estabelecido pelo servidor. As ferramentas não oferecem SQL livre nem um campo para operar outra empresa. Perfil e módulos são reavaliados; excluir usuários, revogar integrações ou retirar permissões afeta os acessos correspondentes.
Proteção adicional de dados, para a equipe técnica: o servidor dispõe de um modo opcional com acesso PostgreSQL próprio, políticas RLS específicas e contexto da empresa autenticada. Ele exige configuração e verificação antes de ativar MCP_TENANT_ISOLATION_ENABLED=true; o padrão é desativado. A instalação desse recurso não comprova que ele esteja ativo no ambiente. A conexão administrativa/OAuth permanece separada, e as permissões e políticas dos outros aplicativos não devem ser alteradas para habilitá-lo. A presença de RLS nas tabelas, sozinha, não comprova que o papel usado pelo MCP esteja sujeito a essas políticas.
Operações externas e destrutivas exigem confirmar: true no contrato, além da aprovação humana. Excluir entrevistas, vagas, currículos ou usuários exige as permissões administrativas previstas na ferramenta. Outras remoções, como logos e templates, seguem seus próprios requisitos. Não deduza o perfil exigido apenas pelo nome da ação.
| Item | Comportamento atual |
|---|---|
| Convite de ativação | 120 minutos por padrão, ajustáveis entre 15 e 1.440 minutos e limitados pela validade final da credencial. Exige concluir o aceite antes do vencimento. |
| Credencial individual | Pode ter validade final definida pela equipe. Sem data final, continua sujeita a revogação, arquivamento e revalidação do usuário/permissões. |
| Token de acesso | Até dez minutos. O cliente pode renová-lo; isso não significa digitar credenciais a cada dez minutos. |
| Família de renovação | Até 30 dias, limitada pela validade da integração e sujeita a revogação. Rotação de refresh tokens com detecção de reutilização. |
| Login lembrado no navegador | Até oito horas, sem prolongamento a cada uso, quando o recurso estiver instalado. Novos acessos sempre exigem consentimento. |
| Sessão da gestão interna | Até 30 minutos de inatividade ou oito horas desde o login; depende da elegibilidade atual do operador ERP. |
| Requisições MCP | 180 por minuto por integração, incluindo consultas de andamento. HTTP 429 pode informar Retry-After. |
| Operações pendentes | 50 por integração por padrão; configurável pela administração. Aguarde a fila antes de enviar novas operações. |
| Corpo da requisição | JSON até 512 KiB. Arquivos são enviados pelo fluxo próprio, não como conteúdo binário dentro da chamada MCP. |
| Resultados e auditoria | Argumentos/resultados de operações expiram em sete dias; auditoria MCP tem retenção de 90 dias. Isso não define a retenção dos dados de negócio no painel. |
Apagar cookies, trocar de navegador, deixar a sessão expirar ou renovar o segredo pode exigir identificação novamente. Revogar ou arquivar a credencial também invalida seu acesso lembrado. O login do console administrativo, a ativação do convite, a sessão de consentimento e os tokens dos assistentes são independentes. Reconectar para aprovar novos escopos não exige gerar outro segredo enquanto a credencial atual continuar válida.
Uso simultâneo: painel, ChatGPT e Claude podem operar com suas autenticações. Quando usam a mesma base, alterações ficam compartilhadas; duas edições do mesmo registro podem conflitar ou sobrescrever valores conforme o fluxo do painel. Consulte a situação atual antes de gravar e evite repetir a mesma ação em duas conversas.
Compartilhe com o assistente somente os dados necessários à tarefa e observe as políticas da sua organização e do provedor de IA. Não publique relatórios, currículos, links temporários ou credenciais em repositórios abertos. O consentimento MCP não libera faturamento, habilitação comercial de módulos nem alterações no aplicativo do candidato ou no extrator.
Tratamento de erros e reconexão
Observe o resultado MCP e o estado da operação, além do status HTTP. Uma resposta HTTP 200 pode conter um erro de ferramenta ou uma operação que falhou. A mensagem “conexão expirada” exibida pelo cliente também pode envolver falta de escopo; consulte o contexto e o consentimento.
| Sintoma | O que verificar |
|---|---|
| Convite não chegou | Confira o e-mail cadastrado na SophIA e a pasta de spam. A equipe verifica o estado de entrega e pode reenviar. “Enviado” significa aceite pelo provedor, não entrega comprovada. |
| Link de ativação expirado, utilizado ou substituído | Use somente o convite mais recente. Se ainda não houve aceite, peça reenvio à equipe enquanto a validade final permitir; se o acesso já venceu, peça nova credencial. Abrir o link não estende o prazo. |
| Segredo perdido depois do aceite | Não há recuperação do segredo anterior. A equipe usa Novo segredo, que revoga o acesso anterior e envia outro convite para aceite. |
| Credencial revogada ou arquivada | Solicite nova credencial. Reconectar o assistente ou reenviar uma solicitação não reativa esse acesso. |
| URL do convite diferente da cadastrada no assistente | Use a URL oficial exibida após o aceite ou confirmada pela equipe. Não misture domínio próprio e Heroku no mesmo fluxo. Após uma troca da origem oficial, atualize a conexão e conclua nova autorização. |
| 404 na conexão ou POST na raiz | Confirme o caminho /mcp, em vez da raiz ou /admin. |
| GET /mcp não abre uma página | O endpoint é um transporte MCP. Abrir no navegador não equivale a conectar um cliente; use o cadastro de conector e OAuth. |
| 401 / token inválido | Sem token, expirado, revogado ou pertencente a outro recurso. Um 401 inicial faz parte da descoberta OAuth; repetição após autenticar exige verificar a conexão. |
| 403 / insufficient_scope | Compare scopes e scopes_disponiveis. Reconecte e aprove os acessos necessários na página SophIA; não basta o perfil ser administrador. |
| Claude consulta, mas não cria vagas | Autorize Criar e alterar dados nos acessos adicionais. Remova/adicione novamente somente se for necessário para abrir o consentimento. |
| Escrita autorizada, mas token ainda só leitura | Conclua o retorno ao cliente e inicie uma conversa nova. O suporte pode conferir se o cliente solicita explicitamente um token restrito durante a troca ou renovação. |
| Credencial inválida ou sem acessos | Confira o aceite concluído, o ID e o segredo mais recentes, a validade, o usuário ativo, a troca da senha temporária e as permissões da credencial. Uma credencial pendente ainda não permite autenticação. Desmarque opções que sua credencial não permite ou solicite revisão à equipe. |
| Origem ou retorno OAuth inválido | Reinicie a conexão a partir do cliente. A equipe técnica deve conferir a origem HTTPS pública e o callback permitido; não use URLs de callback como comandos de terminal. |
| Erro 400 / argumentos inválidos | Consulte o schema atual, tipos de IDs, enumerações, campos obrigatórios e datas. Atualize o catálogo da conexão. |
| Erro 409 / conflito de solicitação | O mesmo request_id foi usado com conteúdo diferente. Consulte a operação original antes de criar uma nova. |
| Erro 429 / limite atingido | Respeite Retry-After, reduza a frequência de consultas e aguarde operações pendentes. |
| Ferramenta ausente ou módulo negado | Perfil, visibilidade, escopos e módulo habilitado para a empresa. Reconectar não habilita recursos comerciais. |
| Tarefa permanece queued/running | Consulte o mesmo ID. A equipe verifica worker, fila e serviços externos; não duplique a ação. |
| Estado uncertain | Confira painel e provedor. Não trate como falha definitiva nem repita automaticamente um envio. |
| Download expirado | Peça outro link por sophia_arquivo enquanto o artefato estiver válido; após expirar o registro, avalie gerar o arquivo novamente. |
| LinkedIn ou Currículo Match falha | Verifique a tarefa, a integração externa e o módulo da empresa. Credenciais OAuth do MCP não substituem a conexão do provedor. |
| Arquivamento indisponível na gestão interna | A equipe técnica verifica se a migração 2026-10-01_mcp_credential_archive.sql foi aplicada no banco correto. Usuários finais não precisam executar SQL. |
Para desenvolvedores: o desafio de escopo usa HTTP 403 com WWW-Authenticate para clientes genéricos. O ChatGPT recebe a sinalização compatível em _meta["mcp/www_authenticate"]. Cabe ao cliente conduzir a nova autorização. Um cliente que solicite explicitamente um escopo reduzido continua recebendo acesso reduzido, mesmo que uma concessão anterior seja mais ampla.
O suporte pode usar o log [OAUTH] token_issued, que registra somente grant_type, requested_scope, access_scope e refresh_scope. requested_scope: null indica que o parâmetro foi omitido. Nunca envie tokens, códigos de autorização, segredos ou corpos completos de requisição para diagnóstico.
Validação, suporte e referências
Antes de disponibilizar a conexão para uma equipe:
- Valide o convite por e-mail, o prazo, o aceite e a exibição única da URL, ID e segredo, sem compartilhar esses dados em chamados.
- Confirme empresa, usuário e permissões pelo contexto, usando uma credencial por pessoa.
- Valide uma consulta e compare os dados com o painel no mesmo ambiente.
- Teste uma alteração autorizada e acompanhe a operação até o resultado final.
- Para arquivos e envios, valide upload/download, destinatário ou conta de destino e acompanhamento da tarefa externa.
- Em testes autorizados, confirme que um perfil restrito e uma segunda empresa não acessam registros indevidos, e que revogar ou arquivar uma credencial interrompe novos acessos e invalida os convites pendentes.
Em um chamado, informe o cliente utilizado (ChatGPT, Claude ou outro), horário com fuso, ferramenta, código/status do erro, operation_id ou ID da requisição quando disponível e passos para reproduzir. Utilize o contato técnico da sua conta, conforme o capítulo de suporte. Não envie credenciais nem relatórios pessoais completos.
As instruções de interface foram conferidas em 30/09/2026. Nomes dos menus e disponibilidade podem mudar; a documentação oficial do cliente complementa este guia: