Skip to content

Document elements ​

Document elements are line items on an Invoice or Offer object.

Locked documents ​

Once an offer or invoice is locked (is_locked: true, i.e. sent or issued), its line items are frozen. Creating, cloning, reordering or deleting an element, or changing what it charges, fails with 422 Unprocessable Entity and a translated message:

json
// HTTP 422 Unprocessable Entity
{
    "message": "This document is locked. Its line items can only be changed again after you mark it as draft."
}

These changes stay possible on a locked document:

  • tag_id and page_break of any element
  • revenue_account_no of any element, as long as the invoice's booking is not in a closed fiscal year — otherwise the request fails with 422 and the invoice keeps its booking
  • on a locked offer, an optional element (is_optional: true) may be taken over (is_optional: false) or deleted

Sending unchanged values along with an allowed change is fine — only attributes whose value actually changes count. Mark the document as draft first to edit its line items freely.

The same rule applies to the add products to an offer and add products to an invoice endpoints.

Allowed query parameters ​

Filters ​

FilterTypeDescription
searchStringFull-text search
document_typeStringA document type
(Modules\Salesforce\Invoice, Modules\Salesforce\Offer)
document_idStringA document Id (Invoice or Offer)

Includes ​

document, vatRate, rate, tag, product.tag, product.unit, account

Create an element ​

post
/document_element
Attribute (* required)TypeDescription
document_type *StringModules\Salesforce\Invoice, Modules\Salesforce\Offer
document_id *StringA document Id (Invoice or Offer)
name *StringPosition title
descriptionString?Position text
remarkString?Position remark
type *StringPosition type (paragraph, heading, percentage, subtotal)
unitString?Position unit
quantityFloat?Position quantity
amountFloat?Position amount
vat_rate_idString?VAT Rate ID
tag_idString?Tag ID
is_externalBooleanWhether the element is external
is_excluded_from_budgetBooleanWhether the element is excluded from budget
is_optionalBooleanWhether the element is optional
discount_typeString?Discount type enum value
discount_valueFloat?Discount value
product_idString?A product Id (Product)
page_breakString?Page break position (before, after)
revenue_account_noString?Revenue account number

Example response ​

json
// HTTP 201 Created
{
    // an element object
}

Update an element ​

put
/document_element/{id}
Attribute (* required)TypeDescription
nameStringPosition title
descriptionString?Position text
remarkString?Position remark
typeStringPosition type (paragraph, heading, percentage, subtotal)
unitString?Position unit
quantityFloat?Position quantity
amountFloat?Position amount
vat_rate_idString?VAT Rate ID
tag_idString?Tag ID
is_externalBooleanWhether the element is external
is_excluded_from_budgetBooleanWhether the element is excluded from budget
is_optionalBooleanWhether the element is optional
discount_typeString?Discount type enum value
discount_valueFloat?Discount value
product_idString?A product Id (Product)
page_breakString?Page break position (before, after)
revenue_account_noString?Revenue account number

An element always stays on the document it was created on: document_type and document_id are ignored on update and clone.

Example response ​

json
// HTTP 200 OK
{
    // an element object
}

Retrieve an element ​

get
/document_element/{id}

Example response ​

json
// HTTP 200 OK
{
    "id": "1A5m6kqoVw",
    "order": 1,
    "name": "Client Meeting",
    "type": "paragraph",
    "description": "2 Std. Administration à 100.00/Std.",
    "remark": "",
    "quantity": 2,
    "amount": 100,
    "vat_rate": 7.7,
    "vat_rate_id": "abc123",
    "unit": null,
    "has_discount": false,
    "discount_value": null,
    "discount_type": null,
    "discount_total": null,
    "discount_formatted": null,
    "total": 200,
    "subtotal_at_position": null,
    "percentage": null,
    "is_external": false,
    "is_optional": false,
    "is_excluded_from_budget": false,
    "revenue_account_no": "3400",
    "account": null,
    "data": null,
    "page_break": null,
    "rate": null,
    "tag": null,
    "document": {
        // A document object (Invoice or Offer)
    },
    "product": {
        // A product object
    }
}

Delete an element ​

delete
/document_element/{id}

Example response ​

json
// HTTP 204 No Content

Delete many elements ​

post
/document_element/delete-many

Deletes multiple document elements at once. The request body is a JSON array of element ids. Returns 200 OK with deleted and skipped arrays; elements of a locked document are reported under skipped (reason: "document_locked") and left intact — see Bulk delete.

List elements ​

To list a documents elements, you may include the elements relation when retrieving an Invoice or Offer object.

get
/invoice/{id}?include=elements

Example response ​

json
// HTTP 200 OK
{
    "id": "D4rNdYjlGy",
    "number": "RE-01234",
    "name": "Jahresretainer 2023",
    ...
    "elements": [
        // an array of document elements
    ]
}