Create a new sales document (invoice, sales order, etc.) or update an existing one.

Sales documents in Erply have a header with general information (customer, date etc.) and one or more lines that list the items, quantities and prices.

Every sales document in Erply needs to be confirmed. When confirmed, a sales invoice, for example, 1) receives a number, 2) generates sales revenue and VAT / tax obligation and 3) removes sold items from inventory. A confirmed sales order places a reservation on ordered items. A confirmed document may not be fully editable any more, or you might need special user rights for some kinds of changes.

Possible sales document types are listed below. Most common ones that you'll probably need, are:

  • INVWAYBILL (this is an ordinary sales invoice),
  • CASHINVOICE (basically the same, but the printout is formatted as a POS receipt),
  • ORDER (a sales order).
List of sales documents can be retrieved with getSalesDocuments. If you are making a sale, but you first need to know up-to-date prices and correct tax (VAT) rates for the items customer has selected, and get invoice total, see calculateShoppingCart. To apply a payment to the sale, use savePayment.

If the sales document that you created or updated is associated with a customer who is a natural person — and if your account country is subject to the General Data Protection Regulation (GDPR) — Erply logs the sale in the customer information processing log.

To make saveSalesDocument calls idempotent, use the "temporaryUUID" field.

Input parameters

Parameter name Description Possible value Required
id Sales document ID. Set this parameter to edit an existing sales document.

Please note that when confirmed already, sales invoices may not be fully editable any more.

Default value is INVWAYBILL. If you want to create a typical sales invoice, use INVWAYBILL.

  • INVWAYBILL - Deducts sold goods from inventory and accounts for revenue.

  • CASHINVOICE - Same as previous, but the printout is always formatted as a receipt, not an invoice.

  • WAYBILL - Deducts sold goods from inventory. This document is typically used in B2B environment. Create a WAYBILL if you ship items out of the warehouse, but want to bill the customer only at the end of the month, for all the items that have been shipped meanwhile. Hence, to complete the workflow, you need to follow up with an INVOICE.

  • PREPAYMENT - Prepayment invoice.

  • OFFER - Sales quote.

  • EXPORTINVOICE - Deprecated. This type was meant to be used in European Union, for international sales where a 0% VAT applies and you need to have customer VAT number and a special clause on the printout. Instead, please make an INVWAYBILL (or whatever document type you want) and set euInvoiceType = "EU" or "OUTSIDE_EU".

  • RESERVATION - Reserves goods in the stock. Roughly fills the same role as an order or a sales quote. This document type is being phased out.

  • ORDER - Order from the customer (or webshop). From order, an invoice later needs to be created.

  • INVOICE - Accounts for revenue. You usually only need this document type to follow up WAYBILLs that have been created earlier (see above).

  • CREDITINVOICE - A credit invoice. You may also add a reference to the original invoice being credited (creditToDocumentID = ID of the original invoice) and specify whether the transaction is a void or return transaction ("creditInvoiceType" is "VOID" or "RETURN")
currencyCode Currency code: "EUR", "USD" etc. Currency must be defined in your Erply account. For a list of available currencies, see getCurrencies.

If omitted, or an unknown currency code is provided, API uses your default currency instead. If editing an existing sales document, currency code is not necessary.
String (3)
currencyRate eg. 1.25543
Exchange rate of the main currency against system's default currency.
If the invoice is in system's default currency, you do not need to specify currenyRate — but if you do, use 1.0 as the value.

If omitted, API will apply the current exchange rate stored in Erply.
warehouseID ID of the warehouse (location, store) from which goods are being sold. Each sales document MUST be associated with a specific warehouse.

If you omit this parameter, system will associate ther document with the first warehouse in your account (by ID).

The user name that you using to connect to the API must have access rights for the particular warehouse.

For a list of warehouses, see getWarehouses.

Field "warehouseID" cannot be changed if your account has newer inventory module, the sales document has been confirmed and it is one of those documents that causes inventory levels to change (an INVWAYBILL, CASHINVOICE, WAYBILL, EXPORTINVOICE, or CREDITINVOICE). API will return error code 1017 in that case.

pointOfSaleID Register ID. One warehouse (store) may have many registers.

Setting register IDs is important if you build a POS integration. The Z Report (POS end-of-day report), for example, works by register. In other cases, pointOfSaleID is not necessary.

