Zum Inhalt

API-Referenz

Die REST-API des Druckservers (tavletta serve) für Programme, die Etiketten drucken: jede Anfrage mit ihrer Rolle, ihren Feldern, Antworten und Fehlercodes. Eine Anleitung für ein Inventarprogramm mit Code in Python und C# ist Ein Inventarprogramm anbinden; die Installation des Servers Serverinstallation.

Diese Seite entsteht aus der OpenAPI-3.1-Beschreibung des Servers (tools/openapi_docs.py). Programme und Codegeneratoren lesen dieselbe Beschreibung: docs/openapi.yaml im Quellcode oder GET /api/v1/openapi.json von einem laufenden Server.

Grundlagen

  • Adresse: http://<server>:8790/api/v1 oder die HTTPS-Adresse des Reverse Proxys. Die Beispiele verwenden $TAVLETTA dafür und $TOKEN für das Zugangstoken:
TAVLETTA=https://labels.example.com/api/v1
TOKEN=tav_0123456789ab_...
  • JSON hinein und heraus (UTF-8). Anfragen mit Inhalt brauchen Content-Type: application/json und eine Content-Length.
  • Jede Anfrage ausser GET /api/v1/health braucht den Header Authorization: Bearer <token>.
  • Meldungen kommen in der Sprache von Accept-Language (z. B. de-CH), sonst auf Englisch. Codes ändern sich nie mit der Sprache: Programme prüfen den Code, Menschen lesen die Meldung.
  • Unbekannte Felder werden abgewiesen (unknown_field): Ein Tippfehler druckt nie etwas anderes als gemeint.

Rollen

Jedes Zugangstoken hat eine Rolle (tokens.toml, erstellt mit tavletta token new). Eine Rolle darf, was die Rollen darüber dürfen.

Rolle Darf
preview Drucker und Etiketten auflisten, Etiketten beschreiben, Vorschauen, Druckerzustand, diese Beschreibung
print wie preview, und drucken; die eigenen Aufträge sehen und abbrechen
admin wie print, und jeden Auftrag sehen und abbrechen

Ein Token kann auf einige Drucker aus printers.toml beschränkt werden: Die anderen sind für es dann "nicht gefunden" (404 printer_not_found).

Fehler

Jeder Fehler ist JSON mit einem festen Code und einer Meldung für Menschen:

{"error": {"code": "label_not_found", "message": "No such label: asset-tag.tavletta"}}
Status Code Bedeutung
400 bad_request Die Anfrage lässt sich nicht lesen (z. B. ein Inhalt, der zu früh endet).
400 not_json Der Inhalt ist kein gültiges JSON (415 mit einem anderen Content-Type).
400 invalid_field Ein Feld hat einen falschen Typ oder Wert; die Meldung nennt es.
400 unknown_field Ein Feld, das die Anfrage nicht kennt (ein Tippfehler): Es geschieht nichts.
400 no_label Entweder label oder label_content angeben.
400 data_conflict data_rows oder data_file angeben, nicht beides.
400 no_rows rows wählt keine Datenzeile.
400 no_data sheet ohne Datendatei.
400 no_printer Mehrere Drucker und kein Standard: einen in printer nennen.
400 no_host Keine Druckeradresse (ohne printers.toml).
400 host_given host mit printers.toml: den Drucker mit Namen wählen.
400 too_many_copies Mehr Kopien als max_copies des Druckers.
401 unauthorized Token fehlt, ist falsch, abgelaufen oder widerrufen.
403 forbidden Die Rolle des Tokens reicht nicht (z. B. preview druckt).
403 host_not_allowed Die Druckeradresse ist nicht erlaubt (--allow-printer).
403 origin_not_allowed Eine Webseite einer nicht erlaubten Herkunft (--allow-origin).
403 header_required Kein Token auf dem Server: X-Tavletta-Request senden.
404 not_found Kein solcher Pfad.
404 label_not_found Keine solche Etikettendatei im Etikettenordner.
404 data_not_found Keine solche Datendatei im Etikettenordner.
404 printer_not_found Kein solcher Drucker, oder einer, den das Token nicht verwenden darf.
404 job_not_found Kein solcher Auftrag (der eines anderen Tokens oder älter als 24 Stunden).
405 method_not_allowed Keine Methode dieses Pfads.
408 timeout Das Senden der Anfrage dauerte länger als 30 s.
409 job_finished Der Auftrag ist fertig: nichts abzubrechen.
409 counter_not_saved Die Etikettendatei ist nicht beschreibbar: Es wurde nichts gedruckt.
411 length_required Keine Content-Length (Inhalte in Stücken, chunked, werden nicht angenommen).
413 too_large Inhalt über --max-body, oder zu viele Datenzeilen, Spalten oder Zellen.
413 too_many_labels Kopien mal Zeilen über --max-labels (standardmässig 10000).
413 label_too_large Das Etikett ist zu gross zum Zeichnen (Elemente, Text, Pixel).
415 not_json Content-Type: application/json senden.
421 wrong_host Ein Server auf Loopback wurde nach einem anderen Hostnamen gefragt.
422 file_problem Die Etikettendatei lässt sich nicht öffnen.
422 label_not_label Die Datei ist kein Tavletta-Etikett.
422 label_newer Das Etikett braucht ein neueres Tavletta: den Server aktualisieren.
422 label_damaged Die Etikettendatei ist beschädigt.
422 label_unprintable Es würde falsch gedruckt: eine fehlende Spalte, ein ungültiger Code …
422 pages_not_allowed Dokumentseiten in label_content brauchen den Server-Schalter --allow-pdf-pages.
422 data_outside Die Datendatei des Etiketts liegt ausserhalb des Etikettenordners.
422 data_problem Die Datendatei lässt sich nicht lesen oder hat kein solches Blatt.
422 prepare_failed Das Etikett lässt sich nicht für den Drucker aufbereiten.
429 too_many_requests Zehn falsche Tokens von dieser Adresse: eine Minute warten.
429 queue_full Zu viele wartende Aufträge: später wiederholen.
500 internal Ein Fehler des Servers; er wird protokolliert.
502 printer_<code> Der Drucker ist nicht erreichbar oder meldet ein Problem.
503 busy Alle Anfrage- oder Zeichenplätze belegt: nach einem Moment wiederholen.

printer_<code>: das Problem des Druckers, einer von generic, not_found, timeout, stalled, port_closed, busy, paused, cover_open, head_open, jam, media_jam, out_of_labels, out_of_paper, label_not_found, wrong_media, paper_size, page_too_large, too_long, too_wide, code_too_large, ribbon, ribbon_out, ribbon_direct, no_cassette, bad_cassette, supplies, format, resolution, queue_paused, job_held, job_canceled, usb_not_found, usb_permission, serial_permission, battery, overheat, unsupported_model, unknown_model, editor_lite.

Ein fehlgeschlagener Auftrag sagt in seinem error warum, mit diesen Codes:

Code Bedeutung
printer_<code> Der Drucker ist nicht erreichbar oder meldet ein Problem (Stau, keine Etiketten mehr …).
counter_not_saved Gedruckt, aber der nächste Zählerwert konnte nicht gespeichert werden.
label_locked Ein anderer Druck hielt die Etikettendatei zu lange.
prepare_failed Das Etikett liess sich nicht für den Drucker aufbereiten.

Grenzen

Was Grenze
Inhalt einer Anfrage 4 MB (--max-body)
Datenzeilen, Spalten, Zellen 100 000, 1000, 2 000 000
Ein Wert oder eine Zelle 100 000 Zeichen
Kopien 9999 oder max_copies des Druckers
Etiketten in einem Auftrag (Kopien mal Zeilen) 10 000 (--max-labels)
Elemente eines Etiketts 200, davon 50 Bilder und Codes; 5000 Zeichen und 100 Zeilen pro Text
Wartende oder druckende Aufträge 100 insgesamt, 20 pro benanntem Token
Aufbewahrte fertige Aufträge 24 Stunden, höchstens 1000
wait 300 Sekunden
Gleichzeitige Anfragen 32, 8 pro Client-Adresse
Falsche Tokens 10 pro Minute und Adresse, dann 429 für eine Minute

Anfragen

Neben den Antworten, die bei jeder Anfrage stehen, kann jede Anfrage die allgemeinen Fehler der Tabelle oben bekommen: 401, 403, 405, 408, 421, 429 (too_many_requests), 500 und 503, und eine mit Inhalt 411, 413 (too_large) und 415.

