File Uploads
DayZero uses S3-backed file storage for bill attachments, bank statements, CSV/Excel imports, and other documents. Uploading is a two-step pattern: put the file in storage to get an s3_key, then pass that key to the endpoint that consumes it.
The
/api/v1/upload/*endpoints work with an API token but are not listed in the public API Reference. The endpoints that consume ans3_key(bills, bulk uploads, reconciliations, reports…) are all public and documented there.
Presigned Upload (Recommended)
Get a presigned upload URL, then upload the file directly to S3 from the client:
Step 1: Request a presigned URL
curl -X POST "https://api.ondayzero.com/api/v1/upload" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-H "Content-Type: application/json" \
-d '{"filename": "receipt.pdf"}'Returns s3_upload_url (a presigned S3 PUT URL, valid for one hour), the s3_key to reference the file with, and the content_type DayZero inferred from the filename. Supported extensions: pdf, csv, xls, xlsx, doc, docx, md, and common image formats (png, jpg, jpeg, gif, webp, heic, heif, bmp, tiff, avif); anything else is rejected with 400.
Step 2: Upload to S3
curl -X PUT "{s3_upload_url}" \
-H "Content-Type: application/pdf" \
--data-binary @receipt.pdfSend the same Content-Type the presign response returned — S3 rejects the upload if it differs.
Step 3: Use the s3_key
Pass the s3_key to whichever endpoint consumes it. Common ones:
| Use | Endpoint and field |
|---|---|
| Attach a document to a bill | s3_key on POST /api/v1/bills, POST /api/v1/bills/received, PUT /api/v1/bills/{bill_id} — see Bills |
| Create bills / invoices from PDFs with AI | single_bill_s3_keys / multi_bill_s3_key on POST /api/v1/bills/ai-create; single_invoice_s3_keys / multi_invoice_s3_key on POST /api/v1/invoices/ai-create |
| Import bank transactions from CSV/Excel | s3_key on POST /api/v1/transactions/bulk-upload/headers → /preview → /bulk-upload — see Transactions |
| Bulk-import invoices, bills or journal entries | s3_key on POST /api/v1/invoices/bulk, POST /api/v1/bills/bulk, POST /api/v1/journal-entries/bulk-upload/preview and /post |
| Upload a bank statement for reconciliation | statement_s3_key on POST /api/v1/reconciliations — see Reconciliation |
| Feed a spreadsheet to a report | file_s3_key / s3_keys on POST /api/v1/reports — see Reports |
| Vendor contracts and note attachments | s3_key on POST /api/v1/vendor-contracts, POST /api/v1/notes/{note_id}/attachments |
Direct Upload
Upload a file through the API in one call (simpler, but the bytes transit DayZero's servers, so prefer presigned URLs for large files):
curl -X POST "https://api.ondayzero.com/api/v1/upload/direct" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-F "file=@receipt.pdf"Returns the s3_key, filename and file_size. Oversized files are rejected with 413.
Some workflows have their own multipart shortcut that uploads and processes in one request, e.g. POST /api/v1/bills/upload (bill document) and POST /api/v1/reconciliations/upload (bank statement).
Download a File
Get a presigned download URL:
curl "https://api.ondayzero.com/api/v1/upload/download?s3_key=path/to/file.pdf" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Returns download_url, a time-limited S3 link that needs no DayZero headers. Or stream the file through the API (avoids CORS issues with presigned URLs in browsers):
curl "https://api.ondayzero.com/api/v1/upload/stream?s3_key=path/to/file.pdf&filename=receipt.pdf" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID" \
-o downloaded-file.pdffilename is optional and sets the download's Content-Disposition name. Only keys belonging to the business in x-business-id can be downloaded.
List Uploaded Files
curl "https://api.ondayzero.com/api/v1/upload/files" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"Returns items of {id, name, s3_key, type, source, created_at}. Filter with ?source=user_upload or ?source=ai_generated to separate files you uploaded from ones DayZero generated.
CSV Templates
Download templates for bulk imports. GET /api/v1/upload/templates lists the names — currently rec-txns (bank transactions), bulk-invoice-upload, bulk-bill-upload and bulk-journal-entries:
curl "https://api.ondayzero.com/api/v1/upload/templates/bulk-invoice-upload" \
-H "Authorization: Bearer dz_your_token_here" \
-H "x-business-id: YOUR_BUSINESS_ID"The response carries the template as csv_content_stringified (plain CSV text), csv_content_object (rows as JSON) and csv_content_base64; the journal-entries template is also returned as xls_content_base64, pre-filled with the business's own ledger names.