See getPointsOfSale.
date eg. 2010-01-29
Each sales document must have a date. If omitted, API applies current date.
time eg. 14:59:00
If omitted, API applies current time.

Each sales document MUST be associated with a customer. If you omit this parameter, API will automatically use default POS customer, but make sure you have it defined (Settings » Configuration in Erply backend).

See getCustomers.

Please note that the semantic meaning of "customer" may differ from one account to another. On older accounts, the "Customer" effectively means "recipient of goods", and it is additionally possible to define a "payer", but this is not required. (If not set, then the specified customer is both the payer as well as the recipient.)

On newer accounts, the "Customer" effectively means "payer", and it is possible to define a recipient (field "Ship to"), but this is not required. Hence, the roles have been reversed.

This will affect you if you have a standard integration used on multiple accounts, and you need to be able to set both payers and recipients. At the moment there is no set of parameters that could be used on all accounts with the same result; you need to inspect account configuration and tailor your input to API saveSalesDocument accordingly.

Call getConfParameters and check the value of configuration parameter "invoice_client_is_payer"

If it is 1, then:

  • Use customerID for the payer;
  • shipToID for the recipient, if necessary.

If the value of the parameter is 0 or it has not been defined, then:

  • Use customerID for the recipient;
  • payerID for the payer, if necessary.

Fields "addressID, "payerAddressID" and "shipToAddressID" should be used according to the same pattern.

Future API versions may get a uniform way of addressing recipients and payers.

addressID Customer address to be printed on the invoice.

To get a list of customer addresses, you may retrieve customer record with getCustomers (pass input parameter getAddresses = 1). You may also use API call getAddresses.

Only use this field if your account has a "Payer" field on invoice form. See the explanation above.

If invoice payer ("Bill To") is different from the receiver of goods (the "Ship To" customer), you may set this field, otherwise leave it unset.


Payer address ID.

Only use this field if your account has a "Payer" field on invoice form. See the explanation above.


Only use this field if your account has a "Ship To" field on invoice form. See the explanation above.

If the recipient of goods ("Ship To") is different from invoice payer, you may set this field, otherwise leave it unset.


The address ID of the receiver of goods.

Only use this field if your account has a "Ship To" field on invoice form. See the explanation above.

contactID Customer's contact person. Integer

Only use this field if your account has a "Ship To" field on invoice form. See the explanation above.

Contact person of recipient of goods.

Error code 1010 is returned if shipToID is missing.
Error code 1178 is returned if the provided contact person is not the actual contact person of recipient of goods.

employeeID Invoice creator ID. Employee name is displayed on invoice printout ("Cashier" or "Invoice created by") and used for reporting purposes ("Sales By Employee"). Integer
confirmInvoice By default 1, so API automatically confirms each sales document unless you specify otherwise (set confirmInvoice = 0).

Note: An unconfirmed sales invoice does not (and cannot) have a number.

Another tip: when you integrate Erply with a web shop and consider using unconfirmed sales invoices, perhaps a better option would be generating sales orders instead.
0 or 1
doNotAddRewardPoints 0 or 1
invoiceNo Number to be given to the sales document.

Normally not needed. API will number invoices automatically. Use only when an invoice is created offline and it must definitely receive a number BEFORE it is possible to make the API call.
  • If the document already has a number, it will not be changed. API will not return an error message.
  • Make sure that the manually-assigned number will not interfere with Erply's regular invoice numbering. This field must be an integer (digits only), and only numbers with 8 digits or more are safe to be assigned manually (these will not affect invoices made from Erply)
  • If you want to assign an invoice number that also contains letters and other characters, see the next field — customNumber.
  • API will overwrite the number if it detects it's a duplicate. In that case, return attribute "invoiceNo" will contain the correct number. If you do not want this behavior, and do not want the number to automatically change (even if it is a duplicate), set allowDuplicateNumbers = 1.
customNumber Assign a custom number to this sales document. As opposed to invoiceNo, this field may contain letters, spacing and punctuation.

Please note that back office support for custom numbers is currently limited. The custom number is displayed in the list of invoices and on the printouts, but you cannot search by that field.