Anfrage Rolle Was
GET /api/v1/health keine Läuft der Server; ohne Token (für Health Checks)
GET /api/v1/openapi.json preview Diese Beschreibung (OpenAPI 3.1); ein Token mit beliebiger Rolle
GET /api/v1/printers preview Die Drucker aus printers.toml, die das Token verwenden darf, mit ihrem Zustand; ohne die Datei die Druckermodelle, die für jedes eingestellte Adresse und die gefundenen Drucker (--discover)
GET /api/v1/printers/{id}/status preview Einen Drucker nach seinem Zustand fragen: Material, Probleme, Auflösung
GET /api/v1/labels preview Die Etikettendateien im Etikettenordner und seinen Unterordnern
GET /api/v1/labels/{name} preview Womit ein Etikett gefüllt werden kann: Elemente, Variablen, Datenspalten, Grösse, Zähler
POST /api/v1/preview preview Das ausgefüllte Etikett als Bild; es wird nichts gedruckt
POST /api/v1/print print Drucken: Die Anfrage wird geprüft und dann eingereiht; jeder Drucker druckt einen Auftrag nach dem anderen
GET /api/v1/jobs/{id} print Zustand eines Druckauftrags (ein print-Token: seine eigenen Aufträge; admin: alle). 24 Stunden nach dem Ende aufbewahrt
DELETE /api/v1/jobs/{id} print Einen Auftrag abbrechen: sofort, solange er wartet, nach dem aktuellen Etikett, während er druckt

GET /api/v1/health

Läuft der Server; ohne Token (für Health Checks).

  • Rolle: keine (ohne Token)
Status Antwort Codes
200 Läuft
curl "$TAVLETTA/health"

GET /api/v1/openapi.json

Diese Beschreibung (OpenAPI 3.1); ein Token mit beliebiger Rolle.

  • Rolle: preview
Status Antwort Codes
200 OpenAPI
curl -H "Authorization: Bearer $TOKEN" \
     "$TAVLETTA/openapi.json"

GET /api/v1/printers

Die Drucker aus printers.toml, die das Token verwenden darf, mit ihrem Zustand; ohne die Datei die Druckermodelle, die für jedes eingestellte Adresse und die gefundenen Drucker (--discover).

  • Rolle: preview
Parameter In Bedeutung
X-Tavletta-Request Header Nötig (beliebiger Wert), wenn der Server kein Token hat: Eine Webseite kann ihn nicht senden und den Server so keine Drucker ansprechen lassen.
discover Query Ohne printers.toml und mit --discover: suchen. Standard true
status Query Jeden Drucker aus printers.toml nach seinem Zustand fragen (5 s gemerkt). Standard true
Status Antwort Codes
200 Drucker
curl -H "Authorization: Bearer $TOKEN" \
     "$TAVLETTA/printers"

GET /api/v1/printers/{id}/status

Einen Drucker nach seinem Zustand fragen: Material, Probleme, Auflösung.

  • Rolle: preview
Parameter In Bedeutung
X-Tavletta-Request Header Nötig (beliebiger Wert), wenn der Server kein Token hat: Eine Webseite kann ihn nicht senden und den Server so keine Drucker ansprechen lassen.
id Pfad Druckername (printers.toml) oder ID des Druckermodells.
host Query Nur ohne printers.toml; braucht die Rolle print.
Status Antwort Codes
200 Zustand
400 Keine Adresse, oder host angegeben mit printers.toml no_host, host_given, invalid_field
404 Unbekannter Drucker, oder einer, den das Token nicht verwenden darf printer_not_found
502 Der Drucker ist nicht erreichbar oder meldet ein Problem printer_<code>
curl -H "Authorization: Bearer $TOKEN" \
     "$TAVLETTA/printers/it-cab/status"

GET /api/v1/labels

Die Etikettendateien im Etikettenordner und seinen Unterordnern.

  • Rolle: preview
Status Antwort Codes
200 Etiketten
curl -H "Authorization: Bearer $TOKEN" \
     "$TAVLETTA/labels"

GET /api/v1/labels/{name}

Womit ein Etikett gefüllt werden kann: Elemente, Variablen, Datenspalten, Grösse, Zähler.

  • Rolle: preview
