Upload document to the inbox
POST
/v1/attachmentsUploads a document (PDF, PNG, JPG, or JPEG; max 10MB) without a journal entry, so it waits in the inbox. Put it on a draft later with attachment_id on PUT /v1/journal-entries/{id}. Numina reads it only with run_ocr "true", and the bookkeeping agent does not run on it. Uploading a file the company already has returns the existing document with 200 and duplicate: true.
Requires one ofdocuments:writewrite:draftwrite:ledger
Body
multipart/form-data
- File to upload (PDF, PNG, JPG, or JPEG; max 10MB). Its content must match its declared type.
- run_ocrstringIf "true", Numina reads the file (OCR) so the document becomes searchable. Defaults to "false".One of
truefalse
Errors
400The upload is missing, too large, or not a valid file401Invalid or missing authentication403Missing scope, or the company is archived429Rate limit exceeded500Internal Server Error
Every error has the same shape. See Errors.
curl -X POST https://api.numina.app/v1/attachments \
-H "Authorization: Bearer numi_YOUR_API_KEY" \
-F file=@receipt.pdfimport { openAsBlob } from "node:fs";
const form = new FormData();
form.append("file", await openAsBlob("receipt.pdf"), "receipt.pdf");
const response = await fetch("https://api.numina.app/v1/attachments", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NUMINA_API_KEY}`,
},
body: form,
});
const data = await response.json();import os
import requests
response = requests.post(
"https://api.numina.app/v1/attachments",
headers={
"Authorization": f"Bearer {os.environ['NUMINA_API_KEY']}",
},
files={"file": open("receipt.pdf", "rb")},
)
data = response.json()Response
{
"attachment": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"file_name": "string",
"status": "uploaded",
"created_at": "string",
"attachment_number": 185,
"year": "2026",
"is_empty": false,
"file_count": 0,
"booked_accounting_year": "2026",
"content_sha256": "string",
"journal_entry_ids": [
"550e8400-e29b-41d4-a716-446655440000"
]
},
"duplicate": false
}{
"attachment": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"file_name": "string",
"status": "uploaded",
"created_at": "string",
"attachment_number": 185,
"year": "2026",
"is_empty": false,
"file_count": 0,
"booked_accounting_year": "2026",
"content_sha256": "string",
"journal_entry_ids": [
"550e8400-e29b-41d4-a716-446655440000"
]
},
"duplicate": false
}