For custom numbers, API does not check for duplicates (whether another document with this number already exists).
customReferenceNumber Sales document's custom reference number. This field must be used only if you want to override default reference numbers. If a document does not have a custom reference number, Erply itself will assign a default one, using the method selected in Settings → Configuration. If this field's value is longer than 25 characters, API returns error 1014. String
webShopOrderNumbers A string field that contains a valid json array of the numbers. Example: ["ABC", "DEF", "GHI"]. This field can be used for web shop integrations. An integration can store the "transaction number" ("invoice number", "order number") that was assigned to the transaction by a web shop platform. String
trackingNumber Document tracking number String (255)
fulfillmentStatus Fulfillment status as some agreed string value String (255)
allowDuplicateNumbers Prevent API from overwriting invoice number if it detects that an invoice with the same number already exists.
By default 0.
0 or 1
notes Notes printed on the invoice String
internalNotes Notes to be displayed on invoice form, as a notice/reminder to other users. String
projectID Project associated with the sales document. See getProjects.

If you want to have your sales documents categorized in a custom way, attributes may be a better choice than projects. See below.
invoiceState Status of the document itself.
For invoices, possible values: PENDING, READY, MAILED, PRINTED. For orders, possible values are: PENDING, READY, SHIPPED, FULFILLED, CANCELLED
May be left unspecified, system will determine it automatically. By default, unconfirmed documents are PENDING and confirmed documents are READY. Status then gets updated to MAILED or PRINTED, determined by the method of delivery.
paymentType Expected invoice payment method: eg. CASH, CARD, TRANSFER, CHECK, GIFTCARD.

You can specify payment method either by code name or by ID (field paymentTypeID); both are not needed.

This is just an informative field, indicating how the customer will likely pay the invoice. For more accurate information and for reporting, you need to inspect the payments associated with this document. An invoice can have many payments (of different types).

Also, if you want this field to have a value (eg. to be able to filter invoices by payment method), you need to set it explicitly; applying a payment will not automatically update invoice's payment method.

A list of invoice payment methods can be retrieved with getInvoicePaymentTypes. To create your own custom methods (and assign code names if needed), see saveInvoicePaymentType.
String (10)
paymentTypeID Payment method ID. If you specify paymentType (see above), this field is not needed. Integer
paymentDays eg. 5
By default: system-specific, usually 14.
In how many days the invoice is due.
hidePaymentDays By default 0
If specified, the printout of created invoice will not mention any due date.
0 or 1
printDiscounts By default 1
Whether the discount % for discounted items is printed on the invoice
0 or 1
penalty penalty for late payments as % per day, eg. "0,5"
This field is only informative and system does not account penalty automatically.
reserveGoods By default 0
Documents that neither sell the goods nor reserve them in the stock — PREPAYMENT, OFFER and ORDER — can optionally still include a reservation. Set reserveGoods = 1 in that case.
0 or 1
reserveGoodsUntilDate eg. 2010-03-15
Use if parameter "reserveGoods" is set to 1
Until what date the reservation is kept.
If unspecified, reservation lasts indefinitely (until the document is modified and reservation removed)
sendByEmail By default 0
Invoices marked with "sendByMail" have an e-mail indicator in the invoices table — these are meant to be sent by customer by e-mail.
0 or 1
pricelistID Normally not needed. Erply can automatically apply customer and store price lists and calculate up-to-date final prices for you — use calculateShoppingCart for that. Integer
paymentStatus Invoice payment status.
Possible values: PAID, UNPAID.
If set to PAID, system will automatically create a payment with today's date and invoice due amount. Payment type will be set according to attribute "paymentType", if possible, and typically defaults to TRANSFER.
Setting the value to UNPAID does not delete or change any payments.
paymentInfo Invoice payment information, who paid, when, how.
Max 255 characters
isCashInvoice For CREDITINVOICEs only. Does not apply to US locale.

Cash invoices have a calculation algorithm different from other sales documents. Cash invoice calculations are based on prices with VAT, so that invoice total would match the prices exactly.

To make the distinction possible for credit invoices as well, set the isCashInvoice attribute to 1 if the source document was a cash invoice — then system will use cash invoice calculation method.
creditToDocumentID For CREDITINVOICEs only. ID of the original invoice being credited. This serves as a reference link between these two documents. Integer
creditInvoiceType For CREDITINVOICEs only. Specify whether the cashier is voiding a previous sale (typically possible only for same-day transactions, especially if card payments are involved), or the customer is returning bought items.

Possible values: VOID, RETURN.
If omitted, the transaction is assumed to be a RETURN.
String (10)
amountPaidWithStoreCredit The amount that customer pays from their store credit account.

If the customer uses their store credit to pay an invoice, do not call savePayment — instead, set this attribute.

Example: If invoice total is $9.99, customer pays $5 in cash and $4.99 from store credit, call savePayment with the parameters "CASH" and 5.00, and set parameter "amountPaidWithStoreCredit" to 4.99.
Decimal (2 places)
taxExemptCertificateNumber String
otherCommissionReceivers A comma-separated list of sales associates who will receive commission from this sale.

There are two possible ways to assign commission. First, you may associate each invoice line with a specific employee (see invoice rows, field "employeeID"). The rest of the commission will go to invoice creator by default (field "employeeID").

The other option is to divide commission equally between two or more people. For that, use "otherCommissionReceivers". In that case, Erply will ignore field "employeeID" for commission purposes.
deliveryDate Customer requested delivery date (for the whole document). You may also set requested delivery dates for each line individually, see deliveryDate# below.

To use this, you should enable the feature "Delivery date tracking on sales and purchase orders" in Erply backend: Settings » Configuration » Inventory and Purchase: Enable Extra Features.
ISO date (yyyy-mm-dd)
shippingDate Actual shipping date (for the whole document). ISO date (yyyy-mm-dd)
baseDocumentID Source document ID. For an invoice, source document may be a waybill, order, quote, or prepayment invoice.
If you create a sales order, followed by a sales invoice, set the baseDocumentID on the sales invoice to link these two documents together.
baseDocumentIDs Source document IDs, separated by commas, such as: 1,2,3,4,5. String
exportInvoiceType Deprecated.

For EU users: if you want to create an international invoice (where customer VAT number and a special clause is printed on the invoice), set euInvoiceType = "EU" or "OUTSIDE_EU" instead.
deliveryTypeID Used primarily for categorizing sales orders. In Erply backend there is a report "Sales orders to be fulfilled" that provides a "delivery condition" (delivery type) filter. Types are defined in Inventory » Delivery Conditions.

See getDeliveryTypes.
deliveryOnlyWhenAllItemsInStock This field:
  • Only matters for sales orders.
  • It is related to the "Orders to be fulfilled" report in Erply.
  • By default, Erply does not consider a sales order as eligible for shipping unless all ordered items are in stock. In Settings » Configuration, you can enable partial shipping.
  • If you have partial shipping enabled, but still want particular orders to be ONLY shipped in full, set this flag.
Integer (0 or 1)
packingUnitsDescription Description of packing unit. String
euInvoiceType For European Union users. Possible values are "DOMESTIC", "EU", "EU_WITH_VAT", "OUTSIDE_EU".

"DOMESTIC" is the default value. Set euInvoiceType = "EU" or "OUTSIDE_EU" if you want to create an international invoice where customer VAT number and a special clause is printed on the invoice.
packerID Integer
transactionTypeID Integer Transaction types can be configured in Settings → Purchase transactions (Intrastat)
transportTypeID Integer Transport types can be configured in Settings → Transportation types (Intrastat)
deliveryTermsID Integer Delivery terms can be configured in Settings → Incoterms
deliveryTermsLocation String
triangularTransaction Integer (0 or 1)
purchaseOrderDone Integer (0 or 1)
applianceID Appliance ID. This API call returns error 1006 if assignment module is not enabled on this account. Integer
applianceReference Appliance reference. This API call returns error 1006 if assignment module is not enabled on this account. String
assignmentID Assignment ID. This API call returns error 1006 if assignment module is not enabled on this account. Integer
vehicleMileage Vehicle-specific attribute. This API call returns error 1006 if assignment module is not enabled on this account. Integer
added Sales invoice creation timestamp. Normally not needed — API will assign a timestamp automatically. For new documents only. Unix timestamp
rounding Specify rounding amount (eg. 0.02 or -0.04).

Normally, this is not needed. You can select a rounding option in Erply backend (SETTINGS → Configuration → Invoices and sales) and it will be automatically applied to all invoices. (API response always contains the rounding amount and invoice total after rounding.) Use this input parameter only if the default options are not sufficient and you need to implement a custom rounding rule.

Rounding is applied to invoice total with tax, after all other calculations.
externalNetTotal Assigning this field lets you retrieve invoice / receipt printouts from Erply that show a custom value for net total, tax and invoice total.

