Übersicht
NoyesStorage ist so konzipiert, dass er eigenständig mittels App betrieben werden kann, ohne eine Integration zu erfordern. Soll der NoyesStorage automatisiert mit anderen Systemen kommunizieren, steht eine Schnittstelle (engl. Application Programming Interface, API) zur Verfügung. Dieser Abschnitt bietet eine Schnellstartanleitung zur Interaktion mit NoyesStorage über seine API und ermöglicht so die Integration von NoyesStorage in Anwendungsfälle wie:
- die Übergabe von Bestelldaten aus einem Online-Shop an NoyesStorage,
- das automatische Drucken von Rechnungen, wenn Kundenaufträge kommissioniert werden, und
- die Synchronisation des ERP-Systems mit den Lagerbeständen in NoyesStorage.
Die NoyesStorage-API basiert auf REST, verwendet das JSON-Datenformat für Anfragen und Antworten und nutzt gängige HTTP-Methoden (siehe Tabelle unten), um eine konsistente und vorhersehbare Schnittstelle bereitzustellen. Integrationen nutzen die öffentliche REST-API unter /api/v2/… (OpenAPI unter /api/openapi.json), z. B. POST /api/v2/requests für Abruf-, Kommissionier- und Nachschubaufträge.
Alle verfügbaren Endpunkte, Request-Modelle und Parameter finden Sie in der
API-Endpunktreferenz. Die interaktive API-Dokumentation des
jeweiligen NoyesStorage ist außerdem unter /api erreichbar.
HTTP Kommunikation in der NoyesStorage API
| Methode | Erklärung |
|---|---|
| POST | Create new resources or send data to NoyesStorage (e.g., submitting a fulfillment request). Example: /api/v2/requests |
| GET | Retrieve data from NoyesStorage (e.g., checking the status of requests). Example: /api/v2/requests |
| PUT | Update existing resources. |
| DELETE | Remove resources from NoyesStorage. |
Standard HTTP Antworten und Status der NoyesStorage API
| Status | Erklärung |
|---|---|
| 200 OK | The request succeeded. |
| 201 Created | A new resource was successfully created. |
| 202 Accepted | The request has been accepted but is being processed asynchronously. |
| 400 Bad Request | The request had a syntax error that could not be resolved. |
| 401 Unauthorized | Authentication is required. |
| 404 Not Found | The requested resource does not exist. |
| 500 Internal Server Error | The server encountered an error. |
Um die Schnittstelle vor böswilligen Nutzern zu schützen, benötigen alle Endpunkte eine Authentifizierung über einen API-Schlüssel. Jede Anfrage muss diesen API-Schlüssel im Header enthalten, andernfalls wird die Anfrage abgelehnt. Zusätzlich werden nur Anfragen akzeptiert, die über HTTPS gesendet werden. Dies stellt sicher, dass die Daten vor der Übertragung verschlüsselt und nur von der NoyesStorage-API entschlüsselt werden können. Anfragen, die über unverschlüsseltes HTTP oder ohne gültigen API-Schlüssel gesendet werden, schlagen fehl.
API-Key verwalten
Berechtigungen
Die Standardrollen Admin und Super Admin können API-Keys anzeigen, erstellen, bearbeiten und löschen. Bei benutzerdefinierten Rollen hängen die verfügbaren Aktionen von den zugewiesenen API-Key-Berechtigungen ab.
So erstellen Sie einen API-Key:
- Öffnen Sie in der NoyesStorage App
Einstellungen>API-Key. - Wählen Sie
API-Key hinzufügen. - Geben Sie einen aussagekräftigen Namen ein.
- Wählen Sie nur die API-Berechtigungen aus, die die Integration benötigt. Ein neuer API-Key hat zunächst keine Berechtigungen. Sie können nur Berechtigungen vergeben, die Sie selbst besitzen.
- Legen Sie die Gültigkeitsdauer fest. Das vorausgewählte Ablaufdatum liegt
30 Tage nach der Erstellung. Sie können stattdessen ein anderes zukünftiges
Datum wählen oder
Kein Ablaufdatumaktivieren. - Wählen Sie erneut
API-Key hinzufügenund kopieren Sie den erstellten Schlüssel in das Zielsystem.
Um die Berechtigungen eines bestehenden API-Keys zu ändern, wählen Sie den
Schlüssel in der Tabelle und anschließend Bearbeiten. Nicht mehr benötigte
oder möglicherweise kompromittierte Schlüssel löschen Sie über
API-Key löschen.
API-Keys ohne Ablaufdatum
Verwenden Sie Kein Ablaufdatum nur, wenn ein regelmäßiger Austausch des
API-Keys technisch nicht möglich ist. Prüfen Sie solche Schlüssel
regelmäßig und ersetzen Sie sie, sobald sie nicht mehr benötigt werden.

