Vincular Comprovante ou Nota Fiscal
Cria um registro de anexo vinculado a uma transação e retorna uma URL pré-assinada para upload direto ao S3.
Fluxo de 2 etapas:
- Chame este endpoint com os metadados do arquivo e o ID da transação — retorna o
iddo anexo e auploadUrl. - Faça um
PUTpara auploadUrlcom o binário do arquivo diretamente ao S3 (sem passar pela API), enviando o headerContent-Typedo formato do arquivo.
O id retornado pode ser usado no Download de Anexo após o upload concluir.
Formato do arquivo: o file.name precisa terminar com uma extensão aceita para o file.contentType, sem diferenciar maiúsculas de minúsculas. Se não terminar, a resposta é 400. No PUT, envie o Content-Type indicado para o formato; com outro valor, o S3 recusa o upload com 403 (SignatureDoesNotMatch).
PDF: extensão.pdf,Content-Type: application/pdfPNG: extensão.png,Content-Type: image/pngJPEGouJPG: extensão.jpegou.jpg,Content-Type: image/jpegXLS: extensão.xls,Content-Type: application/vnd.ms-excelXLSX: extensão.xlsx,Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheetODF: extensão.odfou.odt,Content-Type: application/vnd.oasis.opendocument.textOFX: extensão.ofx,Content-Type: application/x-ofx
Idempotência: este endpoint não suporta o header Idempotency-Key. Cada chamada cria um novo registro de anexo — uma transação pode ter múltiplos anexos vinculados.
curl -X POST "https://api-sandbox.contasimples.com/attachments/v1/attachments" \
-H "Content-Type: application/json" \
-H "Signature-Input: example_string" \
-H "Signature: example_string" \
-H "Content-Digest: example_string" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"transactionId": "111304",
"file": {
"name": "nota-fiscal.pdf",
"contentType": "PDF"
},
"description": "Nota fiscal referente à compra"
}'
import requests
import json
url = "https://api-sandbox.contasimples.com/attachments/v1/attachments"
headers = {
"Content-Type": "application/json",
"Signature-Input": "example_string",
"Signature": "example_string",
"Content-Digest": "example_string",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"transactionId": "111304",
"file": {
"name": "nota-fiscal.pdf",
"contentType": "PDF"
},
"description": "Nota fiscal referente à compra"
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://api-sandbox.contasimples.com/attachments/v1/attachments", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Signature-Input": "example_string",
"Signature": "example_string",
"Content-Digest": "example_string",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"transactionId": "111304",
"file": {
"name": "nota-fiscal.pdf",
"contentType": "PDF"
},
"description": "Nota fiscal referente à compra"
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"transactionId": "111304",
"file": {
"name": "nota-fiscal.pdf",
"contentType": "PDF"
},
"description": "Nota fiscal referente à compra"
}`)
req, err := http.NewRequest("POST", "https://api-sandbox.contasimples.com/attachments/v1/attachments", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Signature-Input", "example_string")
req.Header.Set("Signature", "example_string")
req.Header.Set("Content-Digest", "example_string")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://api-sandbox.contasimples.com/attachments/v1/attachments')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Signature-Input'] = 'example_string'
request['Signature'] = 'example_string'
request['Content-Digest'] = 'example_string'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"transactionId": "111304",
"file": {
"name": "nota-fiscal.pdf",
"contentType": "PDF"
},
"description": "Nota fiscal referente à compra"
}'
response = http.request(request)
puts response.body
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "PROCESSING",
"referenceId": "111304",
"file": {
"name": "nota-fiscal.pdf",
"contentType": "PDF"
},
"description": "Nota fiscal referente à compra",
"createdAt": "2026-06-25T22:54:52.000Z",
"uploadUrl": "https://s3.amazonaws.com/bucket/key?X-Amz-Signature=..."
}
{
"error": "Bad Request",
"message": "Um ou mais parâmetros da requisição são inválidos.",
"code": 400,
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"details": [
"O campo exemplo deve ter um valor entre 5 e 100.",
"datas devem estar no formato YYYY-MM-DD."
]
}
{
"error": "Unauthorized",
"message": "Authentication failed. Check the API token and the request signature",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 401
}
{
"error": "Forbidden",
"message": "The request is not allowed for the current credentials",
"code": 403,
"details": {
"requiredScope": "listCategories"
},
"requestId": "123e4567-e89b-12d3-a456-426614174000"
}
{
"error": "Internal Server Error",
"message": "Ocorreu um erro inesperado ao processar a solicitação.",
"requestId": "123e4567-e89b-12d3-a456-426614174000",
"code": 500
}
/attachments/v1/attachments
Target server for requests. Edit to use your own host.
Token Bearer obtido via OAuth 2.0 Client Credentials. Formato: Bearer TOKEN
Bearer TOKENThe media type of the request body
O que foi assinado e os parâmetros da assinatura, no formato da RFC 9421. Uma credencial com chave pública precisa enviar este header em todas as chamadas, inclusive as de leitura, ou a requisição é recusada com 401. A assinatura cobre os componentes @method, @path e @query, e também content-digest quando houver corpo. created e alg são obrigatórios, e o created vale por 300 segundos. O formato completo, com exemplos, está em Assinatura de Requisições.
A assinatura da base definida pela RFC 9421, em base64, entre : e com o mesmo rótulo usado no Signature-Input, por exemplo sig=:SGVsbG8gd29ybGQ=:. Vai sempre junto com o Signature-Input.
Hash do corpo da requisição no formato da RFC 9530, com sha-256 ou sha-512, por exemplo sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:. É obrigatório quando a requisição tem corpo e a credencial tem chave pública, e nesse caso o Signature-Input precisa incluir o componente content-digest.
ID da transação à qual o documento será vinculado. Corresponde ao campo id retornado pelo Extrato Bancário (numérico — envie o valor como string) ou pelo Extrato de Cartão (ULID).
Descrição do documento (opcional).
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Token Bearer obtido via OAuth 2.0 Client Credentials. Formato: Bearer TOKEN
Headers
O que foi assinado e os parâmetros da assinatura, no formato da RFC 9421. Uma credencial com chave pública precisa enviar este header em todas as chamadas, inclusive as de leitura, ou a requisição é recusada com 401. A assinatura cobre os componentes @method, @path e @query, e também content-digest quando houver corpo. created e alg são obrigatórios, e o created vale por 300 segundos. O formato completo, com exemplos, está em Assinatura de Requisições.
A assinatura da base definida pela RFC 9421, em base64, entre : e com o mesmo rótulo usado no Signature-Input, por exemplo sig=:SGVsbG8gd29ybGQ=:. Vai sempre junto com o Signature-Input.
Hash do corpo da requisição no formato da RFC 9530, com sha-256 ou sha-512, por exemplo sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:. É obrigatório quando a requisição tem corpo e a credencial tem chave pública, e nesse caso o Signature-Input precisa incluir o componente content-digest.
Body
ID da transação à qual o documento será vinculado. Corresponde ao campo id retornado pelo Extrato Bancário (numérico — envie o valor como string) ou pelo Extrato de Cartão (ULID).
111304