Skip to main content
Use this guide if your data reaches Daylit over SFTP instead of a live accounting integration. It walks through SSH key setup, connection testing, field mapping, sample validation, your first full snapshot, and ongoing delta uploads. For what to send and how files should be shaped, see SFTP data schema.

What is SFTP?

SFTP (SSH File Transfer Protocol) is a standard way to move files securely between your systems and Daylit over the internet. You export data from your source system as CSV files, then upload them to a Daylit-managed endpoint on a schedule you control. Authentication uses SSH keys — not passwords — so automated jobs can run unattended. Once files land, Daylit validates them against your field mapping, ingests the records, and keeps your AR dashboard current through incremental delta uploads.

Why SFTP?

Most Daylit customers connect their accounting system through Merge — an OAuth link to QuickBooks, NetSuite, Xero, Sage, or another Merge-supported platform. Data syncs automatically with no file exports on your side. SFTP is the right path when a direct connection isn’t possible or practical:
  • Your system isn’t supported by Merge. Legacy ERPs, industry-specific billing platforms, or custom-built tools often aren’t available for OAuth linking.
  • Your IT or security team restricts API access. Some organizations block third-party connections to accounting systems but allow scheduled file drops to an approved endpoint.
  • You already export data on a schedule. If your ERP produces nightly CSV reports or you run SQL exports from a data warehouse, SFTP plugs into that existing workflow.
  • You need to combine data from multiple sources. You can merge customers, invoices, and contacts from different systems into unified files before uploading.
  • You want explicit control over what Daylit receives. You choose exactly which fields and records leave your environment, and when.
Both paths deliver the same outcome in Daylit — customers, invoices, contacts, and credit notes ready for collections and AR reporting. SFTP just means you push files instead of Daylit pulling via API.
If your accounting platform appears in the Merge provider list, a direct integration is usually faster to set up. Use this SFTP guide when your Daylit contact directs you here or when OAuth linking isn’t an option.

Before you start

What you’ll need

  • An export from your source system. Daylit accepts CSV files. Most ERPs, accounting systems, and billing platforms can produce scheduled exports or report-to-file output.
  • A machine that can run an SFTP client. Use the command line (sftp on macOS, Linux, and modern Windows) or a GUI tool such as FileZilla, WinSCP, or Cyberduck.
  • A place to run a scheduled job. Eventually you want uploads on a schedule — cron, Windows Task Scheduler, Airflow, or your ERP’s built-in scheduler.
  • About 30 minutes to reach your first validated sample upload. A full snapshot adds another ~20 minutes depending on volume.
  • One technical contact. Daylit emails this address when something needs your attention.

What you won’t need

  • A VPN or special network access. Standard internet over port 22 is enough.
  • A password. Daylit uses SSH keys only — more secure and easier to automate.
  • A waiting period on Daylit’s side. Everything in this guide is self-serve in the portal, though Daylit support is available if you need help.

Quick start

If you’ve done SFTP integrations before, here’s the speed run. Details follow in the steps below.
1

Generate an SSH key

ssh-keygen -t ed25519 -f ~/.ssh/daylit_ed25519
2

Register the public key

Sign in to Daylit, go to Settings → SFTP Connection → Endpoints, and paste the contents of ~/.ssh/daylit_ed25519.pub. Give the connection a name (for example, primary-source).
3

Map your columns

On the Mapping tab, map your source columns to Daylit’s canonical fields for each object.
4

Copy connection details

After saving, copy the hostname, port, and system-generated username from your connection card.
5

Upload a sample

sftp -i ~/.ssh/daylit_ed25519 username@sftp.daylit.com and put a sample file into /sample/{object}/.
6

Validate and go live

On Sample Checks, confirm validation passes for all four required objects. Upload your /init/ snapshot, run a dry-run, then apply. Schedule delta uploads to /delta/.

Step 1 — Generate your SSH key

An SSH key is a matched pair of files that proves your identity without a password. You generate them yourself and keep the private key secure. You’ll register the public key with Daylit in Step 2.
Generate the key once on the machine that will run your scheduled upload job. On macOS, Linux, or Windows with WSL, open a terminal and run:
# -C "acmecorp-daylit-sftp" is a label to help you identify the key — use your company name instead of acmecorp if you prefer
ssh-keygen -t ed25519 -C "acmecorp-daylit-sftp" -f ~/.ssh/daylit_ed25519
When prompted for a passphrase: leave it empty if an unattended scheduled job will use this key. Use a passphrase only if a human connects interactively. Optional (macOS): copy the public key to your clipboard:
pbcopy < ~/.ssh/daylit_ed25519.pub
You’ll end up with two files:
  • ~/.ssh/daylit_ed25519 — the private key. Never share, email, or commit this file.
  • ~/.ssh/daylit_ed25519.pub — the public key. Safe to share with Daylit.
