# API do AgendAI (leitura) — Dashboard e cancelamentos

Guia de uso (login, convenções, erros): https://api-docs.agendai.pro/md/guia.md


Números consolidados do mês e da semana e índice de cancelamento.

- `GET /dashboard/resumo-mes` — Resumo do mês da Visão geral (minutos e contagens)
- `GET /dashboard/cardMensal` — Ocupação do mês por status, em percentual e em horas
- `GET /dashboard/cardSemanal` — Ocupação da semana ISO por status, em percentual e em horas
- `GET /dashboard/indice-cancelamento-mensal` — Horas canceladas e horas agendadas por pessoa no mês
- `GET /dashboard/indice-cancelamento-semanal` — Horas canceladas e horas agendadas por pessoa na semana ISO

### GET /dashboard/resumo-mes

**Resumo do mês da Visão geral (minutos e contagens)** · operationId `obterResumoMesDashboard`

Autenticação: `Authorization: Bearer <token>`.

Responde: "como está o mês: quanto foi realizado, quanto está confirmado, o que aguarda aprovação ou conferência?". Devolve sete números do mês.

**Cálculo.** Considera as agendas **não excluídas** cujo **`dataInicio`** cai no mês civil (hora de parede gravada como UTC: o mês vai de `AAAA-MM-01T00:00:00Z` inclusive ao dia 1 do mês seguinte exclusivo). Campos em **MINUTOS**: `minutosRealizados` (REALIZADO), `minutosConfirmadosARealizar` (CONFIRMADO), `minutosAgendados` (PRE_RESERVAR + RESERVADO + CONFIRMADO + REALIZADO). Campos em **QUANTIDADE de agendas**: `aguardandoAprovacao` (CONFIRMADO com `statusAprovacao = AGUARDANDO`), `conferenciasPendentes` (REALIZADO com `conferencia = false`), `totalAgendamentos` (todas menos as CANCELADAS; inclui PENDENTE e agendas sem status).

**Permissão e escopo.** Exige token válido (JWT). Sem `@Roles`, mas **é a única rota deste grupo com escopo de dados**: o resultado considera só as agendas que o usuário pode ler (o mesmo escopo da lista de agendas): visão total vê tudo; com o acesso por setor ligado, a pessoa vê os ramos do seu setor (ex.: agendas CS, universo comercial, clientes de que é CS) mais as agendas em que é responsável ou convidada; perfil comercial restrito vê as agendas do seu vendedor mais as em que é responsável ou convidado; quem não tem escopo nenhum (e não é participante) recebe os números zerados (não é 403). Não aceita os filtros `usuarioIds`/`setor`.

Erros: `mesAno` ausente ou em formato inválido dá 400.

#### Parâmetros

| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
| `mesAno` | query | string | sim | Mês de referência. Formatos aceitos: `MM-AAAA` (ex.: `03-2026`, recomendado) ou `Mês AAAA` com o nome do mês em português, capitalizado e com acento (`Março 2026`). Também é lido de `mesAno[mesAno]`. O mês cobre as agendas cujo INÍCIO (`dataInicio`) cai nele. Ex.: `03-2026` |

#### Resposta 200

Resumo do mês.

Tipo da raiz: DashboardResumoMes

| Campo | Tipo | Sempre presente | Descrição |
|---|---|---|---|
| `mesAno` | string | sim | Eco do parâmetro `mesAno` recebido, sem normalizar. |
| `minutosRealizados` | integer | sim | MINUTOS de agendas com status REALIZADO que começam no mês. |
| `minutosConfirmadosARealizar` | integer | sim | MINUTOS de agendas com status CONFIRMADO que começam no mês. |
| `aguardandoAprovacao` | integer | sim | QUANTIDADE (não minutos) de agendas CONFIRMADAS com aprovação em `AGUARDANDO`. |
| `conferenciasPendentes` | integer | sim | QUANTIDADE de agendas REALIZADAS ainda sem conferência (`conferencia = false`). |
| `totalAgendamentos` | integer | sim | QUANTIDADE de agendas do mês que NÃO estão canceladas (status nulo ou diferente de CANCELADO; inclui PENDENTE, reservadas, etc.). |
| `minutosAgendados` | integer | sim | MINUTOS somados dos status PRE_RESERVAR, RESERVADO, CONFIRMADO e REALIZADO. |