Parameter In Bedeutung
name Pfad Darf Schrägstriche für Unterordner enthalten; '.tavletta' darf fehlen.
Status Antwort Codes
200 Etikett
400 Kein Name innerhalb des Etikettenordners invalid_field
404 Kein solches Etikett label_not_found
422 Die Datei ist kein Etikett oder beschädigt file_problem, label_not_label, label_newer, label_damaged
curl -H "Authorization: Bearer $TOKEN" \
     "$TAVLETTA/labels/asset-tag"

POST /api/v1/preview

Das ausgefüllte Etikett als Bild; es wird nichts gedruckt.

  • Rolle: preview

Felder des Inhalts:

Feld Typ Bedeutung
label string Name einer Etikettendatei im Etikettenordner (siehe GET /labels), Unterordner mit '/'; '.tavletta' darf fehlen. Entweder label oder label_content.
label_content object Oder das Etikett selbst, als JSON einer .tavletta-Datei, geprüft wie eine geöffnete Datei. Seine Datendatei wird nicht verwendet (stattdessen data_rows schicken), sein Zähler nie gespeichert.
printer string Mit printers.toml auf dem Server: der Name des Druckers (Standard: der Standarddrucker, den das Token verwenden darf, oder der einzige). Ohne die Datei: die ID eines Druckermodells, wenn nicht das des Etiketts (das Etikett wird wie in der App angepasst).
set object Elementname oder Variablenname -> Wert, wie --set auf der Kommandozeile; Variablen in einem Wert werden gefüllt; 'date' setzt den Zeitpunkt, von dem {=date} und {=time} ausgehen (ISO 8601). Höchstens 1000 Einträge.
set_literal object Wie set, aber geschweifte Klammern in einem Wert sind Text, keine Variablen.
counter_start integer Der {=counter} des ersten Etiketts; er steigt um den Schritt des Etiketts mit jedem Etikett, jeder Kopie und Zeile. 0 bis 999999999999999
data_rows array of object Serienetiketten: ein Etikett pro Zeile, Spaltenname -> Wert; die Platzhalter {Column} des Etiketts nehmen die Werte. Zahlen werden als Text genommen, null als leere Zelle. Höchstens 100000 Zeilen, 1000 Spalten, 2000000 Zellen, 100000 Zeichen pro Wert.
data_file string Oder eine CSV-, TSV-, ODS- oder XLSX-Datei im Etikettenordner. Ohne data_rows und data_file wird die eigene Datendatei des Etiketts verwendet, wenn sie neben dem Etikett im Etikettenordner liegt.
sheet string Blatt der Datendatei, standardmässig das erste.
row integer Gezeigte Datenzeile, ab 1. 1 bis 100000; Standard 1
format "png" | "json" 'json': Breite, Höhe, Warnungen und das PNG in Base64. Standard "png"
view "preview" | "printer" 'printer': das Bild, wie der Drucker es bekommt (gedreht, in seinen Farben). Standard "preview"
Status Antwort Codes
200 PNG, oder JSON mit format=json. Warnungscodes auch im Header X-Tavletta-Warnings (durch Kommas getrennt).
400 Ungültige Anfrage bad_request, invalid_field, unknown_field, no_label, data_conflict, not_json, no_rows, no_data, no_printer, too_many_copies
404 Kein solches Etikett, kein solcher Drucker oder keine solche Datendatei label_not_found, printer_not_found, data_not_found
413 Zu gross: Inhalt, Datenzeilen oder das zu zeichnende Etikett too_large, label_too_large
422 Das Etikett oder seine Daten lassen sich nicht verwenden file_problem, label_not_label, label_newer, label_damaged, label_unprintable, data_outside, data_problem, prepare_failed
curl -H "Authorization: Bearer $TOKEN" \
     -H 'Content-Type: application/json' \
     -d '{"label": "asset-tag", "printer": "it-cab", "data_rows": [{"AssetNumber": "100001"}], "format": "png"}' \
     -o preview.png \
     "$TAVLETTA/preview"

POST /api/v1/print

Drucken: Die Anfrage wird geprüft und dann eingereiht; jeder Drucker druckt einen Auftrag nach dem anderen.

  • Rolle: print

Felder des Inhalts:

