Consolidated expense documents
Attach supporting documents (invoice, calculation memo, contract, bankslip) to an expense of the fund class and query the documents already attached. The expense_key comes from the consolidated expense query.
The file is sent in two steps: the API registers the document and returns an upload URL; then you send the file directly to that URL.
Attach a document
| Profile | Host | Required permission |
|---|---|---|
| Manager | manager-api | Write |
Base URL for each host: Environments (Hosts).
Path params
| Parameter | Type | Description |
|---|---|---|
fund_class_key | string | Fund class key (UUID). |
expense_key | string | Expense key (UUID). |
Body attributes
| Field | Type | Required | Description |
|---|---|---|---|
name | string | required | Document name. Maximum of 255 characters. |
document_type | string | required | invoice (invoice), calculation_memory (calculation memo), contract (contract) or bank_slip (bankslip). |
No other field is accepted.
{
"name": "NF-e 001234 - Auditoria jun/2026",
"document_type": "invoice"
}
Response
{
"name": "NF-e 001234 - Auditoria jun/2026",
"document_key": "d4e5f6a7-b8c9-0123-def4-567890abcdef",
"expense_key": "3571e292-3a83-4011-904d-20ee963022ef",
"document_type": "invoice",
"upload_url": {
"url": "https://<link-temporario-de-envio>",
"fields": {
"key": "d4e5f6a7-b8c9-0123-def4-567890abcdef",
"policy": "<policy>",
"x-amz-algorithm": "AWS4-HMAC-SHA256",
"x-amz-credential": "<credential>",
"x-amz-date": "20260701T120000Z",
"x-amz-signature": "<signature>"
}
}
}
| Field | Type | Description |
|---|---|---|
document_key | string | Document key (UUID). Use it to query the document later. |
expense_key | string | Key of the expense the document belongs to. |
upload_url.url | string | Address to which the file must be sent. |
upload_url.fields | object | Fields that must accompany the file. Send all of them, without changing names or values; the exact set of fields may vary. |
File upload
Make a multipart/form-data POST to upload_url.url, with all the fields of upload_url.fields and the file in the file field (the last one in the form). The URL expires in 10 minutes and accepts files of up to 50 MB. This call goes straight to storage: it does not carry QI Tech authentication headers.
import requests
upload = response_body["upload_url"]
with open("nfe_001234.pdf", "rb") as arquivo:
resposta = requests.post(
upload["url"],
data=upload["fields"],
files={"file": arquivo},
)
resposta.raise_for_status() # 204 indica upload concluído
If the URL expires before the upload, attach the document again to receive a new URL.
List the documents of an expense
An expense_key that does not exist in the fund class returns an empty data, not 404.
| Profile | Host | Required permission |
|---|---|---|
| Manager | manager-api | Read |
Base URL for each host: Environments (Hosts).
The listing is not paginated and does not include the download URL; to download a file, query the document by its key.
{
"data": [
{
"name": "NF-e 001234 - Auditoria jun/2026",
"document_key": "d4e5f6a7-b8c9-0123-def4-567890abcdef",
"expense_key": "3571e292-3a83-4011-904d-20ee963022ef",
"document_type": "invoice"
}
]
}
Query a document by key
| Profile | Host | Required permission |
|---|---|---|
| Manager | manager-api | Read |
Base URL for each host: Environments (Hosts).
{
"name": "NF-e 001234 - Auditoria jun/2026",
"document_key": "d4e5f6a7-b8c9-0123-def4-567890abcdef",
"expense_key": "3571e292-3a83-4011-904d-20ee963022ef",
"document_type": "invoice",
"document_url": "https://<link-temporario-de-download>"
}
| Field | Type | Description |
|---|---|---|
document_url | string | Pre-signed URL to download the file, valid for 24 hours. Query the document again to get a new one. |
Errors
| Status | Code | When it happens |
|---|---|---|
| 400 | EXP000069 | The fund class does not belong to the manager of your API key. |
| 400 | QIT000001 | Invalid body: name or document_type is missing, document_type is not in the list, or an unexpected field was sent. |
| 404 | EXP000072 | The expense is canceled (canceled) and does not accept new documents. |
| 404 | EXP000071 | The document_key does not exist for this expense. |
| 500 | QIT000500 | Attach document: the expense_key does not exist in this fund class. Check the key in the expense query. |
Authentication, permission and host errors: see API Errors.