This may be useful if you are integrating with another software that has its own invoice calculation algorithm that differs from Erply's — and the total on the printout has to match with invoice total in the other software.

This only affects printouts; Erply accounts revenue according to its own calculations. Also: if Erply calculates receipt total to $8.05, you set "externalTotal" to $8.04 and customer pays $8.04, Erply will show the receipt as $0.01 unpaid.

If you edit the invoice in Erply back office and change items, prices or quantities, externalNetTotal / externalVatTotal / externalRounding / externalTotal values will be discarded.

These 4 fields are not enabled by default. Please contact Erply customer support if you need them.
Decimal, 4 places
externalVatTotal See above. Decimal, 4 places
externalRounding See above. Decimal, 4 places
externalTotal See above. Decimal, 4 places
temporaryUUID Optional id value. Used as custom identification on creating new documents. Can be used as a unique value to identify new document creation requests for duplicate requests prevention. A valid value can contain characters a-z+A-Z+0-9, symbols (. and -) and can be maximum of 128 characters long String
advancePayment Decimal
advancePaymentPercent Integer
printWithOriginalProductNames Integer (0 or 1)
hidePrices Integer (0 or 1)
hideAmounts Integer (0 or 1)
hideTotal Integer (0 or 1)
isFactoringInvoice Integer (0 or 1)
taxOfficeID Integer
algorithmVersion Optional calculation algorithm version number. Can be used to set a specific calculation algorithm for an invoice. Can only be used on invoice creation. Also note that this feature is only fully supported in Classic BO. Valid values are 1,2,3,4 and 5. Integer
periodStartDate ISO date (yyyy-mm-dd)
periodEndDate ISO date (yyyy-mm-dd)
orderArrived Integer (0 or 1)
orderInvoiced Integer (0 or 1)
eInvoiceBuyerID Buyer ID (e-invoice integration). String
workOrderID Work Order ID (Service App). Integer
ediStatus Status (Docura integration). String
ediText Text (Docura integration). String
documentURL Document URL (Docura integration). String
***** Invoice lines (rows). Send invoice lines as a flat list, each line defined by the following set of parameters. Replace # with set number (1, 2, 3, ...). For example: productID1, amount1, price1, vatrateID1 for the first invoice row, productID2, amount2, price2, vatrateID2 for the second one and so on.

VAT / tax is not a separate invoice row. Instead, for each invoice row you should specify what tax rate applies — and total tax (VAT) will be automatically calculated at the end of the invoice.

When updating an existing document and you do not define invoice rows, API will keep existing ones as they are. (So, if you only want to edit invoice date or creator, you do not need to re-send rows.) However, if row definitions are present, then all rows on the document will be replaced with new ones.

On certain documents, there is a limitation of what can and what cannot be changed. If your account has newer inventory module, the document has already been confirmed and it is one of those documents that causes inventory levels to change (an INVWAYBILL, CASHINVOICE, WAYBILL, EXPORTINVOICE, or CREDITINVOICE), then no rows can be removed or added, and on existing rows you cannot edit productID, serviceID, or the quantity (amount).. API will return error code 1023 if you attempt to do that.

However, you can update price, discount, tax rate and other information if you want. To update just the prices, you may just send the fields price1, price2 etc. — product ID and amount are not necessary. However, if you choose to send fields productID1, amount1 etc., then these must match what is currently on the document, otherwise API will return error code 1023.

stableRowID# Stable ID of the invoice row. This will be persisted if the row is the same as previously. Can be used to reference a specific row if it existed previously. Fields that are copied over are limited so saves still require other fields to be present. Only use this when the row is infact the same existing row. Integer
productID# ID of the product (SKU) sold. Either productID or serviceID can be set, but not both at the same time. Both can be omitted, however - in that case a free-text invoice row will be created. Integer
serviceID# ID of the service sold. Integer
itemName# Name of the sold item (use only if you want to override the default product/service name). String
vatrateID# ID of VAT rate. Integer

Sold quantity.

Sold quantity must be a decimal, and can not be zero.

