DCTFWeb: Guias

Endpoints da WebApiAlcance para o registro interno das guias de DCTFWeb e PGDAS emitidas pela plataforma. Este domínio não fala com o Serpro: ele guarda, lista e serve o que já foi emitido - metadados (cliente, usuário, setor, tipo, competência, status) e o PDF da guia.

Quem emite é o domínio de Emissão, que grava aqui cada guia coletada. Registros também podem nascer pelo CRUD, fora do fluxo da automação.

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 (tag DCTFWeb: Guias).

Caminho antigo `/dctfweb-guias` continua vivo, porém deprecado

Cada rota desta página tem um alias em /api/v1/dctfweb-guias/... que serve o mesmo handler - migrar não muda requisição nem resposta. O alias exige os escopos antigos (dctfweb_guias:read / dctfweb_guias:write) e será removido numa versão futura. Mapa rota a rota em DCTFWeb: visão geral.

Base path

/api/v1/dctfweb/guias

Escopos necessários

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

O recurso vem do primeiro segmento do path (dctfweb) e a ação, do método HTTP. Tokens emitidos antes da consolidação não carregam esses escopos - relogue ou atualize a API Key antes de migrar.

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 /dctfweb/guias/

Registra uma nova guia de DCTFWeb/PGDAS. Responde 201 Created.

Parâmetros

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

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,
  "setor": "pessoal",
  "tipo": "DCTFWeb",
  "competencia": "2025-06",
  "status": "Concluído",
  "arquivo_nome": "DCTFWeb_27898481000150_2025-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": null,
    "data_hora_emissao": "2026-08-05T09:12:44-03:00",
    "setor": "pessoal",
    "tipo": "DCTFWeb",
    "competencia": "2025-06",
    "status": "Concluído",
    "arquivo_nome": "DCTFWeb_27898481000150_2025-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

O data segue DctfwebGuiaRead e nunca inclui file_base64.

Escopo: dctfweb:write

GET /dctfweb/guias/

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

Parâmetros de query

ParâmetroTipoDefaultObservações
id_clienteint-Filtra por cliente.
id_usuarioint-Filtra por usuário (autoria).
setorstr-fiscal | pessoal. Case-insensitive, ignora espaços nas pontas.
tipostr-DCTFWeb | PGDAS. Case-insensitive.
statusstr-Ex.: Concluído, Falha. Case-insensitive.
competenciastr-Competência AAAA-MM.
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/dctfweb/guias/?setor=pessoal&competencia=2025-06&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",
        "setor": "pessoal",
        "tipo": "DCTFWeb",
        "competencia": "2025-06",
        "status": "Concluído",
        "arquivo_nome": "DCTFWeb_27898481000150_2025-06.pdf"
      }
    ],
    "total": 137,
    "total_pages": 7,
    "current_page": 1,
    "per_page": 20
  }
}

Quando per_page é omitido, total_pages vale 1 e per_page vem null.

Escopo: dctfweb:read

GET /dctfweb/guias/{guia_id}

Busca uma guia pelo ID. Retorna apenas metadados (DctfwebGuiaRead), 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",
    "setor": "pessoal",
    "tipo": "DCTFWeb",
    "competencia": "2025-06",
    "status": "Concluído",
    "arquivo_nome": "DCTFWeb_27898481000150_2025-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

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

Escopo: dctfweb:read

PUT /dctfweb/guias/{guia_id}

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

Parâmetros

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

Campos deliberadamente não editáveis

id_cliente, id_usuario e data_hora_emissao não existem no corpo de atualização. O PUT não pode reatribuir a guia a outro cliente/usuário nem reescrever a data de emissão.

Request

{
  "status": "Falha",
  "competencia": "2025-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",
    "setor": "pessoal",
    "tipo": "DCTFWeb",
    "competencia": "2025-07",
    "status": "Falha",
    "arquivo_nome": "DCTFWeb_27898481000150_2025-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

ID inexistente retorna 404.

Escopo: dctfweb:write

DELETE /dctfweb/guias/{guia_id}

Remove uma guia pelo ID.

Restrito por perfil

Além do escopo dctfweb:write, esta rota exige perfil administrador ou diretoria. Um token com o escopo correto mas perfil operacional é recusado.

Response 200 OK

{
  "status": "success",
  "message": "Guia deletada com sucesso!",
  "data": null
}

ID inexistente retorna 404.

Escopo: dctfweb:write + perfil administrador ou diretoria

GET /dctfweb/guias/{guia_id}/pdf

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

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 dctfweb_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 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: dctfweb: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.
setorSetor (fiscal / pessoal).
tipoTipo (DCTFWeb / PGDAS).
competenciaCompetência AAAA-MM.

sort_dir aceita asc ou desc (default desc). O desempate é sempre por id, na mesma direção do sort primário - as guias de um mesmo lote compartilham o mesmo data_hora_emissao, e sem o desempate a paginação repetiria ou pularia registros entre páginas.

Schemas

DctfwebGuiaCreate

Corpo de POST /dctfweb/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.
setor"fiscal" | "pessoal"simValor fora do par → 422.
tipo"DCTFWeb" | "PGDAS"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.

DctfwebGuiaUpdate

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

CampoTipoObservações
setor"fiscal" | "pessoal"-
tipo"DCTFWeb" | "PGDAS"-
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.

DctfwebGuiaRead

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-
setorstrfiscal | pessoal.
tipostrDCTFWeb | PGDAS.
competenciastr | nullAAAA-MM.
statusstr-
arquivo_nomestr | null-
arquivo_mimestr | null-

Não inclui file_base64.

DctfwebGuiaListItem

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

PaginatedDctfwebGuias

data de GET /dctfweb/guias/.

CampoTipoObservações
itemsList[DctfwebGuiaListItem]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 (até 16 MB) e nunca aparece nas respostas JSON - só em GET /{guia_id}/pdf.
  • Os filtros setor, tipo e status comparam em maiúsculas e sem espaços nas pontas, dos dois lados.
  • 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 a guia: atividade_id fica null (o PDF pode ser a única cópia do artefato).
  • Alias deprecado equivalente: /api/v1/dctfweb-guias/... (escopos dctfweb_guias:read / dctfweb_guias:write).