Exemplo (dados fictícios):

```json
{
  "mesAno": "03-2026",
  "minutosRealizados": 7440,
  "minutosConfirmadosARealizar": 1800,
  "aguardandoAprovacao": 6,
  "conferenciasPendentes": 14,
  "totalAgendamentos": 132,
  "minutosAgendados": 12600
}
```

#### Erros

- **400**: Parâmetros inválidos. `message` é uma lista com um item por problema, no formato `campo: motivo`.
- **401**: Token ausente, inválido, expirado ou de usuário desativado. Faça login de novo.

---

### GET /dashboard/cardMensal

**Ocupação do mês por status, em percentual e em horas** · operationId `obterCardMensalDashboard`

Autenticação: `Authorization: Bearer <token>`.

Responde: "que fatia da capacidade do mês está confirmada, pré-reservada, reservada, realizada, cancelada ou livre?".

**Capacidade (base 100%).** `capacidadeHoras` = horas úteis do mês (calendário de dias úteis, 2023-2025 por tabela fixa, 2026 em diante pela regra de dias úteis; mês desconhecido = 160) x **número de pessoas distintas que têm ao menos uma agenda não excluída no mês** (qualquer status, só agendas com consultor). Ou seja, a capacidade depende de quem tem agenda, não do tamanho cadastrado da equipe.

**Como o status é contado.** Soma as durações de TODAS as agendas não excluídas (`deleted_at` nulo) da organização cujo `dataInicio` cai no período, por status, em **horas** (minutos / 60). Uma agenda CANCELADA com `deduzir = true` conta como REALIZADA. Agendas PENDENTE e agendas sem status NÃO aparecem em nenhum campo da resposta e NÃO reduzem o `livre` (`livre` = capacidade menos as cinco categorias exibidas), mas contam para o número de pessoas da capacidade. `livre` nunca é negativo (sobreposição/overbooking é cortada em 0).

**Unidades.** `porcentagem*`: percentual 0-100 como **TEXTO** com 2 casas (`"12.50"`); `horasPorStatus.*` e `capacidadeHoras`: **número em horas**, 2 casas. Os percentuais são horas / capacidade x 100 e podem passar de 100 individualmente, mas `porcentagemLivre` é cortado em 0.

**Permissão:** exige token válido (JWT) e organização identificada. Não há `@Roles` nem checagem de tela. Os filtros `usuarioIds` e `setor` restringem às pessoas informadas (400 se malformados ou `setor` desconhecido). Nenhum escopo por usuário: qualquer usuário autenticado vê as horas de todas as pessoas da organização.

Erros: `mesAno` ausente ou inválido (ex.: `foo`, `13-2026`, nome de mês errado) responde **400**.

#### Parâmetros

| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
| `mesAno` | query | string | sim | Mês de referência. Formatos aceitos: `MM-AAAA` (ex.: `03-2026`, recomendado) ou `Mês AAAA` com o nome do mês em português, capitalizado e com acento (`Março 2026`). Também é lido de `mesAno[mesAno]`. O mês cobre as agendas cujo INÍCIO (`dataInicio`) cai nele. Ex.: `03-2026` |
| `usuarioIds` | query | lista de string (uuid) | não | Restringe às pessoas (usuário responsável da agenda). UUIDs (maiúsculas são aceitas e convertidas), repetidos ou separados por vírgula; máx. 200; só usuários da organização. UUID malformado dá 400. Ex.: `["5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10"]` |
| `setor` | query | lista de string — um de: `CONSULTORIA`, `PROJETOS`, `COMERCIAL`, `FINANCEIRO`, `MIGRACAO`, `CS` | não | Restringe ao setor efetivo do responsável: CONSULTORIA, PROJETOS, COMERCIAL, FINANCEIRO, MIGRACAO, CS (sem diferenciar maiúsculas). Com `usuarioIds`, vale a interseção. Desconhecido dá 400. Ex.: `["CONSULTORIA"]` |

#### Resposta 200

Ocupação do mês.

Tipo da raiz: DashboardCard