This is a required field; however, you may omit it if you specify a package and quantity of packages instead (fields packageID# and amountOfPackages#).

Decimal yes

Net sales price per item, pre-discount.

If you omit both "price" and "discount", Erply will automatically apply the current price in the selected location (store) to the selected customer, according to price lists.

If you omit "price", but set "discount", Erply will automatically use product card price, and will subtract the discount from product card price.

discount# Discount % that WILL BE SUBTRACTED from the price specified in previous parameter.

The algorithm is as follows:

discountedPrice = round((price (100 - discount) / 100), defaultDecimalPlaces)
lineTotal = round(discountedPrice
amount), 2)
lineVat = round((lineTotal * (100 + vatrate) / 100), 2)
employeeID# Assign commission from the sale of this line item to a specific employee. Integer
campaignIDs# A comma-separated list of sales promotions that were applied to this invoice row. Needed for reporting. String
campaignID# Alias to campaignIDs#. Use campaignIDs# instead. String

Set this field if you want to indicate that the product was sold as packages. Use it together with "amountOfPackages#".

Packages are product-specific; a product can have zero or more defined packages. To retrieve a product's packages, call getProducts with input parameter getPackageInfo = 1 and see the block productPackages in the output.


Amount of packages sold.

If you specify both amount# and amountOfPackages#, they must correspond to each other: amount# must be equal to amountOfPackages# multiplied by the quantity in one package.

However, it is sufficient to specify only one of the two fields; the second one will be calculated automatically.

batch# Alcohol batch number.

This parameter can be used only when Alcohol Wholesaling module is enabled, otherwise API will return error 1006.
ZIPCode# The next fields are for automatically assigning a tax rate for this line item. You may send all the information about the sales tax (ZIP code, state / county / city names and tax rates), and API will automatically find corresponding tax rate ID, if such a tax already exists in Erply, or create a new one.

To use this feature, ask Erply helpdesk to enable the split tax rate (state tax / county tax / city tax) module on your account.
State# State name. See above. String
County# County name. See above. String
City# County name. See above. String
Category# Tax category (not used right now). See above. String
StateSalesTax# State sales tax %. See above. Decimal
CountySalesTax# County sales tax %. See above. Decimal
CitySalesTax# City sales tax %. See above. Decimal
TotalSalesTax# Must be equal to StateSalesTax + CountySalesTax + CitySalesTax. See above. Decimal
returnReasonID# A reason for returning the item (if document is a return), or for discount (if document is a regular sale). Reasons can be listed with API call getReasonCodes. Note that there are separate reason codes for discounts and returns. Integer
deliveryDate# Customer requested delivery date for this specific item. You can also set a requested delivery date for the whole document, see deliveryDate above.

To use this, you should enable the feature "Delivery date tracking on sales and purchase orders" in Erply backend: Settings » Configuration » Inventory and Purchase: Enable Extra Features.
ISO date (yyyy-mm-dd)

Source document ID. This can be used on invoices, to refer which row originates from which waybill. Erply back office or Actual Reports can provide a printout where invoice rows are grouped by waybill.

Requires CREDITINVOICE or INVOICE document type, API will return error code 1013 for other types.


Recurring billing ID.

Set this field if you want to indicate that this invoice line originates from a recurring billing.

If you specify this field, you must also set "billingStartDate#" and "billingEndDate#". If this ID refers to a metered recurring billing, then "billingReadingIDs#" field is required, too; otherwise API will return error code 1010.

Erply will automatically update billing status; this period for this customer will be marked as billed.

Recurring billing can be set up in back office, in Sales → Recurring billing, or with API call saveBillingStatement.

To be able to set this field, your data model may need updating. If API returns error code 1124, please contact customer support.


A comma-separated list of integers.

You need to specify this field if you want to associate this invoice line with a recurring, metered, billing. Erply will need to know which readings of the meter the invoice must be associated with.

Readings can be entered in back office, when you open a Billing Statement, or with API call saveBillingStatementReading. The list of readings associated with a recurring billing can be queried with API call getBillingStatementReadings.

You are allowed to set this field only if billingStatementID# refers to a billing statement that is based on metered readings. Otherwise, setting this field is forbidden and API will return error code 1013.

If the reading IDs actually belong to another recurring billing, or a different invoice has already been associated with them, API will return error code 1130.

billingStartDate# Billing start date. See previous field. ISO date (yyyy-mm-dd)
billingEndDate# Billing end date. See previous field. ISO date (yyyy-mm-dd)
***** End of invoice rows
***** Additional information about applied discounts:
If you want, you can send detailed information about which promotions, price lists and what amount of manual discount applied to this invoice line, and what was the amount of each discount. This information is used in Erply backend for discount reporting, and can be retrieved with API call getAppliedPromotionRecords.

