Profissionais
Gerencie os profissionais que prestam serviços na sua clínica ou estabelecimento. Profissionais são entidades independentes de agentes NooviChat — podem existir sem acesso ao sistema.
Licença e permissão
Profissionais é uma funcionalidade nativa disponível em todos os planos. Qualquer membro da conta pode consultar os campos necessários ao agendamento; criar, atualizar, remover e consultar dados de gestão exige administrador ou a permissão appointment_manage.
Autenticação e erros de acesso
Os exemplos usam um api_access_token pertencente a um usuário. O backend também aceita uma sessão ou cabeçalhos Devise válidos do usuário; tokens de AgentBot não autorizam estas rotas. Credencial inválida retorna 401. Conta inexistente, suspensa, malformada ou inacessível ao usuário retorna o mesmo 404 genérico, sem revelar se o ID pertence a outro tenant. Nas mutações, falta de permissão retorna 403.
Envelopes de erro
Erros comuns de autenticação, recurso e parâmetro usam error. Validações do profissional usam errors. O corpo de 403 indica falta de permissão.
{ "error": "mensagem" }Visão Geral
Cada profissional tem horários de atendimento configurados por dia da semana, buffer entre consultas, cor para o calendário e especialidade.
Campo opcional agent_id vincula o profissional a um usuário NooviChat quando ele também opera o sistema diretamente. Em dados legados, um vínculo que não pertence mais à conta é protegido na leitura e aparece como null para quem possui acesso de gestão.
Resposta conforme a permissão
Todo membro recebe somente os campos operacionais de agendamento: id, account_id, name, specialty, color, buffer_minutes, working_hours, active, service_ids e avatar_url. Administradores e usuários com appointment_manage também recebem registro, contato, atributos internos, auditoria, timestamps e agent_id.
Envelope do body
Em POST e PATCH, envie os atributos dentro do objeto professional. A API ainda aceita os mesmos atributos no nível raiz por compatibilidade com clientes legados, mas o envelope aninhado é o contrato recomendado.
/api/v1/accounts/{account_id}/professionalsLista todos os profissionais ativos da conta (não-descartados), ordenados por nome. Qualquer membro da conta pode visualizar.
Sem filtros nem paginação
Esta listagem retorna sempre todos os profissionais ativos da conta — não aceita parâmetros de query de filtro ou paginação.
curl -s "https://chat.seudominio.com/api/v1/accounts/1/professionals" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"data": [
{
"id": 3,
"account_id": 1,
"name": "Dr. Maria Santos",
"specialty": "Odontologia Geral",
"color": "#3B82F6",
"buffer_minutes": 10,
"working_hours": {
"mon": [{ "start": "08:00", "end": "18:00" }],
"tue": [{ "start": "08:00", "end": "18:00" }],
"fri": [{ "start": "08:00", "end": "13:00" }]
},
"active": true,
"service_ids": [7],
"avatar_url": null
}
]
}/api/v1/accounts/{account_id}/professionalsCria novo profissional. Exige administrador ou a permissão appointment_manage.
Body (professional)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
name | string | Sim | Nome completo do profissional |
specialty | string | null | Nao | Especialidade (Odontologia, Fisioterapia etc.) |
registry | string | null | Nao | Número do registro profissional (CRM, CRO, CRP etc.) |
email | string | null | Nao | Email do profissional |
phone | string | null | Nao | Telefone do profissional |
color | string | null | Nao | Valor de cor usado no calendário (padrão #3B82F6) |
buffer_minutes | integer | Nao | Buffer em minutos entre consultas, de 0 a 2147483647 (padrão 0) |
working_hours | object | Nao | Horários por mon, tue, wed, thu, fri, sat ou sun; cada dia recebe um array de janelas start/end em HH:MM |
custom_attributes | object | Nao | Metadados livres associados ao profissional |
agent_id | integer (int64) | null | Nao | ID de um usuário que seja membro desta mesma conta; null deixa/remove o vínculo |
active | boolean | Nao | Status ativo (padrão true) |
service_ids | array[integer (int64)] | Nao | Lista completa de IDs de serviços desta conta. Envie dentro de professional; o nível raiz segue aceito por compatibilidade. |
avatar | string | file | null | Nao | ID assinado de blob no JSON ou arquivo no multipart/form-data |
Vínculos são validados pela conta
agent_id e todos os itens de service_ids precisam pertencer à conta autenticada. Um ID de outra conta, malformado ou fora do intervalo suportado rejeita a requisição inteira com 422; a API não remove nem filtra IDs silenciosamente.
Semântica de service_ids
Enviar service_ids: [] define a lista como vazia. Omitir o campo cria um profissional sem serviços no POST e preserva os vínculos atuais no PATCH. null, itens nulos/vazios ou valores aninhados retornam 422 sem mutação parcial.
Em multipart/form-data, use o valor literal professional[service_ids]=[] para limpar todos. Para atribuir IDs, repita professional[service_ids][]=ID para cada serviço.
Contrato de working_hours
As chaves aceitas são mon, tue, wed, thu, fri, sat e sun. Cada janela deve ter start e end com hora zero-padded entre 00:00 e 23:59, e start deve ser anterior a end. Janelas adjacentes são aceitas; sobrepostas ou duplicadas, container nulo e dias desconhecidos retornam 422.
O objeto vazio {} é válido: a listagem de disponibilidade não gera slots, enquanto uma criação direta não recebe restrição de horário de trabalho. Dados legados malformados falham fechados e não disponibilizam horários.
Avatar
No JSON, avatar recebe um ID assinado válido do Active Storage. Em multipart/form-data, pode receber o arquivo diretamente. São aceitas imagens PNG, JPEG/JPG, GIF e WEBP de até 5 MB. ID assinado ou arquivo inválido retorna 422; em uma atualização, null ou string vazia remove o avatar.
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/professionals" \
-H "api_access_token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"professional": {
"name": "Dr. Maria Santos",
"specialty": "Odontologia Geral",
"registry": "CRO-SP 12345",
"color": "#3B82F6",
"buffer_minutes": 10,
"agent_id": 12,
"service_ids": [7],
"working_hours": {
"mon": [{"start": "08:00", "end": "18:00"}],
"tue": [{"start": "08:00", "end": "18:00"}],
"fri": [{"start": "08:00", "end": "13:00"}]
}
}
}'{
"data": {
"id": 3,
"account_id": 1,
"name": "Dr. Maria Santos",
"specialty": "Odontologia Geral",
"registry": "CRO-SP 12345",
"email": "maria@example.com",
"phone": "+5511999990000",
"color": "#3B82F6",
"buffer_minutes": 10,
"working_hours": {
"mon": [{ "start": "08:00", "end": "18:00" }],
"tue": [{ "start": "08:00", "end": "18:00" }],
"fri": [{ "start": "08:00", "end": "13:00" }]
},
"active": true,
"custom_attributes": {},
"discarded_at": null,
"discarded_by_id": null,
"discard_reason": null,
"created_at": "2027-07-21T12:00:00.000Z",
"updated_at": "2027-07-21T12:00:00.000Z",
"agent_id": 12,
"service_ids": [7],
"avatar_url": null
}
}/api/v1/accounts/{account_id}/professionals/{professional_id}Retorna detalhes de um profissional específico.
curl -s "https://chat.seudominio.com/api/v1/accounts/1/professionals/3" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"data": {
"id": 3,
"account_id": 1,
"name": "Dr. Maria Santos",
"specialty": "Odontologia Geral",
"color": "#3B82F6",
"buffer_minutes": 10,
"working_hours": {
"mon": [{ "start": "08:00", "end": "18:00" }],
"tue": [{ "start": "08:00", "end": "18:00" }],
"fri": [{ "start": "08:00", "end": "13:00" }]
},
"active": true,
"service_ids": [7],
"avatar_url": null
}
}/api/v1/accounts/{account_id}/professionals/{professional_id}Atualiza dados do profissional. Exige administrador ou a permissão appointment_manage.
curl -X PATCH "https://chat.seudominio.com/api/v1/accounts/1/professionals/3" \
-H "api_access_token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "professional": { "buffer_minutes": 15, "service_ids": [] } }'Campos omitidos são preservados
O PATCH altera apenas os atributos enviados. Para os vínculos, agent_id: null remove o agente; service_ids: [] remove todos os serviços; omitir service_ids mantém os serviços atuais. Enviar service_ids: null retorna 422 sem alterar o profissional.
{
"data": {
"id": 3,
"account_id": 1,
"name": "Dr. Maria Santos",
"specialty": "Odontologia Geral",
"registry": "CRO-SP 12345",
"email": "maria@example.com",
"phone": "+5511999990000",
"color": "#3B82F6",
"buffer_minutes": 15,
"working_hours": {
"mon": [{ "start": "08:00", "end": "18:00" }],
"tue": [{ "start": "08:00", "end": "18:00" }],
"fri": [{ "start": "08:00", "end": "13:00" }]
},
"active": true,
"custom_attributes": {},
"discarded_at": null,
"discarded_by_id": null,
"discard_reason": null,
"created_at": "2027-07-21T12:00:00.000Z",
"updated_at": "2027-07-21T12:00:00.000Z",
"agent_id": 12,
"service_ids": [],
"avatar_url": null
}
}/api/v1/accounts/{account_id}/professionals/{professional_id}Remove o profissional por soft-delete. Exige administrador ou appointment_manage; o histórico de atendimentos é preservado.
curl -X DELETE "https://chat.seudominio.com/api/v1/accounts/1/professionals/3" \
-H "api_access_token: YOUR_TOKEN"Efeito do soft-delete
O registro deixa de aparecer na listagem e novas consultas diretas por seu ID retornam 404. Atendimentos históricos preservam professional_id e a projeção compacta do profissional arquivado.
/api/v1/accounts/{account_id}/professionals/{professional_id}/availabilityRetorna slots livres do profissional. A data é opcional e usa o fuso de agendamento da conta.
Parâmetros de Query
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
date(query) | string (date) | Nao | Data estrita em YYYY-MM-DD. Padrão: hoje no fuso de agendamento da conta. |
service_id(query) | integer (int64) | Nao | Serviço desta conta oferecido pelo profissional; usa o override de duração da oferta quando configurado |
duration_minutes(query) | integer (int32) | Nao | Duração entre 1 e 2147483647 quando service_id não for informado (padrão 60). Com service_id, ainda é validado, mas a duração efetiva prevalece |
Data e fuso horário
Quando date é omitido, a API usa a data atual no fuso de agendamento da conta: primeiro reporting_timezone, depois o fuso salvo no onboarding e, sem uma configuração válida, America/Sao_Paulo. Os timestamps de slots carregam o offset desse fuso.
curl -s "https://chat.seudominio.com/api/v1/accounts/1/professionals/3/availability?date=2027-08-03&service_id=7" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"data": {
"date": "2027-08-03",
"professional_id": 3,
"slots": [
"2027-08-03T08:00:00-03:00",
"2027-08-03T08:15:00-03:00",
"2027-08-03T08:30:00-03:00"
]
}
}Apenas slots livres
A resposta lista somente os horários de início disponíveis. Horários ocupados são omitidos — não há campo available nem objetos com start/end. A grade avança em intervalos de 15 minutos e, para a data atual, horários que já passaram no fuso da conta são removidos. A duração, o buffer_minutes e os compromissos existentes também participam do cálculo.
Com service_id, a duração efetiva é override_duration_minutes da oferta, quando configurado, ou a duração base do serviço.