| Campo | Tipo | Sempre presente | Descrição |
|---|---|---|---|
| `porcentagemConfirmadas` | string | sim |  |
| `porcentagemPreReservadas` | string | sim |  |
| `porcentagemReservado` | string | sim |  |
| `porcentagemRealizadas` | string | sim |  |
| `porcentagemCanceladas` | string | sim |  |
| `porcentagemLivre` | string | sim | 100 menos a soma dos demais, nunca negativa. |
| `horasPorStatus` | DashboardHorasPorStatus | sim | Horas (NÚMERO, em horas, 2 casas) de cada status; as mesmas que sustentam os percentuais. |
| `horasPorStatus.confirmadas` | number | sim |  |
| `horasPorStatus.preReservadas` | number | sim |  |
| `horasPorStatus.reservado` | number | sim |  |
| `horasPorStatus.realizadas` | number | sim |  |
| `horasPorStatus.canceladas` | number | sim |  |
| `horasPorStatus.livre` | number | sim | Capacidade que sobra, nunca negativa; 0 sem capacidade. |
| `capacidadeHoras` | number | sim | Capacidade do período em HORAS = horas úteis do período x número de pessoas com alguma agenda no período. É a base (100%) dos percentuais. |

Exemplo (dados fictícios):

```json
{
  "porcentagemConfirmadas": "12.50",
  "porcentagemPreReservadas": "3.10",
  "porcentagemReservado": "8.00",
  "porcentagemRealizadas": "40.25",
  "porcentagemCanceladas": "5.00",
  "porcentagemLivre": "31.15",
  "horasPorStatus": {
    "confirmadas": 20,
    "preReservadas": 4.96,
    "reservado": 12.8,
    "realizadas": 64.4,
    "canceladas": 8,
    "livre": 49.84
  },
  "capacidadeHoras": 160
}
```

#### Erros

- **400**: Parâmetros inválidos. `message` é uma lista com um item por problema, no formato `campo: motivo`.
- **401**: Token ausente, inválido, expirado ou de usuário desativado. Faça login de novo.

---

### GET /dashboard/cardSemanal

**Ocupação da semana ISO por status, em percentual e em horas** · operationId `obterCardSemanalDashboard`

Autenticação: `Authorization: Bearer <token>`.

Responde: o mesmo que `cardMensal`, mas para uma **semana ISO** (segunda 00:00 a domingo 23:59:59.999).

**Capacidade (base 100%).** `capacidadeHoras` = horas úteis da semana (2023-2025 por tabela fixa, 2026 em diante pela regra de dias úteis; 40 h para semana fora das regras) x número de pessoas distintas com ao menos uma agenda não excluída na semana.

**Como o status é contado.** Soma as durações de TODAS as agendas não excluídas (`deleted_at` nulo) da organização cujo `dataInicio` cai no período, por status, em **horas** (minutos / 60). Uma agenda CANCELADA com `deduzir = true` conta como REALIZADA. Agendas PENDENTE e agendas sem status NÃO aparecem em nenhum campo da resposta e NÃO reduzem o `livre` (`livre` = capacidade menos as cinco categorias exibidas), mas contam para o número de pessoas da capacidade. `livre` nunca é negativo (sobreposição/overbooking é cortada em 0).

**Unidades.** `porcentagem*`: percentual 0-100 como **TEXTO** com 2 casas; `horasPorStatus.*` e `capacidadeHoras`: **número em horas**. `semanaAno` ecoa o texto recebido sem normalizar (`00-2027` volta `00-2027`); só com os literais `null`/`undefined` vem a semana de hoje no formato `"S AAAA"` (espaço, sem zero à esquerda, ex.: `"7 2026"`).

**Permissão:** exige token válido (JWT) e organização identificada. Não há `@Roles` nem checagem de tela. Os filtros `usuarioIds` e `setor` restringem às pessoas informadas (400 se malformados ou `setor` desconhecido). Nenhum escopo por usuário: qualquer usuário autenticado vê as horas de todas as pessoas da organização.

Erros: `semanaAno` ausente ou vazio dá 400; formato inválido dá 400. Detalhe: os textos literais `null` e `undefined` passam pelo controller e o serviço os trata como "semana de hoje".

#### Parâmetros

| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
| `semanaAno` | query | string | sim | Semana ISO 8601 (segunda a domingo) no formato `SS-AAAA` (também `SS AAAA`), onde AAAA é o ANO ISO (29/12/2025 é a semana 01 de 2026) e SS vai de 0 a 53. `00-2027` é normalizado para a semana ISO real (53-2026). Ausente ou malformado dá 400. Também é lido de `semanaAno[semanaAno]`. Ex.: `11-2026` |
| `usuarioIds` | query | lista de string (uuid) | não | Restringe às pessoas (usuário responsável da agenda). UUIDs (maiúsculas são aceitas e convertidas), repetidos ou separados por vírgula; máx. 200; só usuários da organização. UUID malformado dá 400. Ex.: `["5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10"]` |
| `setor` | query | lista de string — um de: `CONSULTORIA`, `PROJETOS`, `COMERCIAL`, `FINANCEIRO`, `MIGRACAO`, `CS` | não | Restringe ao setor efetivo do responsável: CONSULTORIA, PROJETOS, COMERCIAL, FINANCEIRO, MIGRACAO, CS (sem diferenciar maiúsculas). Com `usuarioIds`, vale a interseção. Desconhecido dá 400. Ex.: `["CONSULTORIA"]` |

#### Resposta 200

Ocupação da semana.

Tipo da raiz: qualquer

| Campo | Tipo | Sempre presente | Descrição |
|---|---|---|---|
| `semanaAno` | string | sim |  |

Exemplo (dados fictícios):

```json
{
  "semanaAno": "11-2026",
  "porcentagemConfirmadas": "12.50",
  "porcentagemPreReservadas": "3.10",
  "porcentagemReservado": "8.00",
  "porcentagemRealizadas": "40.25",
  "porcentagemCanceladas": "5.00",
  "porcentagemLivre": "31.15",
  "horasPorStatus": {
    "confirmadas": 20,
    "preReservadas": 4.96,
    "reservado": 12.8,
    "realizadas": 64.4,
    "canceladas": 8,
    "livre": 49.84
  },
  "capacidadeHoras": 160
}
```

#### Erros

- **400**: Parâmetros inválidos. `message` é uma lista com um item por problema, no formato `campo: motivo`.
- **401**: Token ausente, inválido, expirado ou de usuário desativado. Faça login de novo.

---

### GET /dashboard/indice-cancelamento-mensal

**Horas canceladas e horas agendadas por pessoa no mês** · operationId `obterIndiceCancelamentoMensal`

Autenticação: `Authorization: Bearer <token>`.

Responde: "quanto cada pessoa cancelou em um mês e quanto agendou no total?". É a matéria-prima do índice de cancelamento: **a rota NÃO calcula o percentual**; quem consome divide `Cancelados` por `Total Agendamentos` (ou por Cancelados + Total, conforme a definição de negócio).

**Formato.** `resultadoFinal` tem sempre duas séries (`Cancelados` e `Total Agendamentos`). Cada série traz listas paralelas por pessoa (`ordem` = nome, `usuarioIds`, `data` = horas sem arredondar, `horas` = horas com 2 casas). A mesma pessoa ocupa a mesma posição nas duas séries. Pessoas sem nenhuma agenda no período não aparecem.

**Cálculo (unidade: HORAS decimais).** Considera agendas não excluídas da organização cujo `dataInicio` cai no período e que tenham consultor. `Cancelados` = horas das agendas com status CANCELADO **exceto** as canceladas com `deduzir = true` (essas contam como REALIZADO). `Total Agendamentos` = horas de TODAS as agendas **não canceladas** (PRE_RESERVAR, RESERVADO, CONFIRMADO, REALIZADO, PENDENTE, sem status e canceladas com `deduzir`), ou seja, NÃO inclui as canceladas. Agrupa por pessoa: o responsável da agenda (reserva no usuário do consultor, depois no consultor).

**Permissão:** exige token válido (JWT) e organização identificada. Não há `@Roles` nem checagem de tela. Os filtros `usuarioIds` e `setor` restringem às pessoas informadas (400 se malformados ou `setor` desconhecido). Nenhum escopo por usuário: qualquer usuário autenticado vê as horas de todas as pessoas da organização.

Erros: `mesAno` ausente ou com formato inválido responde **400**.

#### Parâmetros

| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
| `mesAno` | query | string | sim | Mês de referência. Formatos aceitos: `MM-AAAA` (ex.: `03-2026`, recomendado) ou `Mês AAAA` com o nome do mês em português, capitalizado e com acento (`Março 2026`). Só é lido de `mesAno` (a forma `mesAno[mesAno]` NÃO é aceita nesta rota: sem `mesAno`, responde 400). O mês cobre as agendas cujo INÍCIO (`dataInicio`) cai nele. Ex.: `03-2026` |
| `usuarioIds` | query | lista de string (uuid) | não | Restringe às pessoas (usuário responsável da agenda). UUIDs (maiúsculas são aceitas e convertidas), repetidos ou separados por vírgula; máx. 200; só usuários da organização. UUID malformado dá 400. Ex.: `["5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10"]` |
| `setor` | query | lista de string — um de: `CONSULTORIA`, `PROJETOS`, `COMERCIAL`, `FINANCEIRO`, `MIGRACAO`, `CS` | não | Restringe ao setor efetivo do responsável: CONSULTORIA, PROJETOS, COMERCIAL, FINANCEIRO, MIGRACAO, CS (sem diferenciar maiúsculas). Com `usuarioIds`, vale a interseção. Desconhecido dá 400. Ex.: `["CONSULTORIA"]` |

#### Resposta 200

Séries do índice de cancelamento do mês.

Tipo da raiz: DashboardIndiceCancelamento

| Campo | Tipo | Sempre presente | Descrição |
|---|---|---|---|
| `resultadoFinal` | DashboardSerie[] | sim | Sempre duas séries, nesta ordem: `Cancelados` e `Total Agendamentos`. |
| `resultadoFinal[].ordem` | string[] | sim | Nome de cada pessoa (coluna), ordenado por nome. Pode repetir entre homônimos. |
| `resultadoFinal[].usuarioIds` | lista de string (uuid) \| null | sim | Usuário de cada coluna, na mesma ordem de `ordem`; nulo quando a agenda está reservada num consultor sem usuário. |
| `resultadoFinal[].name` | string — um de: `Cancelados`, `Total Agendamentos` | sim | Nome da série. |
| `resultadoFinal[].data` | number[] | sim | Horas (decimais, SEM arredondar) de cada coluna. |
| `resultadoFinal[].horas` | number[] | sim | Mesmas horas de `data`, arredondadas a 2 casas. |

Exemplo (dados fictícios):

```json
{
  "resultadoFinal": [
    {
      "ordem": [
        "Consultor Exemplo",
        "Outra Consultora Exemplo"
      ],
      "usuarioIds": [
        "5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10",
        "9a3c7e10-2b4d-4f68-a1c5-7e8d9f0a1b22"
      ],
      "name": "Cancelados",
      "data": [
        4,
        1.5
      ],
      "horas": [
        4,
        1.5
      ]
    },
    {
      "ordem": [
        "Consultor Exemplo",
        "Outra Consultora Exemplo"
      ],
      "usuarioIds": [
        "5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10",
        "9a3c7e10-2b4d-4f68-a1c5-7e8d9f0a1b22"
      ],
      "name": "Total Agendamentos",
      "data": [
        120.5,
        98.33333333333333
      ],
      "horas": [
        120.5,
        98.33
      ]
    }
  ]
}
```

#### Erros

- **400**: Parâmetros inválidos. `message` é uma lista com um item por problema, no formato `campo: motivo`.
- **401**: Token ausente, inválido, expirado ou de usuário desativado. Faça login de novo.

---

### GET /dashboard/indice-cancelamento-semanal

**Horas canceladas e horas agendadas por pessoa na semana ISO** · operationId `obterIndiceCancelamentoSemanal`

Autenticação: `Authorization: Bearer <token>`.

Responde: "quanto cada pessoa cancelou em uma semana ISO e quanto agendou no total?". É a matéria-prima do índice de cancelamento: **a rota NÃO calcula o percentual**; quem consome divide `Cancelados` por `Total Agendamentos` (ou por Cancelados + Total, conforme a definição de negócio).

**Formato.** `resultadoFinal` tem sempre duas séries (`Cancelados` e `Total Agendamentos`). Cada série traz listas paralelas por pessoa (`ordem` = nome, `usuarioIds`, `data` = horas sem arredondar, `horas` = horas com 2 casas). A mesma pessoa ocupa a mesma posição nas duas séries. Pessoas sem nenhuma agenda no período não aparecem.

