Zum Inhalt

Ü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:

  1. Öffnen Sie in der NoyesStorage App Einstellungen > API-Key.
  2. Wählen Sie API-Key hinzufügen.
  3. Geben Sie einen aussagekräftigen Namen ein.
  4. 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.
  5. 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 Ablaufdatum aktivieren.
  6. Wählen Sie erneut API-Key hinzufügen und 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.

API-Key mit Berechtigungen und Ablaufdatum erstellen

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

  1. SimpleERPIntegration richtet eine HTTP-Sitzung ein und sendet den API-Key bei jeder Anfrage als Bearer Token.
  2. create_fulfillment erstellt den Request mit POST /api/v2/requests. Bei Erfolg enthält die Antwort die eindeutige id des Requests.
  3. get_request ruft GET /api/v2/requests mit dem Filter id__eq auf. Da es sich um einen Listen-Endpunkt handelt, steht der gefundene Request im Feld items der paginierten Antwort.
  4. wait_until_finished fragt den Status im gewählten Intervall ab und endet bei SUCCEEDED, CANCELLED oder ABORTED.

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.