Daylit accepts ED25519, ECDSA, and RSA (3072 bits or larger). ED25519 is the modern default. Use ssh-keygen -t rsa -b 4096 if your environment requires RSA.
The public key is one long line starting with ssh-ed25519 (or ssh-rsa), followed by base64, then your comment:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINjB7Tx... acmecorp-daylit-sftp
If you see -----BEGIN OPENSSH PRIVATE KEY-----, you’re looking at the private key. Don’t paste that into the portal. Estimated time: 5 minutes.

Step 2 — Register the public key in Daylit

Sign in at intelligence.daylit.com. If you don’t have access yet, request it from your Daylit contact. Then:
  1. Open your public key file in a text editor and copy the entire single line.
  2. Go to Settings → SFTP Connection → Endpoints.
  3. Paste the public key into the SSH Public Key field.
  4. Enter a Connection Name (for example, sage-export or primary-source) so you can identify which system the data comes from. Use lowercase letters, digits, and hyphens.
  5. Click Save configuration.
The portal validates the format immediately. The most common error is pasting the private key by accident. Estimated time: 2 minutes.

Step 3 — Get your connection details

After you save your endpoint, Daylit creates your SFTP user, private storage area, and access scope. Your connection card shows:
  • SFTP Hostname / Endpointsftp.daylit.com
  • Port22 (standard SFTP)
  • Assigned Username — system-generated for this connection
  • Key updated at — timestamp of the latest key rotation for this connection

Optional: SSH config entry

For command-line use, add an entry to ~/.ssh/config:
Host daylit
  HostName sftp.daylit.com
  User your-assigned-username
  Port 22
  IdentityFile ~/.ssh/daylit_ed25519
  IdentitiesOnly yes
Run chmod 600 ~/.ssh/config ~/.ssh/daylit_ed25519. After that, you can connect with sftp daylit instead of typing the full command sftp -i ~/.ssh/daylit_ed25519 your-username@sftp.daylit.com each time. The SSH config entry supplies your hostname, username, port, and key automatically.

Upload paths

Daylit creates these top-level directories for your workspace:
PathPurpose
/test/Connectivity check only — no business validation
/sample/Small files (≤ 100 rows) to validate your mapping
/init/Full snapshot of every record in an object
/delta/Incremental updates since your last successful upload
Within each phase folder, place files in the matching object subfolder (for example, /sample/invoice/). See SFTP data schema for the full path structure.

Test your connection

Connect to your SFTP workspace with one of these commands:
sftp -i ~/.ssh/daylit_ed25519 your-username@sftp.daylit.com
Or, if you completed the optional SSH config step above:
sftp daylit
At the SFTP prompt, upload any small file to /test/ and exit:
sftp> put any_small_file.csv /test/
sftp> bye
On first connect, your client may ask to verify the host. Accept if the fingerprint matches what the portal shows.
If you’re prompted for a password, you have a key mismatch or wrong username/hostname. Re-check your private key path and the username on your connection card.
Back in Daylit, click Test connection on the connection card. Once active, you’ll see a green status banner and a Connection verified status confirming Daylit received your file. Estimated time: 5 minutes.

Step 4 — Get your data prepared

Daylit requires five objects before you can go live:
ObjectWhat it is
CustomerCompanies or individuals you bill
Customer ContactAP and billing contacts at each customer
InvoiceInvoices with amounts, dates, status, and embedded payment info
Credit NoteRefunds, returns, and applied or unapplied credits
PaymentIndividual payment events, one row per invoice allocation
For file format, required fields, and upload paths, see SFTP data schema. Estimated time: 2 minutes.

Step 5 — Map your columns to Daylit fields

Daylit uses a canonical schema — a fixed set of field names per object (for example, every invoice has remote_id, customer_remote_id, total_amount, issue_date). Your source system likely uses different column names. The mapping tells Daylit how to translate. For each object, the Mapping tab shows three columns: Daylit field (fixed), External parameter name, and Format. Enter the corresponding parameter name from your data for each Daylit field, then select the correct format. Be especially careful with date fields — the format must match how your export represents dates (for example, MM/DD/YYYY vs YYYY-MM-DD).
You can also download default YAML or JSON config files, edit them offline, and upload via Upload config. Click Save mapping when done. Daylit keeps track of different mapping versions so you can always see exactly what was in effect when a given file was ingested. Estimated time: ~10 minutes per object the first time.

Step 6 — Upload and validate your sample

A sample proves your mapping is correct before you send data at scale. Daylit validates the sample but does not ingest it into production.

Produce the sample

Export 10–100 representative rows for one object from your source system. Include a mix of customers, statuses, and edge cases — not all rows from one customer.

Upload

Command line:
sftp -i ~/.ssh/daylit_ed25519 your-username@sftp.daylit.com
# (or just: sftp daylit, if you set up ~/.ssh/config above)
sftp> put invoices_sample_2026-06-02.csv /sample/invoice/
sftp> bye
You must upload to the correct object subfolder or Daylit won’t detect the file.

Validate in the portal

Go to Settings → SFTP Connection → Sample Checks, select your SFTP connection, and click Validate for each object (or Validate all). Pass — all rows parsed with zero errors. Move on to the next object. Fail — the report shows row-level errors in plain language: Common sample failures:
  • Date format mismatch — update the format in Mapping, save, and click Validate again. You don’t need to re-upload unless you want to test a new file.
  • Currency symbol or thousands separator in an amount column — add the decimal transform.
  • Empty required field — map the field to the correct source column or fix the export.
Estimated time: 5–15 minutes for the first iteration.

Step 7 — Upload your init (full snapshot)

Once every sample passes, send your first init — a complete snapshot of every record in the object. You usually do this once per object; future updates are deltas.

Produce the init

Run the same export as your sample, but with no row limit:
  • Customer — every active customer (inactive optional)
  • Customer Contact — customer ID, contact ID, and email
  • Invoice — every invoice: open, partially paid, paid, voided, and draft
  • Credit Note — every credit note, applied or unapplied
  • Payment — every payment event, one row per invoice allocation (optional)

Upload order

Upload parents before children so foreign keys resolve immediately:
  1. /init/customer/ first
  2. /init/customer_contact/ and/or /init/invoice/ next
  3. /init/credit_note/ and/or /init/payment/
sftp daylit
sftp> put customers_init_2026-06-02.csv /init/customer/
sftp> put contacts_init_2026-06-02.csv /init/customer_contact/
sftp> put invoices_init_2026-06-02.csv /init/invoice/
sftp> put credit_notes_init_2026-06-02.csv /init/credit_note/
sftp> put payment_init_2026-06-02.csv /init/payment/
sftp> bye
For large files, enable progress in the SFTP client:
sftp> progress
sftp> put invoices_init_2026-06-02.csv /init/invoice/

Dry-run and apply

After upload, click Dry-run in the portal to generate a report and preview how your data will look. Start with the Customer object first, then proceed in dependency order. Fix any validation errors before moving on. When the dry-run is clean, click Apply to ingest the data. Large inits may take time to complete.
Dependency order requiredDry-runs and apply must follow dependency order: /init/customer//init/customer_contact//init/invoice//init/credit_note/. Customer must be applied successfully before other objects can be dry-run or applied.
If validation fails, the init is rejected as a unit — Daylit doesn’t write half of a snapshot. You see exactly what failed and re-upload after fixing. We again take the latest upload file for init check, or you can replace the original file.A single wrong row will invalidate the whole batch. This is initial batch hence we need to ensure the data is correct.
Estimated time: 30 minutes to few hours depending on data volume.

Step 8 — Set up your delta schedule

After your init is applied, keep Daylit current with deltas — incremental files containing every record created or modified since your last successful upload.

What a delta should contain

Filter exports by your source system’s “last modified” timestamp:
SELECT * FROM invoices
WHERE modified_on > '2026-06-02T14:43:51Z';
Whatever your tool is (saved search, scheduled report, SQL query, Power Automate flow), build it to filter by your “last modified” column and the timestamp of the last successful run.

How often to run

Daylit picks up new files every 15 minutes, so running more frequently than that doesn’t speed ingestion. Common cadences:
  • Hourly — active collections and AR aging workflows
  • Nightly — when 24-hour freshness is sufficient
  • Every 15 minutes — high-priority objects like invoices
You can use different cadences per object.

Scheduling the upload

