--- title: 10.2. Anexar Documento a Títulos url: https://docs.vehub.com.br/API/Integra%C3%A7%C3%A3o%20FIDC/10.%20Documentos%20do%20T%C3%ADtulo/10.2.%20Anexar%20Documento%20a%20T%C3%ADtulos/ --- | Método | URL | |--------|-----| | ![POST](https://img.shields.io/badge/POST-green) | `https://BASE_URL/public/v1/recebiveis/titulos/documentos` | Anexa um documento a **um ou mais títulos**, identificados pelo id, com um único upload. É a mesma regra de [Anexar Lastro Avulso por Chave](../9.%20Lastros%20Avulsos/9.3.%20Anexar%20Lastro%20Avulso%20por%20Chave.md), mas escolhendo os títulos pelo id em vez da chave do lastro — serve para títulos criados sem `lastro.chave` (CNAB, XML, tela) e para mirar um título específico entre as parcelas de uma nota. **Cada chamada acrescenta um documento.** Um título pode receber, em chamadas separadas, a nota fiscal, o contrato mestre e o termo de utilização — um não substitui o outro. Use `tipoDocumento` para dizer o que está sendo enviado. ## Request Body A requisição deve ser enviada como `multipart/form-data`. | Campo | Tipo | Obrigatório | Descrição | |-------|------|-------------|-----------| | `arquivo` | Arquivo | Sim | Arquivo a ser anexado. Um único arquivo por chamada. | | `idsTitulos` | Lista de números | Sim | Títulos que recebem o documento, **todos da mesma operação**. Repita o campo para cada título. Até **1.000** por chamada. | | `tipoDocumento` | Texto | Não | Tipo do documento, pelo nome (maiúsculas e minúsculas indiferentes). Ver a tabela abaixo. | | `tipoDocumento` | Onde o arquivo é gravado | |-----------------|--------------------------| | `NFSE`, `NFE`, `CTE`, `DuplicataMercantil` | **Documento fiscal**: no lastro principal dos títulos, que precisam compartilhar o mesmo lastro principal — e a chamada precisa trazer **todos** os títulos desse lastro (todas as parcelas da nota). Um novo envio com arquivo diferente **substitui** o anterior. | | `Contrato` (contrato mestre), `TermoUtilizacao`, `CCB`, `NC`, `Nsu` | **Documento adicional** dos títulos. Cada tipo e cada arquivo diferente viram um documento a mais. | | _(não informado)_ | No lastro principal, se todos os títulos compartilham um principal que ainda não tem arquivo; senão, como documento adicional (`Contrato`). | ```` bash title="Exemplo de cURL — contrato mestre para três títulos" curl -X POST "https://BASE_URL/public/v1/recebiveis/titulos/documentos" \ -H "Authorization: Bearer {token}" \ -H "GrupoEconomico: {grupo}" \ -F "arquivo=@/caminho/para/contrato-mestre.pdf" \ -F "idsTitulos=551203" \ -F "idsTitulos=551204" \ -F "idsTitulos=551377" \ -F "tipoDocumento=Contrato" ```` ```` json title="Response Body — 200 OK" { "status": "sucesso", "mensagem": "Documento anexado ao lastro.", "idLastro": 98231, "principal": false, "reaproveitado": false, "idsTitulos": [551203, 551204, 551377] } ```` ```` json title="Response Body — 200 OK (mesmo contrato já enviado para outro título da operação)" { "status": "sucesso", "mensagem": "Documento já existente vinculado ao título.", "idLastro": 98231, "principal": false, "reaproveitado": true, "idsTitulos": [551400] } ```` ## Erros Todos os erros retornam o envelope `RetornoPadrao`. | HTTP | Quando | |------|--------| | `409 Conflict` | O mesmo arquivo (mesmo conteúdo, qualquer nome) já está anexado a algum dos títulos. Nada é gravado. | | `404 Not Found` | Algum título não existe. A mensagem lista os ids. | | `400 Bad Request` | Nenhum arquivo, nome do arquivo vazio, nenhum título, mais de 1.000 títulos, títulos de operações diferentes, `tipoDocumento` inexistente, documento fiscal para títulos com lastros principais diferentes ou para só parte dos títulos de um lastro principal. | ```` json title="Response Body — 409 Conflict (arquivo já anexado ao título)" { "status": "erro", "mensagem": "O arquivo 'contrato-mestre.pdf' já está anexado ao(s) título(s) 551203." } ```` ```` json title="Response Body — 404 Not Found (título inexistente)" { "status": "erro", "mensagem": "Título(s) 551999 não encontrado(s)." } ```` ```` json title="Response Body — 400 Bad Request (títulos de operações diferentes)" { "status": "erro", "mensagem": "Os títulos informados pertencem a operações diferentes. Envie o documento separadamente para cada operação." } ```` ```` json title="Response Body — 400 Bad Request (nota compartilhada com títulos fora da chamada)" { "status": "erro", "mensagem": "O documento fiscal é o lastro principal compartilhado com outros títulos (551204, 551205). Inclua todos os títulos da nota na chamada ou envie pela chave do lastro." } ```` ```` json title="Response Body — 400 Bad Request (tipoDocumento inexistente)" { "status": "erro", "mensagem": "Tipo de documento inválido: 999. Valores aceitos: ..." } ```` ```` json title="Response Body — 400 Bad Request (acima do limite)" { "status": "erro", "mensagem": "Informe no máximo 1000 títulos por chamada. Repita a chamada para os demais: o mesmo arquivo é reaproveitado, sem novo upload." } ```` !!! note "Validação da requisição" Um `tipoDocumento` com nome fora da lista acima — e, na [variante base64](#variante-com-o-arquivo-em-base64), o corpo sem `nomeArquivo`, `conteudoBase64` ou `idsTitulos`, ou com `nomeArquivo` acima de 255 caracteres — é recusado antes de chegar à regra de anexo: a resposta é `400 Bad Request` no formato `ProblemDetails`, descrito em [Primeiros Passos](../1.%20In%C3%ADcio/1.1.%20Primeiros%20Passos.md). Um `tipoDocumento` enviado como **número** que não corresponde a nenhum tipo é recusado no envelope `RetornoPadrao`, com a mensagem `Tipo de documento inválido` e a lista dos valores aceitos, sem upload. ## Variante com o arquivo em base64 Para integrar sem `multipart/form-data`, envie o arquivo em base64 no corpo JSON. A regra e as respostas (200, 400, 404 e 409) são as mesmas da rota acima. | Método | URL | |--------|-----| | ![POST](https://img.shields.io/badge/POST-green) | `https://BASE_URL/public/v1/recebiveis/titulos/documentos/base64` | | Campo | Tipo | Obrigatório | Descrição | |-------|------|-------------|-----------| | `idsTitulos` | Lista de números | Sim | Títulos que recebem o documento, todos da mesma operação (até 1.000). | | `nomeArquivo` | Texto | Sim | Nome do arquivo, com a extensão (até 255 caracteres). | | `conteudoBase64` | Texto | Sim | Conteúdo do arquivo codificado em base64. | | `tipoDocumento` | Texto | Não | Mesmos valores do campo `tipoDocumento` da rota multipart. | ```` json title="Request Body — base64" { "idsTitulos": [551203, 551204], "nomeArquivo": "termo-utilizacao.pdf", "conteudoBase64": "JVBERi0xLjQKJ...", "tipoDocumento": "TermoUtilizacao" } ```` ```` json title="Response Body — 400 Bad Request (base64 inválido)" { "status": "erro", "mensagem": "O conteúdo do arquivo 'termo-utilizacao.pdf' não é um base64 válido." } ```` ```` json title="Response Body — 400 Bad Request (base64 vazio)" { "status": "erro", "mensagem": "O conteúdo do arquivo 'termo-utilizacao.pdf' está vazio." } ```` # Modelo de dados ## Retorno | Campo | Tipo | Descrição | |-------|------|-----------| | `status` | Texto | Status do processamento. | | `mensagem` | Texto | Mensagem retornada pela API. | | `idLastro` | Número | Lastro que recebeu o arquivo (documento fiscal) ou que foi vinculado aos títulos (documento adicional). | | `principal` | Booleano | `true` quando o arquivo foi gravado no lastro principal (documento fiscal). | | `reaproveitado` | Booleano | `true` quando o mesmo arquivo já existia em outro título da operação e foi apenas vinculado, sem novo upload. | | `idsTitulos` | Lista de números | Títulos que passaram a ter o documento (ids repetidos na chamada contam uma vez). | # Observações - **Tudo ou nada:** se algum título não existe, é de outra operação ou já tem o arquivo, a chamada inteira é recusada e nada é gravado. - **Nota com várias parcelas:** o documento fiscal fica no lastro principal, que é o mesmo para todas as parcelas da nota. Por isso a troca do arquivo exige todos os títulos desse lastro na chamada; a recusa lista (até 20) os que faltaram. Para não precisar dos ids, use a [rota por chave](../9.%20Lastros%20Avulsos/9.3.%20Anexar%20Lastro%20Avulso%20por%20Chave.md), que sempre alcança todas as parcelas. - **Nome do arquivo:** só o nome é usado — um caminho enviado junto é descartado (`../pasta/contrato.pdf` é gravado como `contrato.pdf`). Nome que fica vazio é recusado com `Informe o nome do arquivo, com a extensão.` - **Contrato mestre compartilhado:** o mesmo arquivo já anexado a outro título da operação não é recusado — o documento existente é vinculado aos novos títulos (`reaproveitado: true`). Isso também vale para repetir a chamada em blocos de até 1.000 títulos. - **Sem interpretação do conteúdo:** o arquivo não é parseado nem validado. Os dados da nota (número, série, valor, datas) continuam os informados na criação dos títulos. - **Envio à administradora:** os documentos adicionais seguem para a administradora apenas nas operações do canal **Envio de arquivo configurado**; acompanhe em [Listar Documentos do Título](10.1.%20Listar%20Documentos%20do%20T%C3%ADtulo.md).