# SAP Business One — Accounting API: gotchas

> Canonical URL: https://developers.apideck.com/apis/accounting/sap-business-one/gotchas

## POST /accounting/bills

`reference` cannot be written: SAP Business One sets it to the document number. Use `bill_number` for the vendor's invoice number (*Vendor Ref. No.*). Bills are posted when created: `status` is not written, because SAP Business One keeps drafts in a separate Drafts object.

## PATCH /accounting/bills/{id}

To change a line, send it with the `id` from a read: SAP Business One updates the line with that number. A line without an `id` is matched by its position in `line_items`, so it is added only when it comes after all of the document's existing lines; otherwise it replaces the line at that position. To add lines safely, send every existing line with its `id` followed by the new ones. Lines left out of the request are kept.

## POST /accounting/invoices

`reference` cannot be written: SAP Business One sets it to the document number. Use `po_number` for the customer's reference (*Customer Ref. No.*). `number` is assigned by the document numbering series. Invoices are posted when created: `status` is not written, because SAP Business One keeps drafts in a separate Drafts object.

## PATCH /accounting/invoices/{id}

To change a line, send it with the `id` from a read: SAP Business One updates the line with that number. A line without an `id` is matched by its position in `line_items`, so it is added only when it comes after all of the document's existing lines; otherwise it replaces the line at that position. To add lines safely, send every existing line with its `id` followed by the new ones. Lines left out of the request are kept.

## POST /accounting/credit-notes

`reference` is stored as the customer reference number (*Customer Ref. No.*, `NumAtCard`). `total_amount` is required by the API but SAP Business One computes the document total from the lines, including tax, so the value sent is not stored. Credit notes are posted when created: `status` is not written, because SAP Business One keeps drafts in a separate Drafts object.

## PATCH /accounting/credit-notes/{id}

To change a line, send it with the `id` from a read: SAP Business One updates the line with that number. A line without an `id` is matched by its position in `line_items`, so it is added only when it comes after all of the document's existing lines; otherwise it replaces the line at that position. To add lines safely, send every existing line with its `id` followed by the new ones. Lines left out of the request are kept.

## POST /accounting/purchase-orders

`reference` is stored as the vendor reference number (*Vendor Ref. No.*, `NumAtCard`). `po_number` is the document number SAP Business One assigns, so it cannot be chosen.

## PATCH /accounting/purchase-orders/{id}

To change a line, send it with the `id` from a read: SAP Business One updates the line with that number. A line without an `id` is matched by its position in `line_items`, so it is added only when it comes after all of the document's existing lines; otherwise it replaces the line at that position. To add lines safely, send every existing line with its `id` followed by the new ones. Lines left out of the request are kept.

## GET /accounting/attachments/{reference_type}/{reference_id}

Only `invoice`, `bill`, `credit-note` and `quote` are supported as a `reference_type`; any
other value returns `400`. A document's files form one SAP Business One attachment entry and
the list returns all of them in one page. An attachment `id` is `{entry}-{line}` (for
example `4-2`). `size`, `created_by` and `updated_at` are not available, and `created_at`
carries the date only.

## POST /accounting/attachments/{reference_type}/{reference_id}

Only `invoice`, `bill`, `credit-note` and `quote` are supported as a `reference_type`.
Uploads need the company's attachments folder (Administration > System Initialization >
General Settings > Path) to exist and be writable by the Service Layer user; otherwise
every upload fails with `Internal error (-43) occurred`. SAP Business One keeps all
attachments in that one folder, so a file name can be used once per company: a name
another document already uses returns `400` ("A file with this name already exists"),
and a name the same document already uses returns `409`. Rename the file to upload it.
Files are limited to 50 MB, and `description` is not stored. When two uploads reach a
document without attachments at the same moment, the second returns `409` naming the
attachment entry its file was stored in; that entry is not attached to the document.

## GET /accounting/attachments/{reference_type}/{reference_id}/{id}

The `id` (`{entry}-{line}`) must belong to the document named by
`reference_type`/`reference_id`. An id from another document's attachments returns `404`.

