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).| Object | What it is | Example filename | Required |
|---|---|---|---|
| Customer | Companies or individuals you bill | customers_*.csv | ✓ |
| Customer Contact | AP, billing, and primary contacts | contacts_*.csv | ✓ |
| Invoice | Every invoice with embedded payment info (paid amount, paid-on date, balance, due date) | invoices_*.csv | ✓ |
| Credit Note | Refunds, returns, and applied or unapplied credits | credit_notes_*.csv | ✓ |
| Payment | Individual payment events — one row per invoice allocation | payments_*.csv | Optional |
File format
| Setting | Value |
|---|---|
| Format | CSV |
| Encoding | UTF-8 (no BOM) |
| Delimiter (CSV) | Comma , |
| Quote character | Double quote ", escape by doubling: "" (RFC 4180) |
| Line endings | \n (LF) or \r\n (CRLF) |
| Header row | Required on every file |
| Dates | YYYY-MM-DD (default). Other patterns (MM-DD-YYYY, MM/DD/YYYY, and more) are selectable per field in the mapping UI. |
| Datetimes | ISO 8601 UTC — YYYY-MM-DDTHH:MM:SSZ (default). MySQL TIMESTAMP, IBM SQL, and other patterns are selectable per field; timezone-naive values are assumed UTC. |
| Decimals | Dot separator — 1234.56. Currency symbols and thousands separators are stripped automatically; accounting-style negatives ((1234.56)) become -1234.56. |
| Booleans | true/false, yes/no, or 1/0 |
| Nulls | Empty string |
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
| Path | Purpose |
|---|---|
/test/ | Connectivity check — no business validation |
/sample/ | Small file (≤ 100 rows) to validate your mapping |
/init/ | Full snapshot of every record in an object |
/delta/ | Incremental updates since your last successful upload |
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 on Settings -> SFTP connection. Schemas are versioned. Schemas below are v1.Conventions used in every object
| Field | Purpose |
|---|---|
remote_id | The record’s identifier in your source system. Required on every row. Daylit upserts on this value. |
remote_updated_at | ISO 8601 UTC timestamp of the last modification in your source system. Must increase monotonically per remote_id. |
*_remote_id | Foreign key to another object’s remote_id (for example, customer_remote_id on an invoice). |
status | Normalized lifecycle state. Allowed values are listed per 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.
| Field | Type | Required | Notes |
|---|---|---|---|
remote_id | string | ✓ | Unique per customer in your source system |
customer_company_name | string | ✓ | Legal/billing entity name |
remote_updated_at | datetime | ✓ | Source-system last-modified timestamp. Drives incremental sync. |
address_line1 | string | optional | |
address_line2 | string | optional | |
address_city | string | optional | |
address_state | string | optional | 2-letter US state or ISO 3166-2 subdivision |
address_zipcode | string | optional | |
address_country | string | optional | ISO 3166-1 alpha-2 (US, GB, IN). Can be set to a static value if all customers share one country. |
default_payment_terms | string | optional | Net-N days, e.g. 30 for Net 30 |
credit_limit | decimal | optional |
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.
| Field | Type | Required | Notes |
|---|---|---|---|
remote_id | string | ✓ | Unique per contact |
customer_remote_id | string | ✓ | FK to Customer.remote_id |
email | string | ✓ | Primary email for this contact |
first_name | string | optional | |
last_name | string | optional | |
phone | string | optional | E.164 preferred |
title | string | optional | Job title, e.g. Accounts Payable Manager |
department | string | optional | e.g. Finance, Accounting |
is_primary | boolean | optional | true if this is the customer’s main contact. Defaults to false. |
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.
| Field | Type | Required | Notes |
|---|---|---|---|
remote_id | string | ✓ | Unique per invoice |
customer_remote_id | string | ✓ | FK to Customer.remote_id |
remote_updated_at | datetime (ISO 8601 UTC) | ✓ | |
number | string | ✓ | Human-readable invoice number |
issue_date | date | ✓ | Date the invoice was issued |
due_date | date | ✓ | Date the invoice is due |
total_amount | decimal | ✓ | Grand total, including taxes and fees |
paid_amount | decimal | ✓ | Cumulative amount paid. 0 if unpaid |
balance | decimal | ✓ | Send explicitly — don’t make Daylit calculate it |
paid_on_date | date | optional | Date the invoice was fully paid. Empty if not fully paid. |
currency | string | ✓ | ISO 4217 |
status | enum | ✓ | See allowed values below |
memo | string | optional |
status values:
| Value | Meaning |
|---|---|
DRAFT | Not finalized or sent; excluded from AR totals |
SUBMITTED | Issued to the customer; payment still expected |
OPEN | Outstanding, amount still due |
PARTIALLY_PAID | Some payment received, balance > 0 |
PAID | Fully paid, balance = 0 |
VOID | Cancelled or invalidated; excluded from AR totals |
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.
| Field | Type | Required | Notes |
|---|---|---|---|
remote_id | string | ✓ | Unique per credit note |
customer_remote_id | string | ✓ | FK to Customer.remote_id |
total_amount | decimal | ✓ | Always positive — Daylit treats it as a credit |
remote_updated_at | datetime | optional | Source-system last-modified timestamp |
number | string | optional | Human-readable credit note number |
transaction_date | date | optional | Date the credit note was issued |
status | enum | optional | See below. Defaults to SUBMITTED. |
remaining_credit | decimal | optional | Unapplied credit still available. 0 if fully applied. |
currency | string | optional | ISO 4217. Defaults to USD. |
exchange_rate | decimal | optional | Rate at issuance, if multicurrency |
inclusive_of_tax | boolean | optional | true if total_amount includes tax. Defaults to false. |
memo | string | optional |
status values:
| Value | Meaning |
|---|---|
SUBMITTED | Issued but not yet approved or applied (default) |
AUTHORIZED | Approved and available to apply against invoices |
PAID | Fully applied; no remaining credit |
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.
| Field | Type | Required | Notes |
|---|---|---|---|
remote_id | string | ✓ | Payment identifier. Repeated across rows when one payment covers multiple invoices. |
invoice_remote_id | string | ✓ | FK to Invoice.remote_id — the invoice this row applies to |
total_amount | decimal | ✓ | Total amount of the payment (the same value on every row for that payment) |
applied_amount | decimal | optional | Portion of the payment applied to this invoice row. If omitted, the total amount is assumed to be applied to the linked invoice. |
transaction_date | date | optional | Date the payment was received |
currency | string | optional | ISO 4217. Defaults to USD. |
status | string | optional | Source payment status, e.g. completed, pending |
payment_method | string | optional | e.g. ach, card, wire, check |
transaction_id | string | optional | Bank or processor reference |
notes | string | optional | Free-form note |
remote_updated_at | datetime | optional | Source-system last-modified timestamp |
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 in 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.