Document lifecycle
Create, update, lock and process a document, create one document from another, and print it.
This page follows a document from creation to processing. The examples use a delivery note, the document that issues goods from a warehouse to a customer. Other document types work the same way under their own route; see Anatomy of a document for the list.
Create
POST the header, with or without items, to the collection route.
curl -X POST https://<your-instance>/api/documents/expedition/delivery-notes \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customerId": 1042,
"warehouseId": 1,
"formNumber": "DN-2026-0418",
"items": [
{
"productId": 733,
"quantityIssued": 4,
"unitIdIssued": 1,
"priceWoVat": 100,
"price": 121,
"vatRate": 21
}
]
}'What happens on the server:
- Validation comes first. The whole request is checked before anything is written. If it is invalid you get
400andmessageslists every violation at once, so you can fix them all in one go. See Errors. - An internal number is reserved. On insert the server assigns the next
internalNumberof that document type. You cannot choose it. Put your own reference informNumber. - The stored document comes back. The response body is the document as saved, including its new
id, the ids of its items and the calculated totals. Keep theid: every later call needs it.
Which fields are required depends on the document type. For delivery notes and orders the header needs a customerId and a warehouseId. An item needs a productId, a quantity and, as a group, a unit, a price and a VAT rate. The request examples on each create endpoint's reference page show the minimal valid bodies.
Update
PUT /api/documents/…/{documentId} updates the header and the items you send. The body has the same shape as on create.
- Header fields you send are written. Header fields you leave out keep their stored value.
- An item in the body with an
idupdates that stored item. - An item without an
idis added as a new item. - Stored items that are missing from the body are kept, unless you add
?removeItemsNotInRequest=true. Then they are deleted, and the body becomes the complete list of items.
curl -X PUT "https://<your-instance>/api/documents/expedition/delivery-notes/77120" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"note": "Deliver to the back entrance",
"items": [
{ "id": 301555, "note": "Fragile" }
]
}'Do not send back the fields the server maintains itself, such as isProcessed, isLocked, lockOwner, createdAt, lastModify and the totals. They are calculated, not stored from your request.
Some header fields are fixed once the document exists. The warehouse of a delivery note cannot be changed, for example. The server answers 400 and says which field it objects to.
Change single items
To touch only the items, you do not have to send the whole document:
| Request | Effect |
|---|---|
POST …/{documentId}/items | Add items. The body is an array of items. |
PUT …/{documentId}/items/{itemId} | Update one item. |
The document totals are recalculated after each of them. To remove items, see Deleting.
Locks
A lock marks a document as being edited. When a user opens a document in WinShop, it is locked in their name until they close it. The lock exists so that two parties do not overwrite each other's changes.
| Request | Effect |
|---|---|
GET …/{documentId}/lock | Returns the lock state. |
POST …/{documentId}/lock | Locks the document in the name of your API client. Fails with 400 if it is already locked. |
DELETE …/{documentId}/lock | Releases the lock. Fails with 400 if the lock belongs to someone else. |
The lock state is a DocumentLockState:
{ "isLocked": true, "lockOwner": "Jana Novakova" }A locked document cannot be changed
While a document is locked, PUT, the item endpoints and process fail. The answer is 400 Bad Request, not 409, and it carries no code. You recognise it by the message:
"messages": ["Document is locked by Jana Novakova. Document needs to be closed."]
What this means for an integration:
- Before a change, or when a change fails with the message above, read the lock state. If the document is locked, a person has it open. Wait and retry later; do not try to break the lock.
- The lock blocks changes no matter who holds it. If your own client locked the document, release the lock before you send the change.
- For a long-running interactive edit in your own user interface, take the lock when the user opens the document and release it when they are done, so that WinShop users see the document as in use.
Process
POST …/{documentId}/process posts the document. What that means depends on the type: processing a delivery note takes the goods off stock, processing an intake puts them on stock, processing an internal transfer moves them between warehouses.
curl -X POST https://<your-instance>/api/documents/expedition/delivery-notes/77120/process \
-H "Authorization: Bearer $ACCESS_TOKEN"Processing cannot be undone
There is no "unprocess" endpoint. After processing, isProcessed is true and the document is closed for changes: a
PUT or an item change fails with 400 and the message Cannot update an already processed document.
- Processing fails if the document is already processed or is locked.
- Only document types that move stock have
process: intakes, delivery notes, write-offs and internal transfers. Orders and claims have no such step. - Some types still have an older
POST …/{documentId}/finishroute. It is a deprecated alias ofprocessand will be removed. Useprocess.
Create one document from another
Some documents are created from an existing one instead of from scratch. The main case is invoicing a delivery note:
curl -i -X POST https://<your-instance>/api/documents/expedition/delivery-notes/77120/invoice \
-H "Authorization: Bearer $ACCESS_TOKEN"HTTP/1.1 201 Created
Location: https://<your-instance>/api/documents/invoices/5120The answer is 201 Created, and the Location header points at the new invoice. Follow it to read the invoice.
To put several delivery notes on one invoice, use POST /api/documents/expedition/delivery-notes/invoice with their ids in deliveryNoteIds. See Create an invoice from delivery notes.
GET …/{documentId}/pdf returns the document as a PDF file, rendered with the print template the customer has configured for that document type.
curl https://<your-instance>/api/documents/expedition/delivery-notes/77120/pdf \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-o delivery-note-77120.pdfThe response is binary (application/pdf), not JSON. If the document has no printable output, the answer is 404.
Reference
The delivery note endpoints used on this page: