DCTFWeb: Recibos

Endpoints da WebApiAlcance para o registro interno dos recibos de transmissão da DCTFWeb. Como o domínio de Guias, este não fala com o Serpro: guarda, lista e serve o que já foi coletado - metadados (cliente, usuário, tipo, competência, status) e o PDF do recibo.

Quem coleta é o domínio de Emissão, que grava aqui cada recibo obtido. 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: Recibos).

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

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

Base path

/api/v1/dctfweb/recibos

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/recibos/

Registra um novo recibo de DCTFWeb. Responde 201 Created.

Parâmetros

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

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,
  "tipo": "DCTFWeb",
  "competencia": "2025-06",
  "status": "Concluído",
  "arquivo_nome": "RECIBO_DCTFWeb_27898481000150_2025-06.pdf",
  "arquivo_mime": "application/pdf",
  "file_base64": "JVBERi0xLjQK..."
}

Response 201 Created

{
  "status": "success",
  "message": "Recibo registrado com sucesso!",
  "data": {
    "id": 2087,
    "id_cliente": 123,
    "id_usuario": 7,
    "atividade_id": null,
    "data_hora_emissao": "2026-08-05T09:12:44-03:00",
    "tipo": "DCTFWeb",
    "competencia": "2025-06",
    "status": "Concluído",
    "arquivo_nome": "RECIBO_DCTFWeb_27898481000150_2025-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

O data segue DctfwebReciboRead e nunca inclui file_base64.

Escopo: dctfweb:write

GET /dctfweb/recibos/

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

Parâmetros de query

ParâmetroTipoDefaultObservações
id_clienteint-Filtra por cliente.
id_usuarioint-Filtra por usuário (autoria).
tipostr-DCTFWeb | PGDAS. Case-insensitive, ignora espaços nas pontas.
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).

Não há filtro por setor aqui - diferente de Guias, o registro de recibo não tem essa coluna.

Request

GET /api/v1/dctfweb/recibos/?competencia=2025-06&status=Conclu%C3%ADdo&page=1&per_page=20

Response 200 OK

{
  "status": "success",
  "message": "Recibos recuperados com sucesso!",
  "data": {
    "items": [
      {
        "id": 2087,
        "id_cliente": 123,
        "id_usuario": 7,
        "atividade_id": 9981,
        "data_hora_emissao": "2026-08-05T09:12:44-03:00",
        "tipo": "DCTFWeb",
        "competencia": "2025-06",
        "status": "Concluído",
        "arquivo_nome": "RECIBO_DCTFWeb_27898481000150_2025-06.pdf"
      }
    ],
    "total": 58,
    "total_pages": 3,
    "current_page": 1,
    "per_page": 20
  }
}

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

Escopo: dctfweb:read

GET /dctfweb/recibos/{recibo_id}

Busca um recibo pelo ID. Retorna apenas metadados (DctfwebReciboRead), sem file_base64.

Parâmetros

ParâmetroLocalTipoObrigatórioObservações
recibo_idrotaintsimID do recibo.

Response 200 OK

{
  "status": "success",
  "message": "Recibo encontrado com sucesso!",
  "data": {
    "id": 2087,
    "id_cliente": 123,
    "id_usuario": 7,
    "atividade_id": 9981,
    "data_hora_emissao": "2026-08-05T09:12:44-03:00",
    "tipo": "DCTFWeb",
    "competencia": "2025-06",
    "status": "Concluído",
    "arquivo_nome": "RECIBO_DCTFWeb_27898481000150_2025-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

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

Escopo: dctfweb:read

PUT /dctfweb/recibos/{recibo_id}

Atualiza um recibo. Todos os campos do corpo são opcionais - só os informados são aplicados.

Parâmetros

recibo_id na rota; corpo em DctfwebReciboUpdate (ver DctfwebReciboUpdate).

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 o recibo a outro cliente/usuário nem reescrever a data de emissão.

Request

{
  "status": "Falha"
}

Response 200 OK

{
  "status": "success",
  "message": "Recibo atualizado com sucesso!",
  "data": {
    "id": 2087,
    "id_cliente": 123,
    "id_usuario": 7,
    "atividade_id": 9981,
    "data_hora_emissao": "2026-08-05T09:12:44-03:00",
    "tipo": "DCTFWeb",
    "competencia": "2025-06",
    "status": "Falha",
    "arquivo_nome": "RECIBO_DCTFWeb_27898481000150_2025-06.pdf",
    "arquivo_mime": "application/pdf"
  }
}

ID inexistente retorna 404.

Escopo: dctfweb:write

DELETE /dctfweb/recibos/{recibo_id}

Remove um recibo 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": "Recibo deletado com sucesso!",
  "data": null
}

ID inexistente retorna 404.

Escopo: dctfweb:write + perfil administrador ou diretoria

GET /dctfweb/recibos/{recibo_id}/pdf

Devolve o PDF binário do recibo - 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_recibo_{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 do recibo 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.
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 - os recibos 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

DctfwebReciboCreate

Corpo de POST /dctfweb/recibos/.

CampoTipoObrigatórioObservações
id_clienteintsimFK do cliente.
id_usuariointsimIgnorado: sobrescrito pelo usuário autenticado.
atividade_idint | nullnãoAtividade que originou o recibo. Nulo quando o registro nasce pelo CRUD.
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.

DctfwebReciboUpdate

Corpo de PUT /dctfweb/recibos/{recibo_id}. Todos os campos são opcionais.

CampoTipoObservações
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.

DctfwebReciboRead

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

CampoTipoObservações
idintID do recibo.
id_clienteint-
id_usuariointAutor do registro.
atividade_idint | null-
data_hora_emissaodatetime | null-
tipostrDCTFWeb | PGDAS.
competenciastr | nullAAAA-MM.
statusstr-
arquivo_nomestr | null-
arquivo_mimestr | null-

Não inclui file_base64.

DctfwebReciboListItem

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

PaginatedDctfwebRecibos

data de GET /dctfweb/recibos/.

CampoTipoObservações
itemsList[DctfwebReciboListItem]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 tipo aceita DCTFWeb e PGDAS, mas na prática hoje só chegam recibos DCTFWeb: a coleta de PGDAS-D está inativa no fluxo de emissão. A coluna existe para paridade com Guias.
  • O PDF fica em coluna MEDIUMTEXT (até 16 MB) e nunca aparece nas respostas JSON - só em GET /{recibo_id}/pdf.
  • Os filtros tipo e status comparam em maiúsculas e sem espaços nas pontas, dos dois lados.
  • Apagar a atividade que originou o recibo não apaga o recibo: atividade_id fica null.
  • Alias deprecado equivalente: /api/v1/dctfweb-recibos/... (escopos dctfweb_recibos:read / dctfweb_recibos:write).