You must have the respective extra modules enabled on your account:
  • "Promotion Report" for promotions;
  • "Applied Price Lists" for price lists;
  • "Applied Manual Discount" for manual discount.
If you do not have these modules, these fields will be ignored and not written to database. The extra modules can be enabled by customer support.
<brWhen updating an existing document and you define invoice rows, you must resend promotion statistics, too. But if your account has newer inventory module, the document has already been confirmed and it is one of those documents that causes inventory levels to change (an INVWAYBILL, CASHINVOICE, WAYBILL, EXPORTINVOICE, or CREDITINVOICE), then these fields will be ignored, API will keep promotion statistics as it is.

If you use API call calculateShoppingCart to calculate totals and apply price lists and promotions, you do not need to compile this data set manually. calculateShoppingCart outputs records with the same structure, although separately for each invoice line. Gather all the fields prefixed with "promotionRule" and pass them on as input parameters to saveSalesDocument.

Since each invoice line can have multiple promotions and price lists applied, please note how the parameters need to be specified. For an example, let us assume that first invoice line had two discounts on it. First, describe the first discount on first invoice line:
  • promotionRule1amount1
  • promotionRule1finalPrice1
  • promotionRule1totalDiscount1
  • promotionRule1campaignType1
  • promotionRule1campaignDiscountValue1
  • promotionRule1campaignDiscountPercentage1
  • promotionRule1campaignID1
Then, the second discount on first invoice line:
  • promotionRule1amount2
  • promotionRule1finalPrice2
  • promotionRule1totalDiscount2
  • promotionRule1campaignType2
  • promotionRule1campaignDiscountValue2
  • promotionRule1campaignDiscountPercentage2
  • promotionRule1campaignID2
If the second invoice line also had discounts, you can then specify those:
  • promotionRule2amount1
  • ...

If a promotion was applied, but did not give any discounts, you do not need to send this information.
promotionRule#campaignID# Applied promotion ID, if this was a promotion discount.

A record can have either "promotionID" or "priceListID", but not both at the same time. To specify a manual discount, omit both.
promotionRule#priceListID# Applied price list ID, if this was a price list discount.

A record can have either "promotionID" or "priceListID", but not both at the same time. To specify a manual discount, omit both.
promotionRule#amount# What quantity the promotion, price list, or manual discount applied to, on this particular invoice line.

If customer bought 2 or more of this item, but only one was with promotional discount (eg. a Buy One, Get One promotion), then set the value to 1.

If a price list discount applied, then this value should always be equal to row quantity.
promotionRule#finalPrice# Total value (price * quantity) of the discounted items, immediately AFTER applying the discount.

The name of the field is incorrect, but preserved for compatibility.

Please note that this is not the same as "line total". If only some of the items on this invoice line were discounted, this must be the total for these discounted items only.
promotionRule#totalDiscount# Total $ discount given to this invoice line. Decimal
promotionRule#campaignType# "ITEMS" or "INVOICE" — if this was a promotion discount.

"ITEMS" for line or item discounts; "INVOICE" for any discounts that applied to the whole document. (Since there is no "invoice discount" concept in Erply, invoice discounts need to be divided proportinally between invoice lines.)
promotionRule#campaignDiscountValue# Dollar discount that was specified in promotion parameters — if this was a dollar discount promotion. (For instance, if the promotion was "Get $20 off of all shoes", the field value should be 20.). Decimal
promotionRule#campaignDiscountPercentage# Percentage discount as it was defined in promotion description — if this was a percentage discount promotion (eg "10% off"). Decimal
promotionRule#priceListDiscountType# "PRICE" or "DISCOUNT" — if this was a price list discount.

"PRICE" - if the price list applied a fixed price, "DISCOUNT" - if the price list applied a discount percentage.
promotionRule#priceListDiscountPercentage# Discount percentage from the price list (in case the price list discount was percentage-based). Decimal
promotionRule#manualDiscountPercentage# Manual discount percentage — if any manual discount was applied. Decimal
promotionRule#manualDiscountReasonID# Manual discount reason code ID (see getReasonCodes).

To record a manual discount, field promotionRule#manualDiscountPercentage# is required, too; the reason code ID on its own is not sufficient.