**Cálculo (unidade: HORAS decimais).** Considera agendas não excluídas da organização cujo `dataInicio` cai no período e que tenham consultor. `Cancelados` = horas das agendas com status CANCELADO **exceto** as canceladas com `deduzir = true` (essas contam como REALIZADO). `Total Agendamentos` = horas de TODAS as agendas **não canceladas** (PRE_RESERVAR, RESERVADO, CONFIRMADO, REALIZADO, PENDENTE, sem status e canceladas com `deduzir`), ou seja, NÃO inclui as canceladas. Agrupa por pessoa: o responsável da agenda (reserva no usuário do consultor, depois no consultor).

**Permissão:** exige token válido (JWT) e organização identificada. Não há `@Roles` nem checagem de tela. Os filtros `usuarioIds` e `setor` restringem às pessoas informadas (400 se malformados ou `setor` desconhecido). Nenhum escopo por usuário: qualquer usuário autenticado vê as horas de todas as pessoas da organização.

Erros: `semanaAno` ausente ou malformado dá 400.

#### Parâmetros

| Nome | Onde | Tipo | Obrigatório | Descrição |
|---|---|---|---|---|
| `semanaAno` | query | string | sim | Semana ISO 8601 (segunda a domingo) no formato `SS-AAAA` (também `SS AAAA`), onde AAAA é o ANO ISO (29/12/2025 é a semana 01 de 2026) e SS vai de 0 a 53. `00-2027` é normalizado para a semana ISO real (53-2026). Ausente ou malformado dá 400. Ex.: `11-2026` |
| `usuarioIds` | query | lista de string (uuid) | não | Restringe às pessoas (usuário responsável da agenda). UUIDs (maiúsculas são aceitas e convertidas), repetidos ou separados por vírgula; máx. 200; só usuários da organização. UUID malformado dá 400. Ex.: `["5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10"]` |
| `setor` | query | lista de string — um de: `CONSULTORIA`, `PROJETOS`, `COMERCIAL`, `FINANCEIRO`, `MIGRACAO`, `CS` | não | Restringe ao setor efetivo do responsável: CONSULTORIA, PROJETOS, COMERCIAL, FINANCEIRO, MIGRACAO, CS (sem diferenciar maiúsculas). Com `usuarioIds`, vale a interseção. Desconhecido dá 400. Ex.: `["CONSULTORIA"]` |

#### Resposta 200

Séries do índice de cancelamento da semana.

Tipo da raiz: DashboardIndiceCancelamento

| Campo | Tipo | Sempre presente | Descrição |
|---|---|---|---|
| `resultadoFinal` | DashboardSerie[] | sim | Sempre duas séries, nesta ordem: `Cancelados` e `Total Agendamentos`. |
| `resultadoFinal[].ordem` | string[] | sim | Nome de cada pessoa (coluna), ordenado por nome. Pode repetir entre homônimos. |
| `resultadoFinal[].usuarioIds` | lista de string (uuid) \| null | sim | Usuário de cada coluna, na mesma ordem de `ordem`; nulo quando a agenda está reservada num consultor sem usuário. |
| `resultadoFinal[].name` | string — um de: `Cancelados`, `Total Agendamentos` | sim | Nome da série. |
| `resultadoFinal[].data` | number[] | sim | Horas (decimais, SEM arredondar) de cada coluna. |
| `resultadoFinal[].horas` | number[] | sim | Mesmas horas de `data`, arredondadas a 2 casas. |

Exemplo (dados fictícios):

```json
{
  "resultadoFinal": [
    {
      "ordem": [
        "Consultor Exemplo"
      ],
      "usuarioIds": [
        "5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10"
      ],
      "name": "Cancelados",
      "data": [
        2
      ],
      "horas": [
        2
      ]
    },
    {
      "ordem": [
        "Consultor Exemplo"
      ],
      "usuarioIds": [
        "5d1b6c2e-8f3a-4c71-9b0e-2a7d4e6f1a10"
      ],
      "name": "Total Agendamentos",
      "data": [
        31.5
      ],
      "horas": [
        31.5
      ]
    }
  ]
}
```

#### Erros

- **400**: Parâmetros inválidos. `message` é uma lista com um item por problema, no formato `campo: motivo`.
- **401**: Token ausente, inválido, expirado ou de usuário desativado. Faça login de novo.
