Alvará de Funcionamento
Endpoints da WebApiAlcance para o registro interno dos Alvarás de Funcionamento municipais emitidos para os clientes. Cobrem criação, listagem paginada com filtros e ordenação, consulta por ID, atualização, remoção e download do PDF. Registros nascem tanto pela automação de emissão quanto pelo CRUD manual - quando vêm da automação, atividade_id referencia a atividade que originou o alvará; quando nascem pelo CRUD, atividade_id é null.
Todos os endpoints exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs.
Base path
/api/v1/alvara-funcionamentoEscopos necessários
alvara_funcionamento:read- listagem, consulta por ID e download do PDF (rotasGET).alvara_funcionamento:write- criação, atualização e remoção (POST,PUT,DELETE).
O escopo é derivado do prefixo público da rota: /alvara-funcionamento vira o recurso alvara_funcionamento (hífen → underscore), e o método HTTP define a ação (read para GET, write para POST/PUT/DELETE).
Envelope de resposta
Exceto o download de PDF (que devolve bytes), toda resposta segue o envelope padrão da WebApi:
{
"status": "success",
"message": "Mensagem em PT-BR",
"data": {}
}Endpoints
POST /alvara-funcionamento/
Registra um novo Alvará de Funcionamento. Responde 201 Created.
Parâmetros
Sem parâmetros de rota ou query - os dados vão no corpo da requisição (AlvaraFuncionamentoCreate, ver AlvaraFuncionamentoCreate).
Request
{
"id_cliente": 123,
"id_usuario": 7,
"atividade_id": 9981,
"ano_competencia": 2026,
"status": "Concluído",
"arquivo_nome": "Alvara_27898481000150_2026.pdf",
"arquivo_mime": "application/pdf",
"file_base64": "JVBERi0xLjQK..."
}Response 201 Created
{
"status": "success",
"message": "Alvará registrado com sucesso!",
"data": {
"id": 4210,
"id_cliente": 123,
"id_usuario": 7,
"atividade_id": 9981,
"ano_competencia": 2026,
"status": "Concluído",
"arquivo_nome": "Alvara_27898481000150_2026.pdf",
"arquivo_mime": "application/pdf",
"data_hora_emissao": "2026-08-05T09:12:44-03:00"
}
}O data segue AlvaraFuncionamentoRead e nunca inclui file_base64.
Escopo: alvara_funcionamento:write
GET /alvara-funcionamento/
Lista alvarás no envelope paginado, com filtros e ordenação. O campo file_base64 não é retornado - para o PDF use GET /alvara-funcionamento/{alvara_id}/pdf.
Parâmetros de query
| Parâmetro | Tipo | Default | Observações |
|---|---|---|---|
id_cliente | int | - | Filtra por cliente. |
id_usuario | int | - | Filtra por usuário (autoria). |
ano_competencia | int | - | Filtra pelo ano de competência. |
status | str | - | Ex.: Concluído, Falha. Case-insensitive. |
start_date | datetime | - | data_hora_emissao >= start_date. |
end_date | datetime | - | data_hora_emissao <= end_date. |
sort_by | str (whitelist) | data_hora_emissao | Whitelist na seção Ordenação, abaixo. Valor fora dela → 422. |
sort_dir | asc | desc | desc | Valor fora da whitelist → 422. |
page | int (≥ 1) | 1 | Página, 1-based. |
per_page | int (1-500) | - | Itens por página. Se omitido, retorna todos (sem paginar). |
Request
GET /api/v1/alvara-funcionamento/?ano_competencia=2026&page=1&per_page=20Response 200 OK
{
"status": "success",
"message": "Alvarás recuperados com sucesso!",
"data": {
"items": [
{
"id": 4210,
"id_cliente": 123,
"id_usuario": 7,
"atividade_id": 9981,
"data_hora_emissao": "2026-08-05T09:12:44-03:00",
"ano_competencia": 2026,
"status": "Concluído",
"arquivo_nome": "Alvara_27898481000150_2026.pdf"
}
],
"total": 42,
"total_pages": 3,
"current_page": 1,
"per_page": 20
}
}Lista vazia é um estado válido - data.items: [] com total: 0, não é erro. Quando per_page é omitido, total_pages vale 1 e per_page vem null.
Escopo: alvara_funcionamento:read
GET /alvara-funcionamento/{alvara_id}
Busca um alvará pelo ID. Retorna apenas metadados (AlvaraFuncionamentoRead), sem file_base64.
Parâmetros
| Parâmetro | Local | Tipo | Obrigatório | Observações |
|---|---|---|---|---|
alvara_id | rota | int | sim | ID do alvará. |
Response 200 OK
{
"status": "success",
"message": "Alvará encontrado com sucesso!",
"data": {
"id": 4210,
"id_cliente": 123,
"id_usuario": 7,
"atividade_id": 9981,
"data_hora_emissao": "2026-08-05T09:12:44-03:00",
"ano_competencia": 2026,
"status": "Concluído",
"arquivo_nome": "Alvara_27898481000150_2026.pdf",
"arquivo_mime": "application/pdf"
}
}ID inexistente retorna 404 Not Found com detail: "Alvará de Funcionamento com ID {id} não encontrado!".
Escopo: alvara_funcionamento:read
PUT /alvara-funcionamento/{alvara_id}
Atualiza um alvará existente. Todos os campos do corpo são opcionais - só os informados são aplicados.
Parâmetros
alvara_id na rota; corpo em AlvaraFuncionamentoUpdate (ver AlvaraFuncionamentoUpdate).
Campos deliberadamente não editáveis
id_cliente, id_usuario e atividade_id não existem no corpo de atualização. O PUT não pode reatribuir o alvará a outro cliente/usuário nem trocar a atividade de origem.
Request
{
"status": "Falha",
"ano_competencia": 2027
}Response 200 OK
{
"status": "success",
"message": "Alvará atualizado com sucesso!",
"data": {
"id": 4210,
"id_cliente": 123,
"id_usuario": 7,
"atividade_id": 9981,
"data_hora_emissao": "2026-08-05T09:12:44-03:00",
"ano_competencia": 2027,
"status": "Falha",
"arquivo_nome": "Alvara_27898481000150_2026.pdf",
"arquivo_mime": "application/pdf"
}
}ID inexistente retorna 404 Not Found.
Escopo: alvara_funcionamento:write
DELETE /alvara-funcionamento/{alvara_id}
Remove um alvará pelo ID.
Restrito por perfil
Além do escopo alvara_funcionamento:write, esta rota exige perfil administrador ou diretoria. Um token com o escopo correto mas perfil operacional é recusado com 403.
Response 200 OK
{
"status": "success",
"message": "Alvará deletado com sucesso!",
"data": null
}ID inexistente retorna 404 Not Found.
Escopo: alvara_funcionamento:write + perfil administrador ou diretoria
GET /alvara-funcionamento/{alvara_id}/pdf
Devolve o PDF binário do alvará - esta é a única rota que expõe o arquivo.
Parâmetros
| Parâmetro | Local | Tipo | Obrigatório | Observações |
|---|---|---|---|---|
alvara_id | rota | int | sim | ID do alvará. |
Response 200 OK
Content-Type: application/pdfContent-Disposition: attachment; filename="<arquivo_nome ou alvara_funcionamento_{id}.pdf>"
Retorna 404 Not Found quando não há registro, quando não há PDF gravado, ou quando o base64 armazenado não pôde ser decodificado - neste último caso com detail: "PDF do alvará com ID {id} não pôde ser decodificado!".
Sem envelope
Diferente das demais rotas, esta não responde { status, message, data } - o corpo é o PDF. Erros aqui saem como HTTPException ({ "detail": "..." }), com o status HTTP real.
Escopo: alvara_funcionamento:read
Ordenação
sort_by aceita apenas os valores abaixo (validados por Literal; qualquer outro retorna 422):
sort_by | Ordena por |
|---|---|
data_hora_emissao | Data/hora de emissão. Default. |
cliente | Nome do cliente (customer.razao_social), não o ID. |
usuario | Nome do usuário (user.nome), não o ID. |
status | Status do registro. |
ano_competencia | Ano de competência. |
sort_dir aceita asc ou desc (default desc).
Schemas
AlvaraFuncionamentoCreate
Corpo de POST /alvara-funcionamento/.
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
id_cliente | int | sim | FK do cliente. |
id_usuario | int | sim | Autor do registro. |
atividade_id | int | null | não | Atividade que originou o alvará. Nulo quando o registro nasce pelo CRUD. |
ano_competencia | int | null | não | Ano de competência do alvará. |
status | str | sim | Ex.: Concluído, Falha. |
arquivo_nome | str | null | não | Nome do arquivo, usado no Content-Disposition do download. |
arquivo_mime | str | null | não | Normalmente application/pdf. |
file_base64 | str | null | não | PDF em base64. Só entra na escrita - nenhum schema de leitura o expõe. |
AlvaraFuncionamentoUpdate
Corpo de PUT /alvara-funcionamento/{alvara_id}. Todos os campos são opcionais.
| Campo | Tipo | Observações |
|---|---|---|
ano_competencia | int | - |
status | str | - |
file_base64 | str | Substitui o PDF gravado. |
arquivo_nome | str | - |
arquivo_mime | str | - |
id_cliente, id_usuario e atividade_id não fazem parte deste schema.
AlvaraFuncionamentoRead
data de POST, GET /{alvara_id} e PUT.
| Campo | Tipo | Observações |
|---|---|---|
id | int | ID do alvará. |
id_cliente | int | - |
id_usuario | int | Autor do registro. |
atividade_id | int | null | - |
data_hora_emissao | datetime | null | - |
ano_competencia | int | null | - |
status | str | - |
arquivo_nome | str | null | - |
arquivo_mime | str | null | - |
Não inclui file_base64.
AlvaraFuncionamentoListItem
Item de items[] na listagem. Igual ao AlvaraFuncionamentoRead, sem arquivo_mime e sem file_base64.
PaginatedAlvaraFuncionamento
data de GET /alvara-funcionamento/.
| Campo | Tipo | Observações |
|---|---|---|
items | List[AlvaraFuncionamentoListItem] | Página atual. |
total | int | Total de registros que atendem aos filtros. |
total_pages | int | 1 quando per_page é omitido. |
current_page | int | Ecoa o page recebido. |
per_page | int | null | null quando omitido na requisição (retorno sem paginação). |
Notas
- O PDF fica em coluna
MEDIUMTEXTe nunca aparece nas respostas JSON - só emGET /{alvara_id}/pdf. sort_by=clienteesort_by=usuariofazemJOINe ordenam pelo nome, que é o que o consumidor exibe.- Apagar a atividade que originou o alvará não apaga o registro:
atividade_idficanull. DELETE /alvara-funcionamento/{alvara_id}remove o registro por completo, incluindo o PDF gravado.