## DELETE /accounting/attachments/{reference_type}/{reference_id}/{id}

Not supported. SAP Business One does not allow an attachment, or a single file of one, to
be removed.

## GET /accounting/attachments/{reference_type}/{reference_id}/{id}/download

The `id` (`{entry}-{line}`) must belong to the document named by
`reference_type`/`reference_id`. An id from another document's attachments returns `404`.

## GET /accounting/bank-accounts

Bank accounts are SAP Business One house bank accounts. `bank_name` comes from the linked bank, and `currency` and `balance` from the linked G/L account (`ledger_account.id`): the balance is in the company's local currency, which is also the `currency` of an all-currencies account. SAP Business One has no account type, status, available balance, overdraft limit, routing number, description or created/updated dates for a house bank account, so these are not returned.

## POST /accounting/bank-accounts

`bank_code` is required and must be the code of a bank that already exists in SAP Business One (*Administration > Setup > Banking > Banks*); an unknown code is rejected with a 400 and no bank is created. `ledger_account.id` is the G/L account the bank account posts to. The bank cannot be changed afterwards: an update ignores `bank_code`.

## GET /accounting/quotes

`status` is `void` for a cancelled quote, `accepted` once it is closed (for example copied to a sales order or closed by hand), otherwise `sent`.

## POST /accounting/quotes

`reference` is stored as the customer reference number (*Customer Ref. No.*, `NumAtCard`).

## PATCH /accounting/quotes/{id}

To change a line, send it with the `id` from a read: SAP Business One updates the line with that number. A line without an `id` is matched by its position in `line_items`, so it is added only when it comes after all of the document's existing lines; otherwise it replaces the line at that position. To add lines safely, send every existing line with its `id` followed by the new ones. Lines left out of the request are kept.

## DELETE /accounting/quotes/{id}

SAP Business One cannot delete quotations. `DELETE` cancels the quote (it stays readable with `status: void`). A quote that has already been copied to a sales order cannot be cancelled; SAP Business One rejects it.

## GET /accounting/sales-orders

Sales orders are SAP Business One sales orders (Service Layer `Orders`). `status` is `cancelled` when the order is cancelled, `closed` once it is closed (fully delivered or invoiced, or closed by hand), otherwise `open`; SAP Business One does not tell a closed order's reason apart, so `invoiced` is not returned. `po_number` is the customer's reference number (*Customer Ref. No.*).

## POST /accounting/sales-orders

`customer.id` is the business partner's CardCode, and each line needs an `item.id` (ItemCode) or a `ledger_account.id` for service lines. `order_date` and `delivery_date` map to the posting and delivery dates. `reference` cannot be written: SAP Business One sets it to the document number; `po_number` holds the customer's reference (*Customer Ref. No.*).

## PATCH /accounting/sales-orders/{id}

To change a line, send it with the `id` from a read: SAP Business One updates the line with that number. A line without an `id` is matched by its position in `line_items`, so it is added only when it comes after all of the document's existing lines; otherwise it replaces the line at that position. To add lines safely, send every existing line with its `id` followed by the new ones. Lines left out of the request are kept.

## PATCH /accounting/sales-orders/{id}

Updates are a PATCH of the fields you send. An order that is closed or cancelled cannot be updated.

## DELETE /accounting/sales-orders/{id}

SAP Business One cannot delete sales orders. `DELETE` cancels the order (it stays readable with `status: cancelled`). Only an order nothing has been delivered or invoiced from can be cancelled; SAP Business One rejects the others.

## POST /accounting/expense-categories

Expense categories are SAP Business One expense G/L accounts. On a segmented chart of accounts SAP Business One needs the parent title account and the segmented account number, which have no unified field: send them in `pass_through` as `FatherAccountKey` and `FormatCode`. SAP Business One assigns the account code and appends the segment names to `name` (for example `Travel (HO, USA, GA)`).


[API reference](https://developers.apideck.com/apis/accounting/reference.md) · [Coverage matrix](https://developers.apideck.com/apis/accounting/coverage)
