ISS Guias

Endpoints da WebApiAlcance para o registro interno das Guias de ISS emitidas para os clientes, nos tipos com_aliquota e sem_aliquota. 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 a guia; 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/iss-guias

Escopos necessários

  • iss_guias:read - listagem, consulta por ID e download do PDF (rotas GET).
  • iss_guias:write - criação, atualização e remoção (POST, PUT, DELETE).

O escopo é derivado do prefixo público da rota: /iss-guias vira o recurso iss_guias (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 /iss-guias/

Registra uma nova Guia de ISS. Responde 201 Created.

Parâmetros

Sem parâmetros de rota ou query - os dados vão no corpo da requisição (IssGuiaCreate, ver IssGuiaCreate).

Autoria não é forjável

O campo id_usuario do corpo é sobrescrito pelo usuário autenticado antes da gravação. Enviá-lo com outro valor não tem efeito.

Request

{
  "id_cliente": 123,
  "id_usuario": 7,
  "atividade_id": 9981,
  "tipo": "com_aliquota",
  "competencia": "2026-06",
  "status": "Concluído",
  "arquivo_nome": "ISS_27898481000150_2026-06.pdf",
  "arquivo_mime": "application/pdf",
  "file_base64": "JVBERi0xLjQK..."
}

Response 201 Created

{
  "status": "success",
  "message": "Guia registrada com sucesso!",
  "data": {
    "id": 4210,
    "id_cliente": 123,
    "id_usuario": 7,
    "atividade_id": 9981,
    "tipo": "com_aliquota",
    "competencia": "2026-06",
    "status": "Concluído",
    "arquivo_nome": "ISS_27898481000150_2026-06.pdf",
    "arquivo_mime": "application/pdf",
    "data_hora_emissao": "2026-08-05T09:12:44-03:00"
  }
}

O data segue IssGuiaRead e nunca inclui file_base64.

Escopo: iss_guias:write

GET /iss-guias/

Lista guias de ISS no envelope paginado, com filtros e ordenação. O campo file_base64 não é retornado - para o PDF use GET /iss-guias/{guia_id}/pdf.

Parâmetros de query

ParâmetroTipoDefaultObservações
id_clienteint-Filtra por cliente.
id_usuarioint-Filtra por usuário (autoria).
tipostr-com_aliquota | sem_aliquota. Case-insensitive.
statusstr-Ex.: Concluído, Falha. Case-insensitive.
competenciastr-Competência AAAA-MM. Case-insensitive.
start_datedatetime-data_hora_emissao >= start_date.
end_datedatetime-data_hora_emissao <= end_date.
sort_bystr (whitelist)data_hora_emissaoWhitelist na seção Ordenação, abaixo. Valor fora dela → 422.
sort_dirasc | descdescValor fora da whitelist → 422.
pageint (≥ 1)1Página, 1-based.
per_pageint (1-500)-Itens por página. Se omitido, retorna todos (sem paginar).

Request

GET /api/v1/iss-guias/?competencia=2026-06&tipo=com_aliquota&page=1&per_page=20

Response 200 OK

{
  "status": "success",
  "message": "Guias recuperadas 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",
        "tipo": "com_aliquota",
        "competencia": "2026-06",
        "status": "Concluído",
        "arquivo_nome": "ISS_27898481000150_2026-06.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: iss_guias:read

GET /iss-guias/{guia_id}

Busca uma guia de ISS pelo ID. Retorna apenas metadados (IssGuiaRead), sem file_base64.

Parâmetros

ParâmetroLocalTipoObrigatórioObservações
guia_idrotaintsimID da guia.

Response 200 OK

{
  "status": "success",
  "message": "Guia encontrada com sucesso!",
  "data": {
    "id": 4210,
    "id_cliente": 123,
    "id_usuario": 7,
    "atividade_id": 9981,
    "data_hora_emissao": "2026-08-05T09:12:44-03:00",
    "tipo": "com_aliquota",
    "competencia": "2026-06",
    "status": "Concluído",
    "arquivo_nome": "ISS_27898481000150_2026-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

ID inexistente retorna 404 Not Found com detail: "Guia de ISS com ID {id} não encontrada!".

Escopo: iss_guias:read

PUT /iss-guias/{guia_id}

Atualiza uma guia de ISS existente. Todos os campos do corpo são opcionais - só os informados são aplicados.

Parâmetros

guia_id na rota; corpo em IssGuiaUpdate (ver IssGuiaUpdate).

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 a guia a outro cliente/usuário nem trocar a atividade de origem.

Request

{
  "status": "Falha",
  "competencia": "2026-07"
}

Response 200 OK

{
  "status": "success",
  "message": "Guia atualizada com sucesso!",
  "data": {
    "id": 4210,
    "id_cliente": 123,
    "id_usuario": 7,
    "atividade_id": 9981,
    "data_hora_emissao": "2026-08-05T09:12:44-03:00",
    "tipo": "com_aliquota",
    "competencia": "2026-07",
    "status": "Falha",
    "arquivo_nome": "ISS_27898481000150_2026-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

ID inexistente retorna 404 Not Found.

Escopo: iss_guias:write

DELETE /iss-guias/{guia_id}

Remove uma guia de ISS pelo ID.

Restrito por perfil

Além do escopo iss_guias: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": "Guia deletada com sucesso!",
  "data": null
}

ID inexistente retorna 404 Not Found.

Escopo: iss_guias:write + perfil administrador ou diretoria

GET /iss-guias/{guia_id}/pdf

Devolve o PDF binário da guia de ISS - esta é a única rota que expõe o arquivo.

Parâmetros

ParâmetroLocalTipoObrigatórioObservações
guia_idrotaintsimID da guia.

Response 200 OK

  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename="<nome ASCII>"; filename*=UTF-8''<nome real>

O nome usa arquivo_nome do registro; quando ausente, cai para iss_guia_{id}.pdf. O cabeçalho traz as duas formas (RFC 6266): filename* carrega o nome real em UTF-8 e filename= é o fallback ASCII para clientes antigos.

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 da guia 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: iss_guias:read

Ordenação

sort_by aceita apenas os valores abaixo (validados por Literal; qualquer outro retorna 422):

sort_byOrdena por
data_hora_emissaoData/hora de emissão. Default.
clienteNome do cliente (customer.razao_social), não o ID.
usuarioNome do usuário (user.nome), não o ID.
statusStatus do registro.
tipoTipo (com_aliquota / sem_aliquota).
competenciaCompetência AAAA-MM.

sort_dir aceita asc ou desc (default desc).

Schemas

IssGuiaCreate

Corpo de POST /iss-guias/.

CampoTipoObrigatórioObservações
id_clienteintsimFK do cliente.
id_usuariointsimIgnorado: sobrescrito pelo usuário autenticado.
atividade_idint | nullnãoAtividade que originou a guia. Nulo quando o registro nasce pelo CRUD.
tipo"com_aliquota" | "sem_aliquota"simValor fora do par → 422.
competenciastr (≤ 20)nãoCompetência AAAA-MM.
statusstr (≤ 50)simEx.: Concluído, Falha.
arquivo_nomestr (≤ 255)nãoNome do arquivo, usado no Content-Disposition do download.
arquivo_mimestr (≤ 100)nãoNormalmente application/pdf.
file_base64str | nullnãoPDF em base64. Só entra na escrita - nenhum schema de leitura o expõe.
data_hora_emissaodatetime | nullnãoQuando nulo, o banco resolve com o instante do INSERT.

IssGuiaUpdate

Corpo de PUT /iss-guias/{guia_id}. Todos os campos são opcionais.

CampoTipoObservações
tipo"com_aliquota" | "sem_aliquota"-
competenciastr (≤ 20)-
statusstr (≤ 50)-
file_base64strSubstitui o PDF gravado.
arquivo_nomestr (≤ 255)-
arquivo_mimestr (≤ 100)-

id_cliente, id_usuario e data_hora_emissao não fazem parte deste schema.

IssGuiaRead

data de POST, GET /{guia_id} e PUT.

CampoTipoObservações
idintID da guia.
id_clienteint-
id_usuariointAutor do registro.
atividade_idint | null-
data_hora_emissaodatetime | null-
tipostrcom_aliquota | sem_aliquota.
competenciastr | nullAAAA-MM.
statusstr-
arquivo_nomestr | null-
arquivo_mimestr | null-

Não inclui file_base64.

IssGuiaListItem

Item de items[] na listagem. Igual ao IssGuiaRead, sem arquivo_mime e sem file_base64.

PaginatedIssGuias

data de GET /iss-guias/.

CampoTipoObservações
itemsList[IssGuiaListItem]Página atual.
totalintTotal de registros que atendem aos filtros.
total_pagesint1 quando per_page é omitido.
current_pageintEcoa o page recebido.
per_pageint | nullnull quando omitido na requisição (retorno sem paginação).

Notas

  • O PDF fica em coluna MEDIUMTEXT e nunca aparece nas respostas JSON - só em GET /{guia_id}/pdf.
  • sort_by=cliente e sort_by=usuario fazem JOIN e ordenam pelo nome, que é o que o consumidor exibe.
  • Apagar a atividade que originou a guia não apaga o registro: atividade_id fica null.
  • DELETE /iss-guias/{guia_id} remove o registro por completo, incluindo o PDF gravado.
  • POST /iss-guias/ sobrescreve id_usuario com o usuário autenticado - o valor enviado no corpo é ignorado.