The four required objects
Every Daylit SFTP integration must send the four required objects below. They are the minimum needed for open AR, collections workflows, and customer-level reporting. Payment is optional — send it for per-payment-event tracking (see Payment).
Daylit accepts additional objects beyond these four without breaking your integration.
How to use this schema
1
Start with the required objects
Prepare Customer, Customer Contact, Invoice, and Credit Note files first. Add Payment only if you want separate per-payment-event tracking.
2
Match each source export to an object
Use the object sections below to identify which source columns map to Daylit’s canonical fields. Keep your source column names as-is; you will map them in Daylit.
3
Map columns in Daylit
In Settings → SFTP Connection, upload a sample file for each object and map your source columns to the canonical fields in this guide.
4
Use sample CSVs as a reference
Compare your exports with the sample CSV files to confirm file shape, IDs, dates, and foreign keys.
5
Validate sample files
Upload sample files to
/sample/{object}/ and confirm validation passes before sending a full /init/ snapshot.File format
Where to put files (SFTP paths)
After provisioning, your SFTP user sees top-level directories for each upload phase. Place files in the matching object subfolder within each phase.Upload paths
Per-object directory structure
- If a daily delta has nothing to send for an object, skip that object. Daylit won’t penalize an empty interval. Daylit warns if a normally active object goes silent for more than 1.5× its usual cadence.
- Send one file per object per push. For large inits, use a single
.csv.gzrather than splitting into parts.
Upload order for init
Push parents before children so foreign keys resolve immediately:customerfirstcustomer_contact(references Customer)invoice(references Customer)credit_note(references Customer)payment(optional; references Invoice)
Canonical schema per object
Every object has a canonical schema — the field names and types Daylit expects after your mapping is applied. You don’t rename columns in your source system; you map them in the portal under Settings → SFTP Connection. Schemas are versioned. Schemas below are v1.Conventions used in every object
Customer
One row per customer. Daylit upserts onremote_id — a repeated remote_id updates the existing customer, a new one inserts. Upload to /init/customer/ and /delta/customer/. Customer is the parent record, so make sure to upload Customers before any other object.
Customer Contact
One row per contact; a customer can have zero, one, or many. Daylit upserts onremote_id. Upload to /init/customer_contact/ and /delta/customer_contact/, after the customers they reference via customer_remote_id.
Invoice
One row per invoice. Payment summary fields (paid_amount, paid_on_date, balance) are embedded on the invoice row, not sent as a separate object. Daylit upserts on remote_id. Upload to /init/invoice/ and /delta/invoice/, after the customers they reference via customer_remote_id.
Allowed
status values:
Credit Note
One row per credit note — refunds, returns, and credit memos issued to customers. Daylit upserts onremote_id. Upload to /init/credit_note/ and /delta/credit_note/, after the customers they reference via customer_remote_id.
Allowed
status values:
Payment
Daylit ingests payments as one row per invoice allocation. A single payment applied across several invoices is sent as multiple rows that share the sameremote_id, each pointing at a different invoice_remote_id with its own applied_amount. Upload to /init/payment/ and /delta/payment/, after the invoices they reference.
Sample CSV files
Example exports showing what each object looks like as a CSV — typical column names from a source system, not the canonical Daylit field names. Use them to understand the shape of each table, as a starting point for your own exports, or to map columns under Settings → SFTP Connection. See the canonical schema above for the fields Daylit expects after mapping. For full sample data across all five objects, open the Sample CSV spreadsheet — one tab per object. Use File → Download in Google Sheets to export as CSV.Customer — customers_sample.csv
Customer — customers_sample.csv
customers_sample.csv
Customer Contact — contacts_sample.csv
Customer Contact — contacts_sample.csv
contacts_sample.csv
Invoice — invoices_sample.csv
Invoice — invoices_sample.csv
invoices_sample.csv
Credit Note — credit_notes_sample.csv
Credit Note — credit_notes_sample.csv
credit_notes_sample.csv
Payment — payments_sample.csv
Payment — payments_sample.csv
payments_sample.csv
Foreign keys and object relationships
Rules:CustomerContact.customer_remote_idmust match an existingCustomer.remote_id.Invoice.customer_remote_idmust match an existingCustomer.remote_id.CreditNote.customer_remote_idmust match an existingCustomer.remote_id.Payment.invoice_remote_idmust match an existingInvoice.remote_id.- Foreign keys resolve at the end of each batch. If a child file arrives before its parent, Daylit holds it for up to 24 hours, then quarantines it with an FK-unresolved error.
Validation rules summary
A file passes validation when all of the following hold: Structure- Path is
/{phase}/{object}/{filename}with recognized phase and object values. - Filename matches
{object}_{phase}_{date}. - File parses cleanly: correct encoding, header row present, no truncated rows.
- Every required field is non-empty.
- Every cell satisfies its declared type.
remote_idis non-empty.
remote_idis unique within the file.- For
init: row count is between 1 and 10× the largest sample ever sent for this object. - For
delta:remote_updated_atperremote_idis monotonically increasing.
- Every
*_remote_idforeign key resolves to a known parent record.
Worked example: ACME Corporation’s first init
ACME Corporation exports all five objects and uploads in order:/delta/{object}/ and Daylit stays current.
Need help?
- Portal in-app chat — bottom-right on every page.
- Email: support@daylit.com. Include your workspace name and the filename you’re asking about.
- Status page: status.daylit.com for any active incidents.