Authentifizierung und API-Key
Produktive Integrationen authentifizieren jede Anfrage mit einem API-Key, der in
der NoyesStorage App ausgegeben wurde. Senden Sie den Schlüssel als Bearer Token
im HTTP-Header Authorization:
Authorization: Bearer <api-key>
Behandeln Sie API-Keys wie Passwörter: nicht in Quellcode einchecken, nur in Secret Stores oder geschützten Umgebungsvariablen speichern und bei Verdacht auf Weitergabe in der App löschen und neu erstellen.
Filtern, Suchen, Sortieren und Pagination
Listen-Endpunkte wie GET /api/v2/skus, GET /api/v2/inventory_view,
GET /api/v2/requests, GET /api/v2/jobs und GET /api/v2/events
unterstützen je nach Ressource Filterparameter, Suche, Sortierung und
Pagination.
Filter verwenden das Schema field__operator=value. Häufige Operatoren sind
__eq für exakte Treffer, __gte und __lte für Bereiche sowie __ilike für
teilweise, groß-/kleinschreibungsunabhängige Treffer. Bei __in wird der
Query-Parameter pro Wert wiederholt:
GET /api/v2/inventory_view?level_id__in=1&level_id__in=2
Kommagetrennte Listen wie ?level_id__in=1,2 werden nicht als mehrere Werte
interpretiert.
Der Parameter search nutzt field:value-Ausdrücke. Die Suche ist teilweise
und groß-/kleinschreibungsunabhängig. Die unterstützten Suchfelder sind
endpunktspezifisch und in der search-Parameterbeschreibung des jeweiligen
Endpunkts aufgeführt:
GET /api/v2/skus?search=id:tee
Mehrere Suchbegriffe können mit den großgeschriebenen Operatoren AND und OR
kombiniert werden. Eine Ebene von Klammern wird unterstützt:
GET /api/v2/inventory_view?search=sku_id:tee AND (box_id:2 OR carrier_id:2)
Mit *:value wird über alle für den jeweiligen Endpunkt unterstützten
Suchfelder gesucht:
GET /api/v2/inventory_view?search=*:tee
Der Parameter sort_by akzeptiert kommagetrennte Feldnamen. Ein Feld ohne
Vorzeichen oder mit + sortiert aufsteigend, - sortiert absteigend:
GET /api/v2/requests?sort_by=created_at,-updated_at
Pagination verwendet page und size. Die Seitennummerierung beginnt bei
page=1; ohne abweichende Anfrage liefert die API standardmäßig page=1 und
size=50:
GET /api/v2/skus?page=1&size=50
Funktionsweise der Anfrageausführung
Das NoyesStorage-System arbeitet mit einer Warteschlange. Ein spezifisches Arbeitspaket kann durch das Senden einer Anfrage angefordert werden. Intern wird diese Anfrage in mehrere Jobs aufgeteilt, die nacheinander ausgeführt werden. Sowohl Anfragen als auch Jobs folgen einem vordefinierten Lebenszyklus, der durch ihren Status ausgedrückt wird.
Requests
Anfragen (engl. Requests) können an den NoyesStorage gesendet werden. Diese Anfrage wird dann intern in eine Reihe von Jobs übersetzt. Die folgende Tabelle listet die verfügbaren Anfragen und deren Beschreibungen auf. Über die API können Fetch, Fulfillment und Replenishment Anfragen an den NoyesStorage gesendet werden, um die Aus- und Einlagerung automatisiert abzuwickeln.
Priorität von Requests
Für über die API erstellte Fetch-, Fulfillment- und Replenishment-
Requests kann optional das Feld priority als Zahl mitgesendet werden. Ohne
Angabe verwendet NoyesStorage die normale Priorität 10. Requests, die über
die NoyesStorage App erstellt werden, werden standardmäßig mit der hohen
Priorität 20 gesendet.
| Priorität | Wert | Verhalten |
|---|---|---|
| Niedrig | 5 |
Wird als normale Anfrage in der Warteschlange behandelt. |
| Normal | 10 |
Standardwert, wenn keine Priorität angegeben wird. |
| Hoch | 20 |
Wird vor normalen Anfragen in der Warteschlange berücksichtigt. |
Prioritäten über 10 werden als Priority-Requests behandelt und vor normalen
Anfragen in die Bearbeitung aufgenommen. Die tatsächliche Ausführung hängt
weiterhin vom aktuellen Systemzustand ab, zum Beispiel von verfügbaren Carriern,
Balkonen, Bots und freien Bearbeitungspositionen.
Requests im NoyesStorage
| Request | Description |
|---|---|
| FULFILLMENT | A Logistic Request consisting of SKU entities to pick. |
| REPLENISHMENT | A Logistic Request consisting of SKU entities to refill. |
| FETCH | A Logistic Request consisting of Fetch-Carrier-Entities. |
| RFID_MAINTENANCE | A System Control Request to write and/or check RFID Tags on a specified Level. |
| ONBOARD | A System Control Request to add a Noyes Bot to any Level. |
| OFFBOARD | A System Control Request to remove a specific Noyes Bot from a Level. |
| PAUSE | A System Control Request that prevents Bots from receiving new commands. |
| RESUME | A System Control Request to allow all Bots to get new commands after a PAUSE Request. |
| UNCHARGING | A System Control Request to remove a Noyes Bot from a Charging Station. |
| RECHARGE | A System Control Request to move a Noyes Bot to a Charging Station. |
Jobs
Jobs sind die einzelnen Aufgaben, die im System ausgeführt werden. Jede Anfrage kann mehrere Jobs generieren, die jeweils einem vordefinierten Lebenszyklus folgen. Die folgende Tabelle liefert einen Überblick über die im NoyesStorage verwendeten Jobs.
Jobs im NoyesStorage
| Job | Description |
|---|---|
| BUFFERING | Moves a Carrier to a Buffer Space on the same Level. |
| RETRIEVING | Moves a Carrier to a Balcony on the same Level. |
| STORING | Moves a Carrier from the Balcony. |
| PICKING | Lets the user pick a given amount out of a Box. |
| PICKING_ALERT | Lets the user handle fulfillment quantities outside the NoyesStorage when the external picking feature is enabled. |
| REFILLING | Lets the user refill a given amount into a Box. |
| CHECKING | Lets the user check a given Carrier Label. |
| PACKING | Lets the user check the summary of a Request after all Entities have been worked on. |
| ONBOARDING | Lets the user onboard a Bot to any level. |
| ONBOARDING_BD | Adds a Bot to the Database and informs all Brain Components about it. |
| OFFBOARDING | Moves a Bot to the Balcony. |
| OFFBOARDING_BD | Lets the user remove a Bot from the Balcony. |
| OFFBOARDING_BC | Moves a Bot to the Balcony. |
| PAUSE | Ensures no Bot gets new commands. |
| RESUME | Allows all Bots to get new commands after a PAUSE. |
| MOVING_BOT | Moves a Bot to a target location/rotation/lifting state. |
| CONNECT_TO_BOTS | Establishes a connection to all Bots that are in the Database. |
| REFRESH_LEVEL | Updates the digital twin in the Bot Coordinator to the Database. |
| UNCHARGE_ALL | Removes all Bots from the Charging Station. |
| CLEAR_AUTOBAHN | Removes all Carriers from the Highway. |
| CHARGING | Moves a given bot to a Charging Station. |
| UNCHARGING | Removes a given bot from the Charging Station. |
| CHECK_RFID_TAG | Checks the values written on an RFID Tag at the given Location and Rotation. |
| WRITE_RFID_TAG | Writes values to an RFID Tag at the given Location and Rotation. |
| CHANGE_RFID_WRITING_MODE | Changes whether or not a bot should ignore the values on an RFID Tag while driving. |
Hinweis zu PICKING_ALERT
PICKING_ALERT erscheint nur, wenn die externe Kommissionierung für fehlende oder außerhalb des NoyesStorage zu bearbeitende Fulfillment-Mengen aktiviert ist. In diesem Fall können angenommene Fulfillment-Requests strukturierte Warnhinweise zu fehlenden oder extern zu bearbeitenden Mengen enthalten, und nachgelagerte Job-Daten können PICKING_ALERT-Jobs enthalten.
Job States
Jeder Job durchläuft einen Lebenszyklus, der durch seinen Status definiert ist. Die folgenden Statusübergänge sind in der Tabelle dargestellt.
Job States in the NoyesStorage System
| State | Description |
|---|---|
| ACCEPTED | Job is ACCEPTED. These transitions are allowed: EXECUTING, ERROR, CANCELLING, ABORTED. |
| EXECUTING | Job is EXECUTING and waiting to be triggered. These transitions are allowed: ERROR, CANCELLING, ABORTED. |
| SUCCEEDED | Job is SUCCEEDED. No transitions are allowed. This is a final state. |
| CANCELLING | Job is CANCELLING. A user requested this job to be cancelled. These transitions are allowed: CANCELLED, ABORTED. |
| CANCELLED | Job is CANCELLED. A user requested this job to be cancelled. The CANCELLING was successful. This is a final state. |
| ABORTED | Job is ABORTED due to a system problem. The system will try to recover from this. This is a final state. |
Quickstart: Ein einfaches Integrationsbeispiel
Das folgende Python-Beispiel erstellt einen Fulfillment-Request für zwei Stück
einer SKU und fragt dessen Status regelmäßig ab. Ersetzen Sie
https://<noyesstorage-url>, <api-key> und SKU-123 durch die Werte Ihrer
Integration.
Der API-Key benötigt die Berechtigung zum Erstellen von Fulfillment-Requests. Zum Abrufen des Status benötigt er zusätzlich die Berechtigung zum Anzeigen von Requests.
import time
import requests
class SimpleERPIntegration:
"""Create requests in NoyesStorage and wait for their final status."""
TERMINAL_STATUSES = {"SUCCEEDED", "CANCELLED", "ABORTED"}
def __init__(self, base_url: str, api_key: str) -> None:
self.requests_url = f"{base_url.rstrip('/')}/api/v2/requests"
self.session = requests.Session()
self.session.headers.update(
{
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
)
def create_fulfillment(self, sku_id: str, quantity: int) -> str:
payload = {
"type": "FULFILLMENT",
"priority": 10,
"entities": [{"sku_id": sku_id, "quantity": quantity}],
}
response = self.session.post(self.requests_url, json=payload, timeout=10)
response.raise_for_status()
return response.json()["id"]
def get_request(self, request_id: str) -> dict:
response = self.session.get(
self.requests_url,
params={"id__eq": request_id},
timeout=10,
)
response.raise_for_status()
items = response.json()["items"]
if not items:
raise LookupError(f"Request {request_id} was not found")
return items[0]
def wait_until_finished(self, request_id: str, interval: int = 10) -> dict:
while True:
request = self.get_request(request_id)
if request["status"] in self.TERMINAL_STATUSES:
return request
time.sleep(interval)
integration = SimpleERPIntegration(
base_url="https://<noyesstorage-url>",
api_key="<api-key>",
)
request_id = integration.create_fulfillment("SKU-123", quantity=2)
result = integration.wait_until_finished(request_id)
print(result["status"])
Erläuterungen zum Code
SimpleERPIntegrationrichtet eine HTTP-Sitzung ein und sendet den API-Key bei jeder Anfrage als Bearer Token.create_fulfillmenterstellt den Request mitPOST /api/v2/requests. Bei Erfolg enthält die Antwort die eindeutigeiddes Requests.get_requestruftGET /api/v2/requestsmit dem Filterid__eqauf. Da es sich um einen Listen-Endpunkt handelt, steht der gefundene Request im Felditemsder paginierten Antwort.wait_until_finishedfragt den Status im gewählten Intervall ab und endet beiSUCCEEDED,CANCELLEDoderABORTED.
Ein Request durchläuft abhängig vom Typ und Bearbeitungsfortschritt Status wie
CREATED, ACCEPTED, EXECUTING, SUCCEEDED, CANCELLED oder
ABORTED. Fragen Sie den Status in einem für Ihre Integration geeigneten
Intervall ab. Verwenden Sie bei Listenabfragen die beschriebenen Filter-,
Sortier- und Paginierungsparameter.
Weitere Request-Typen, Pflichtfelder und Antwortmodelle finden Sie in der API-Endpunktreferenz.