Number ranges
Delivery notes and loans carry a number that is printed on the document. Numbers have to be assigned while offline, so there are two modes: the device formats numbers itself, or it uses numbers it reserved from the server earlier.
Format placeholders
Section titled “Format placeholders”A number format is a text with placeholders:
| Placeholder | Replaced by | Device | Server |
|---|---|---|---|
{YYYY} |
four-digit year | yes | yes |
{YY} |
two-digit year, 26 |
yes | yes |
{MM} |
two-digit month, 03 |
yes | yes |
{DEV} |
device code | yes | no, stays as written |
{SEQ} |
counter without padding | yes | yes |
{SEQ:n} |
counter padded with zeros to n digits (n is 1 or 2 digits); longer counters are not cut |
yes | yes |
Other text is copied as it is. Dates are calendar dates in the time zone of the formatter: the device's time zone on the device, the business time zone on the server.
Differences between the reference implementations, which implementers of either side should match:
| Case | Reference app (device) | Reference server |
|---|---|---|
Format without {SEQ} |
appends the counter: LS gives LS3 |
no counter: LS gives LS for every number |
Several {SEQ} |
only the first is replaced | all are replaced |
{DEV} |
replaced by the device code | left as written |
Examples, from test-vectors/numbering.json:
| Format | Date | Counter | Device code | Device result | Server result |
|---|---|---|---|---|---|
LS-{YYYY}-{DEV}-{SEQ:4} |
2026-03-09 | 42 | B |
LS-2026-B-0042 |
|
{YY}{MM}/{SEQ} |
2026-03-09 | 7 | B |
2603/7 |
|
LS-{YYYY}-{SEQ:5} |
2026-10-12 | 41 | LS-2026-00041 |
||
LS-{DEV}-{SEQ:3} |
2026-10-12 | 41 | LS-{DEV}-041 |
Device numbering
Section titled “Device numbering”In device mode (document_template.numbering.mode is device or absent), each device formats numbers from numbering.format (default LS-{YYYY}-{DEV}-{SEQ:4}), its own device code and its own counter.
- The device code keeps numbers of different devices apart. The reference app defaults it to the first two characters of the node id (
3Ffor node3F2A9C1B) and lets the user change it. Two devices with the same code can produce the same number; the protocol accepts duplicate numbers. - The counter is kept on the device and is not synchronised. It starts at 1 and increases with every number taken. When the format contains
{YYYY}or{YY}, it restarts at 1 with the first number of a new calendar year. The user can set the next value in the app. numbering.nextin the template is reserved; the reference app neither reads nor writes it.
Device numbers are unique per device but not consecutive across the inventory.
Server numbering
Section titled “Server numbering”In server mode (numbering.mode is server), numbers come from the server's number range. To number offline, the client reserves numbers in blocks while it is online:
sequenceDiagram
autonumber
participant C as Client
participant S as Server
Note over C: end of sync round,<br/>template says server numbering,<br/>3 reserved numbers left
C->>S: POST /lve/v1/number-ranges/delivery_note/reserve {count: 25}
Note over S: in one transaction: counter for<br/>"delivery_note:2026" += 25
S-->>C: {key, numbers: [LS-2026-00041 ... LS-2026-00065]}
Note over C: append to the reserved list
Note over C: offline: each new delivery note<br/>takes the first reserved number
Note over C: list empty: fall back to the device format
Request
Section titled “Request”POST /lve/v1/number-ranges/delivery_note/reserve HTTP/1.1Authorization: Bearer 7|kM2p...Content-Type: application/json
{ "count": 25 }| Part | Rules |
|---|---|
key (path) |
The number range. [a-z0-9_]+. The only key in version 1 is delivery_note. |
count |
Integer from 1 to 100. |
Response
Section titled “Response”{ "key": "delivery_note", "numbers": ["LS-2026-00041", "LS-2026-00042", "LS-2026-00043"] }numbers holds exactly count formatted numbers in ascending order.
| Status | Code | When |
|---|---|---|
200 |
Numbers reserved | |
401 |
unauthenticated |
Token missing or revoked |
404 |
not_found |
Unknown key |
422 |
validation_failed |
count missing, not an integer, below 1 or above 100 |
Guarantees
Section titled “Guarantees”- The server hands out every number once, across all devices and users. Concurrent reservations never overlap.
- Numbers within one response are consecutive. Numbers of the server's counter have no gaps when they are handed out.
- Reserved numbers belong to the device that reserved them. A device that never uses a number, loses its reserved list (disconnect, reinstall) or loses a response leaves a gap in the printed sequence. The protocol does not return unused numbers.
- The counter restarts at 1 in every calendar year of the server's business time zone, whatever the format contains. The reference server keeps one counter per key and year (
delivery_note:2026) and decides the year inLVE_TIMEZONE(defaultEurope/Berlin), so a reservation at 00:30 on 1 January in Berlin starts the new year although it is still 31 December in UTC. - A server formats numbers with its own format (
LVE_DELIVERY_NOTE_FORMATon the reference server, defaultLS-{YYYY}-{SEQ:5}). The template'snumbering.formatis not sent to the server and only applies to device numbering and the fallback.
So that server numbers can be "gapless per year" in practice, devices should reserve small blocks and keep using them up; the reference app reserves 25 at a time.
Client behaviour
Section titled “Client behaviour”The reference app:
- reserves 25 numbers at the end of a sync round when the delivery note template is in server mode and fewer than 5 reserved numbers are left; a failed reservation is ignored and tried again next round,
- takes reserved numbers oldest first,
- falls back to device numbering with
numbering.formatwhen no reserved number is left, - keeps reserved numbers across years (a number reserved in December may be used in January),
- drops all reserved numbers when it disconnects from the server.
A server without number ranges leaves number_ranges out of features and answers the endpoint with 404. Clients should then use device numbering.
Loan numbers
Section titled “Loan numbers”Loans are always numbered on the device, with their own counter and the fixed format UE-{YYYY}-{DEV}-{SEQ:4} (UE for Übergabe, handover), for example UE-2026-3F-0001. The counter restarts every calendar year. There is no server number range for loans in version 1.