Feld Typ Bedeutung
label string Name einer Etikettendatei im Etikettenordner (siehe GET /labels), Unterordner mit '/'; '.tavletta' darf fehlen. Entweder label oder label_content.
label_content object Oder das Etikett selbst, als JSON einer .tavletta-Datei, geprüft wie eine geöffnete Datei. Seine Datendatei wird nicht verwendet (stattdessen data_rows schicken), sein Zähler nie gespeichert.
printer string Mit printers.toml auf dem Server: der Name des Druckers (Standard: der Standarddrucker, den das Token verwenden darf, oder der einzige). Ohne die Datei: die ID eines Druckermodells, wenn nicht das des Etiketts (das Etikett wird wie in der App angepasst).
set object Elementname oder Variablenname -> Wert, wie --set auf der Kommandozeile; Variablen in einem Wert werden gefüllt; 'date' setzt den Zeitpunkt, von dem {=date} und {=time} ausgehen (ISO 8601). Höchstens 1000 Einträge.
set_literal object Wie set, aber geschweifte Klammern in einem Wert sind Text, keine Variablen.
counter_start integer Der {=counter} des ersten Etiketts; er steigt um den Schritt des Etiketts mit jedem Etikett, jeder Kopie und Zeile. 0 bis 999999999999999
data_rows array of object Serienetiketten: ein Etikett pro Zeile, Spaltenname -> Wert; die Platzhalter {Column} des Etiketts nehmen die Werte. Zahlen werden als Text genommen, null als leere Zelle. Höchstens 100000 Zeilen, 1000 Spalten, 2000000 Zellen, 100000 Zeichen pro Wert.
data_file string Oder eine CSV-, TSV-, ODS- oder XLSX-Datei im Etikettenordner. Ohne data_rows und data_file wird die eigene Datendatei des Etiketts verwendet, wenn sie neben dem Etikett im Etikettenordner liegt.
sheet string Blatt der Datendatei, standardmässig das erste.
host string Druckeradresse, nur ohne printers.toml (Standard: die in der App eingestellte, sonst mit --discover der einzige gefundene Drucker). Abgewiesen (host_given) mit printers.toml.
copies integer Kopien jedes Etiketts (jeder Zeile); höchstens max_copies des Druckers. Kopien mal Zeilen: höchstens --max-labels (standardmässig 10000). 1 bis 9999; Standard 1
rows string Die zu druckenden Datenzeilen, ab 1: '3-10', '5', '7-' (bis zur letzten) oder '-4'. Um dort weiterzudrucken, wo ein Auftrag anhielt.
no_save_counter boolean Den nächsten {=counter}-Wert nicht in der Etikettendatei speichern. Standard false
wait number Sekunden, die auf das Ende des Auftrags gewartet wird, bevor die Antwort kommt: 200, wenn er fertig wurde, sonst 202. 0 bis 300.0; Standard 0
Status Antwort Codes
200 Der Auftrag wurde innerhalb von 'wait' fertig
202 Eingereiht oder am Drucken; unter Location verfolgen
400 Ungültige Anfrage bad_request, invalid_field, unknown_field, no_label, data_conflict, not_json, no_rows, no_data, no_printer, no_host, host_given, too_many_copies
404 Kein solches Etikett, kein solcher Drucker oder keine solche Datendatei, oder ein Drucker, den das Token nicht verwenden darf label_not_found, printer_not_found, data_not_found
409 Die Etikettendatei ist nicht beschreibbar: Der nächste Zählerwert liess sich nicht speichern, es wurde nichts gedruckt counter_not_saved
413 Zu gross: Inhalt, Datenzeilen, Etiketten in einem Auftrag oder das zu zeichnende Etikett too_large, too_many_labels, label_too_large
422 Das Etikett würde falsch gedruckt file_problem, label_not_label, label_newer, label_damaged, label_unprintable, data_outside, data_problem
429 Zu viele falsche Tokens, oder zu viele wartende Aufträge (100 insgesamt, 20 pro benanntem Token) too_many_requests, queue_full
curl -H "Authorization: Bearer $TOKEN" \
     -H 'Content-Type: application/json' \
     -d '{"label": "asset-tag", "printer": "it-cab", "data_rows": [{"AssetNumber": "100001"}], "wait": 30}' \
     "$TAVLETTA/print"

