> ## Documentation Index
> Fetch the complete documentation index at: https://docs.monk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SFTP Export format

> How Monk sends matched payments back to your ERP over SFTP, and how Monk confirms what your ERP loaded

# SFTP Export format

When Cash App sync to your ERP is on, Monk writes the payments it has matched to
a cash application file in your outbound folder. Your ERP's payment import loads
the file, and your next export confirms what was loaded. For how the integration
works overall, see [File integration (SFTP)](https://docs.monk.com/integrations/sftp).

## Folders and file names

| | Monk-hosted SFTP | Your SFTP server |
| - | - | - |
| Where Monk writes | `/outbound`, where you can download and delete | The outbound folder you give Monk during setup |
| How long files stay | Until you delete them, or 30 days | Until you move or delete them |

Each batch has one `batch_seq` for your whole connection, and contains one cash
application file per entity with rows in that batch. Monk names each file
`<timestamp>_<batch_seq>_<entity_code>_cash_application.csv`, all in lowercase,
and writes it directly into the outbound folder:

```
/outbound/
  20261026-060000_000143_us01_cash_application.csv
  20261026-060000_000143_ca02_cash_application.csv
  20261027-060000_000144_us01_cash_application.csv
```

* `<timestamp>` is when Monk wrote the batch in UTC, as `yyyymmdd-hhmmss`,
  `<batch_seq>` is padded to six digits, and `<entity_code>` is your entity code
  in lowercase.
* `batch_seq` starts at 1 and increases by one with every batch, with no gaps. A
  batch only has files for the entities with rows in it, so an entity's files
  can skip numbers, but a number with no files at all means a batch you have not
  received.
* Monk uploads each cash application file under a temporary name ending in
  `.tmp` and renames it once the upload is complete. Your import must ignore
  `.tmp` files and pick up only names ending in `_cash_application.csv`, so it
  never reads a partly written file.
* On Monk-hosted SFTP, you can delete each file once you have loaded it, so the
  folder only holds files still to load. Otherwise, keep track of the last
  `batch_seq` you have loaded.

For your SFTP server, Monk confirms delivery by listing the folder after it
renames the temporary file; the connector does not return a durable move result.
Monk retries confirmation for up to 25 seconds (five attempts at five-second
intervals). If your ERP moves the file before that listing, Monk treats
delivery as unconfirmed and resends the same file with the same name, bytes,
and `line_ids`. Your ERP must skip lines it has already loaded. A job that
always removes files within seconds can prevent the batch from completing and
hold later batches. Leave files in the folder for at least one minute, or move
them to an archive folder after processing.

## How to read a cash application file

Each row is one instruction for your ERP. Rows that share a `monk_payment_id`
belong to one payment: one customer's payment from one bank deposit.

For example, a customer pays two invoices by wire: 7,500.00 for INV-2026-0451
and 2,542.00 for INV-2026-0452. Their bank deducts a 42.00 fee, so 10,000.00
arrives, and your team approves writing off the fee in Monk. Monk writes three
rows, all with `monk_payment_id` `MK0000004F2K`:

| Row | `operation` | `invoice_number` | `amount` | What your ERP does |
| - | - | - | - | - |
| 1 | `payment_apply` | INV-2026-0451 | 7500.00 | Creates payment MK0000004F2K for 10,000.00 and applies 7,500.00 to INV-2026-0451 |
| 2 | `payment_apply` | INV-2026-0452 | 2500.00 | Applies 2,500.00 of the same payment to INV-2026-0452 |
| 3 | `write_off` | INV-2026-0452 | 42.00 | Writes off the remaining 42.00 on INV-2026-0452 as a bank fee |

Both invoices are now closed in your ERP, and the payment totals 10,000.00,
matching the deposit. The write-off does not change the payment's total.

```csv theme={null}
batch_seq,line_id,entity_code,operation,monk_payment_id,payment_date,payment_amount,bank_account,customer_id,invoice_id,invoice_number,amount,currency,line_date,write_off_kind,reverses_id,memo
143,L7Q2M1,US01,payment_apply,MK0000004F2K,2026-10-16,10000.00,1010,C-881,10045,INV-2026-0451,7500.00,USD,,,,
143,L7Q2M2,US01,payment_apply,MK0000004F2K,2026-10-16,10000.00,1010,C-881,10046,INV-2026-0452,2500.00,USD,,,,
143,L7Q2M3,US01,write_off,MK0000004F2K,2026-10-16,10000.00,1010,C-881,10046,INV-2026-0452,42.00,USD,2026-10-17,provider_fee,,
```

## Operations

| Operation | What to do in your ERP |
| - | - |
| `payment_apply` | Create the payment the first time its `monk_payment_id` appears, then apply `amount` to the invoice |
| `payment_unapplied` | Leave `amount` of the payment unapplied or on account, for example an overpayment. A payment can consist of this row alone |
| `write_off` | Write off `amount` on the invoice as part of the payment named in `monk_payment_id`, using `write_off_kind` to choose the GL account. Every write-off belongs to a payment |
| `reverse` | Reverse the payment named in `reverses_id`, with its write-offs. When Monk corrects a payment, the corrected rows follow under a new `monk_payment_id` |

Which columns each operation fills:

| Column | `payment_apply` | `payment_unapplied` | `write_off` | `reverse` |
| - | - | - | - | - |
| `batch_seq`, `line_id`, `entity_code`, `operation`, `monk_payment_id` | Yes | Yes | Yes | Yes |
| `payment_date`, `payment_amount`, `bank_account`, `customer_id`, `currency` | Yes | Yes | Yes | Yes |
| `invoice_id`, `invoice_number` | Yes | | Yes | |
| `amount` | Yes | Yes | Yes | |
| `line_date`, `write_off_kind` | | | Yes | |
| `reverses_id` | | | | Yes |
| `memo` | Optional | Optional | Optional | Optional |

## Columns

Every file has a header row, and its columns always appear in this order:

```csv theme={null}
batch_seq,line_id,entity_code,operation,monk_payment_id,payment_date,payment_amount,bank_account,customer_id,invoice_id,invoice_number,amount,currency,line_date,write_off_kind,reverses_id,memo
```

The tables below group the columns by what they describe. Monk never adds, removes, renames, or reorders a column, or changes what one means,
within a format version. Any such change, including a new column at the end,
comes with a new format version that your team switches to when your ERP's
import is ready for it, so a loader that reads columns by position keeps
working.

**Identifying the row**

| Column | Description |
| - | - |
| `batch_seq` | The batch this row belongs to |
| `line_id` | Monk's unique ID for this row. Never reused |
| `entity_code` | The entity the payment belongs to. Each cash application file covers one entity |
| `operation` | One of the operations above |

**The payment** (repeated on every row of the payment)

| Column | Description |
| - | - |
| `monk_payment_id` | Monk's ID for the payment: `MK` followed by 10 uppercase letters and digits, 12 characters in total. Store it on the payment record and send it back in the same column of `payments.csv`; Monk matches it ignoring case. Also set on every `write_off` row |
| `payment_date` | Date the payment reached your bank |
| `payment_amount` | This customer's total on the payment |
| `bank_account` | The cash account code configured for this entity during setup |
| `customer_id` | Your ERP customer ID |
| `currency` | The currency of the payment and of every invoice it applies to. A payment in a different currency from its invoices stays in Monk for review and is not sent |

**The application or write-off**

| Column | Description |
| - | - |
| `invoice_id`, `invoice_number` | Your ERP invoice ID and number; blank on `payment_unapplied` |
| `amount` | Positive amount for this row |
| `line_date` | For write-offs, the date the write-off was recorded |
| `write_off_kind` | `short_pay` (the customer paid less than the invoice) or `provider_fee` (a bank or payment processor fee) |
| `reverses_id` | For `reverse`: the `monk_payment_id` to reverse |
| `memo` | Reviewer note |

Every cash application file already satisfies these rules:

* A payment's `payment_amount` equals the sum of its `payment_apply` and
  `payment_unapplied` rows.
* Write-offs never change a payment's total.
* Every customer and invoice ID comes from your latest export, written exactly
  as you sent it.
* A `reverse` always comes before its corrected rows, in the same file.
* Every file of a batch is in place before Monk writes the next batch.
* When Monk sends a payment again, for example after your team retries one
  flagged as not loaded, it repeats the same rows with the same `line_id` and
  `monk_payment_id` in a new batch, so skipping `line_id`s you have already
  loaded prevents a double posting.

## Loading it into your ERP

* Load cash application files in `batch_seq` order.
* Load each payment, meaning every row that shares a `monk_payment_id`,
  completely or not at all.
* Skip any `line_id` you have already loaded. Do not rely on your ERP to reject
  a file sent twice.
* Skip a `reverse` whose `reverses_id` you never loaded.
* Store `monk_payment_id` in a field on the payment that appears in your next
  `payments.csv`, such as the check number or an external reference.
* Map `write_off_kind` to your GL accounts in the import, or
  give Monk the mapping during setup.

## Confirming what your ERP loaded

Monk confirms what your ERP loaded when your next export shows it. A payment is
confirmed when `payments.csv` contains its `monk_payment_id`, and each
application is confirmed when that row carries the expected invoice and amount.
Payments and applications confirm separately, so ERPs that post a payment first
and apply it later are supported. Once a payment comes back, your ERP's version
wins, as for any payment applied there: if your team applied it to different
invoices or amounts, Monk follows your ERP.

A `write_off` is confirmed with its payment. A `reverse` is confirmed when the
reversed payment appears in `payments.csv` with `voided` `true`.

A payment counts as loaded only once it has posted and appears in your export,
so payments your ERP holds for approval are confirmed after they post. A payment
or application not seen within three exports is flagged for review in Monk, so a
cash application file that was never loaded, rows your import rejected, or
payments still waiting for approval do not go unnoticed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.