Add to your crontab (crontab -e):
# Daylit delta upload — invoices hourly
0 * * * * /home/erp-export/daylit_delta.sh
A minimal daylit_delta.sh:
#!/usr/bin/env bash
set -euo pipefail

# 1. Export from your source system
LAST_RUN_FILE=/var/lib/daylit/last_run.txt
SINCE=$(cat "$LAST_RUN_FILE" 2>/dev/null || echo "1970-01-01T00:00:00Z")
NOW=$(date -u +%FT%H%M%SZ)

# (Replace this with whatever produces your CSVs from your ERP.)
/usr/local/bin/erp-export invoices --modified-after "$SINCE" \
  > "/exports/invoices_delta_${NOW}.csv"

# 2. Upload to Daylit
sftp -i ~/.ssh/daylit_ed25519 -o StrictHostKeyChecking=yes \
     your-username@sftp.daylit.com <<EOF
  put /exports/invoices_delta_${NOW}.csv /delta/invoice/
EOF

# 3. Record success
echo "$NOW" > "$LAST_RUN_FILE"
A few things this script does on purpose:
  • It uses a last_run.txt file to remember when the last successful run was, so the next delta picks up from there. Don’t use “the last 24 hours” — if a run fails, you’d miss data permanently.
  • It only updates last_run.txt after the upload succeeds. If the SFTP step fails, the next run re-tries from the same starting point.
  • set -euo pipefail makes the script fail loudly on any error rather than silently producing an empty file.
  • StrictHostKeyChecking=yes ensures the host key is verified.
Estimated time: 30–60 minutes.

Reference

The numbered steps above walk you through initial SFTP onboarding. The sections below cover ongoing maintenance, troubleshooting, and quick lookup — they are not part of the setup flow.

Rotate your SSH key

Rotate every 6–12 months, or when someone with access to your private key leaves the team:
  1. Generate a new key: ssh-keygen -t ed25519 -f ~/.ssh/daylit_ed25519_new
  2. In Settings → SFTP Connection → Endpoints, add the new public key.
  3. Test: sftp -i ~/.ssh/daylit_ed25519_new your-username@sftp.daylit.com
  4. Update your scheduled job to use the new key and run it once manually.
  5. Remove the old public key from the portal and delete the old private key from disk.

Troubleshooting

Your SFTP client is presenting the wrong key, or the key isn’t registered in the portal.
  • Confirm you’re using -i ~/.ssh/daylit_ed25519 (path to the private key).
  • Verify the matching public key appears under Settings → SFTP Connection → Endpoints.
  • Confirm the username matches your connection card exactly.
Compare the fingerprint your client shows against the value in the portal. If they match, accept the new key. If they don’t, stop and contact support@daylit.com.
Your CSV doesn’t have a column your mapping references. Re-check the export query and your mapping on the Mapping tab.
A child record references a parent that isn’t in the init. Upload the customer init first, and confirm customer ID columns match across exports (for example, client_id vs account_id).
A record’s remote_updated_at is older than the version Daylit already has. Verify your export uses the same timestamp column as your mapping.
Use set -euo pipefail in your script so SFTP failures exit non-zero. Log stderr and configure your scheduler to alert on failure.

FAQ

No. Daylit accepts SSH keys only (ED25519, ECDSA, or RSA ≥ 3072 bits). Keys are more secure and easier to automate.
Try formatting to CSV export. A small middleware script (SQL query → file) usually solves export limitations. More file format options are coming soon. Contact Daylit to scope a solution.
Yes. Daylit upserts on remote_id — duplicate sends update existing rows rather than creating duplicates.
Yes. Create a second workspace and run your scheduled job against test first. Point at production once you’re satisfied.
Your files are encrypted at rest and in transit when you upload via SFTP. We never share your data with other clients. The ingestion pipeline is read-only into Daylit; we do not write back to your source system.

Glossary

TermDefinition
Canonical schemaDaylit’s fixed field names per object. Your mapping translates source column names to these fields.
SampleA small file that validates your mapping. Not ingested into production.
InitA full snapshot of every record in an object. Sent once as the starting state.
DeltaAn incremental update with records created or modified since the last successful upload.
remote_idThe record’s identifier in your source system. Required on every row. Daylit upserts on this value.
UpsertInsert if remote_id is new; update if it’s already known.

Getting help

  • Portal in-app chat — bottom-right on every page.
  • Email: support@daylit.com. Include your workspace name and the filename or timestamp you’re asking about.
  • Status page: status.daylit.com for any active incidents.