GET /api/v1/jobs/{id}

Zustand eines Druckauftrags (ein print-Token: seine eigenen Aufträge; admin: alle). 24 Stunden nach dem Ende aufbewahrt.

  • Rolle: print
Parameter In Bedeutung
id Pfad Die id aus POST /print.
Status Antwort Codes
200 Auftrag
404 Kein solcher Auftrag job_not_found
curl -H "Authorization: Bearer $TOKEN" \
     "$TAVLETTA/jobs/$JOB"

DELETE /api/v1/jobs/{id}

Einen Auftrag abbrechen: sofort, solange er wartet, nach dem aktuellen Etikett, während er druckt.

  • Rolle: print
Parameter In Bedeutung
id Pfad Die id aus POST /print.
Status Antwort Codes
202 Abgebrochen, oder hält nach dem aktuellen Etikett an
404 Kein solcher Auftrag job_not_found
409 Schon fertig job_finished
curl -H "Authorization: Bearer $TOKEN" \
     -X DELETE \
     "$TAVLETTA/jobs/$JOB"

Antworten

Job

Feld Typ Bedeutung
id string Zufällig, 16 Zeichen.
state "queued" | "waiting" | "printing" | "done" | "failed" | "canceled" waiting: Er ist an der Reihe, aber ein anderer Auftrag hält die Etikettendatei (ihren Zähler). done, failed und canceled sind endgültig.
printer string ID des Druckermodells.
printer_name string or null Sein Name in printers.toml.
host string Die Adresse des Druckers.
owner string or null Name des Tokens.
label string or null Name im Etikettenordner; null für label_content.
printed integer Bisher gedruckte Etiketten.
total integer Zu druckende Etiketten: Kopien x Zeilen.
rows_printed integer Vollständig gedruckte Datenzeilen: nach einem Fehler mit rows ab der nächsten wieder drucken (rows_printed + erste Zeile).
cancel_requested boolean DELETE wurde geschickt.
error null or Warning Warum er fehlschlug: printer_<code>, counter_not_saved, label_locked oder prepare_failed.
remark string or null Ein Hinweis des Druckers, für Menschen.
warnings array of Warning Bei der Prüfung gefunden; er wurde trotzdem gedruckt.
created string UTC.
started string or null
finished string or null

Label

Feld Typ Bedeutung
name string
printer object ID und Name des Modells.
size object Band, Länge, Ausrichtung, mm.
elements array of object
variables array of string Eigene Variablen, {=lot}: mit 'set' gefüllt.
builtin_variables array of string
columns array of string Platzhalter {Column}: die Schlüssel von data_rows.
data_file string or null
data_file_unusable boolean
data_sheet string or null
counter object used (das Etikett hat {=counter}), next, step.
features array of string

NamedPrinter

Ein Drucker aus printers.toml.

Feld Typ Bedeutung
name string Was Anfragen in 'printer' nennen.
printer string ID des Druckermodells.
model string Druckermodell, für Menschen.
host string
description string or null
location string or null
media string or null
default boolean
max_copies integer
status object or null Der Zustand (wie PrinterStatus), oder Zustand UNREACHABLE mit einem Fehler; null mit status=false.

PrinterStatus

Feld Typ Bedeutung
printer string
host string
name string Sein Name in printers.toml.
model string
state string
error null or Warning
dpi number
firmware string or null
modes array of string
media object Was eingelegt ist, soweit der Drucker es sagt: tape_mm, remaining_mm, total_mm, pitch_mm, cassette.

Preview

Feld Typ Bedeutung
width integer
height integer
warnings array of Warning
png string

Beispiel eines Auftrags:

{
  "id": "HxIwYqXuV4qYRBM7",
  "state": "done",
  "printer": "cab",
  "printer_name": "it-cab",
  "host": "cab-it.example.com",
  "owner": "inventory-tool",
  "label": "asset-tag.tavletta",
  "printed": 20,
  "total": 20,
  "rows_printed": 20,
  "cancel_requested": false,
  "error": null,
  "remark": null,
  "warnings": [],
  "created": "2026-11-12T15:34:45+00:00",
  "started": "2026-11-12T15:34:45+00:00",
  "finished": "2026-11-12T15:35:04+00:00"
}