If you specify promotionRule#manualDiscountPercentage#, but omit promotionRule#manualDiscountReasonID#, API will use the value of returnReasonID# as a fallback. (returnReasonID# can signify both a return reason and a discount reason, although in a situation where it is important to not mix up the two, it is recommended to use returnReasonID# only for return reasons, and record the manual discount reason with this parameter.)
***** End of discount information
***** Additional attributes associated with this item.
Attributes must be supplied as a flat list, each attribute defined by the following set of three parameters. Replace # with set number (1, 2, 3, ...).

When updating an existing entry, API will only update the attributes specified in input data and leave all other existing attributes unchanged. To delete an attribute, set its value to 'null' or 'undefined'.
attributeName# Attribute name. Name can only contain the following symbols: A-Z, a-z, 0-9, dash and underscore. String
attributeType# Attribute type, possible types are 'text', 'int' and 'double'. By default 'text'. String
attributeValue# Value of the attribute. Set value to 'null' or 'undefined' to delete an attribute.
'text' attribute can be any string, maximum 255 characters.
'int' must be a signed 32-bit integer.
'double' must be a decimal number.
***** End of attribute fields
***** To store strings longer than 255 characters, use "long attributes". (All accounts might not have this capability (API returns error 1006). If necessary, please ask Erply customer support to turn this feature on.)

As with regular attributes, send parameters longAttributeName1 and longAttributeValue1 to store an attribute, longAttributeName2 and longAttributeValue2 to store another etc. The "#" symbol below should be replaced with numbers 1, 2, 3, etc.

When updating an existing entry, API will only update the attributes specified in input data and leave all other existing attributes unchanged. To delete an attribute, set its value to 'null' or 'undefined'.
longAttributeName# Attribute name. Name can only contain the following symbols: A-Z, a-z, 0-9, dash and underscore. String
longAttributeValue# Value of the attribute. Set value to 'null' or 'undefined' to delete an attribute. String (65535)
***** End of long attribute fields


Field name Type Description
invoiceID Integer ID of the created (or updated) document
invoiceNo String Document number.

For unconfirmed sales invoices, this field will be "0" — these documents do not have a number yet, it is assigned when the invoice gets confirmed.

If you assigned a custom number to this sales document (one that may contain letters and other characters), the value of this field will also be "0". See the next field, customNumber, instead.
customNumber String Custom number of the document
invoiceLink String

URL pointing to a HTML version of the invoice.

This URL is valid only for 24 hours; if you want to send the invoice / order by e-mail, you must retrieve the contents of this URL and enclose it as an attachment, instead of sending the URL itself.

Alternatively, instead of the standard printout, you can retrieve a custom printout with API call getSalesDocumentActualReportsHTML, using an Actual Reports template of your choice.

receiptLink String URL pointing to a receipt-sized HTML printout version of the document.

For POS receipts (type = "CASHINVOICE"), both printouts are equivalent, because receipts are always printed in receipt format. The "receiptLink" URL is only necessary for documents that could be printed out either way — eg. orders and laybys.

This URL is valid only for 24 hours; if you want to send the invoice / order by e-mail, you must retrieve the contents of this URL and enclose it as an attachment, instead of sending the URL itself.

This URL is valid only for 24 hours; if you want to send the invoice / order by e-mail, you must retrieve the contents of this URL and enclose it as an attachment, instead of sending the URL itself.
net Decimal (2 places) Net total of the invoice
vat Decimal (2 places) Total VAT of the invoice
rounding Decimal (2 places) Rounding amount applied to invoice total
total Decimal (2 places) Invoice total (= net + vat + rounding)
rows Array
Field nameTypeDescription
rowIDIntegerInvoice row ID. That is a transient value, it changes every time the document is re-saved. This field has only been provided to provide an easier mapping between getSalesDocuments and getAppliedPromotionRecords.
stableRowIDIntegerStable row ID. ID that will be persisted for the row if the row is the same between saves.
productIDIntegerProduct ID.

The item on the invoice may be either:
  • a product;
  • a service (although services are deprecated and disabled entirely on newer accounts, so most likely you can ignore that option);
  • or a free-text item (in which case both productID and serviceID are 0 and the only information is item name in the field itemName.
serviceIDIntegerService ID.

Please note that services are deprecated and we recommend to use non-stock products instead.
amountDecimalSold quantity.