# iPaaS und Middleware

> Die BatteryPass-API aus n8n, Make, Power Automate, MuleSoft, Boomi, Workato, Zapier und SAP Integration Suite mit einem Schlüssel aus dem Geheimnisspeicher der Plattform aufrufen und den Änderungsfeed abfragen.

Die meisten ERP-Integrationen laufen auf einer Integrationsplattform statt in eigenem Code. Jede Plattform unten
kann BatteryPass aufrufen, denn die API braucht nur zwei Dinge: eine HTTPS-Anfrage mit dem Header
`Authorization: Bearer <Schlüssel>` und JSON (oder `multipart/form-data` für Importe). Diese Seite zeigt, wo der
Schlüssel auf jeder Plattform hingehört und wie jede dem [Änderungsfeed](https://passport.kabin.sh/docs/de/api-reference/changes/list-changes)
folgt.

Die Plattformen sind nach ihrer öffentlichen Dokumentation beschrieben. BatteryPass bietet auf keiner davon einen
eigenen Konnektor an und hat keine Partnerschaft mit ihren Herstellern.

## Was alle Plattformen gleich machen

- **Der Schlüssel liegt im Anmeldedatenspeicher der Plattform**, nie in einer Flow-Definition, einem Skript oder
  einer Variablen, die in Ausführungsprotokollen erscheint. Ein Schlüssel je Flow und Umgebung (siehe
  [Sicherheit](https://passport.kabin.sh/docs/de/integrations/security)).
- **Der Vertrag.** BatteryPass veröffentlicht seinen Integrationsvertrag als OpenAPI 3.0.3 unter
  `/api/v1/openapi.json` und `/api/v1/openapi.yaml` auf Ihrer BatteryPass-Adresse und zum Herunterladen in der
  [API-Referenz](https://passport.kabin.sh/docs/de/api-reference). Plattformen, die OpenAPI 3 importieren, bauen daraus ihre Operationen.
- **Abfragen statt Webhooks.** Ausgehende Webhooks sendet BatteryPass noch nicht; sie sind geplant und brauchen eine
  eigene Entscheidung. Planen Sie einen Flow (alle paar Minuten), der `GET /api/v1/changes` mit dem gespeicherten
  Cursor aufruft, die Einträge der Reihe nach verarbeitet und `next_cursor` speichert, wenn er nicht `null` ist. Das
  Muster ist überall gleich:

```text title="Abfrageschleife"
cursor = aus dem Datenspeicher der Plattform laden (beim ersten Lauf leer)
wiederholen:
  GET /api/v1/changes?types=passport.published,passport.republished&limit=100&cursor={cursor}
  für jeden Eintrag: Entität lesen, ERP aktualisieren
  wenn next_cursor null ist: aufhören     (eine leere Seite behält den alten Cursor)
  cursor = next_cursor, speichern          (erst, nachdem das ERP die Seite angenommen hat)
```

- **Fehler.** `429` nach `Retry-After` und `5xx` mit Backoff wiederholen, andere `4xx` nicht (siehe
  [Fehler und Wiederholungen behandeln](https://passport.kabin.sh/docs/de/guides/handle-errors)).

## Plattformen

**n8n**

Nutzen Sie den Knoten **HTTP Request** mit einer Anmeldung vom Typ **Header Auth**: Name `Authorization`, Wert
`Bearer bp_live_…` ([n8n: HTTP-Request-Anmeldedaten](https://docs.n8n.io/integrations/builtin/credentials/httprequest/)).
Die Anmeldung wird verschlüsselt gespeichert und in Ausführungen nicht angezeigt.

Abfragen: Ein **Schedule Trigger** startet den Flow; den Cursor halten Sie in den statischen Daten des Workflows
oder in einer kleinen Datenbanktabelle, rufen `GET /changes` in einem HTTP-Request-Knoten auf, teilen die Einträge
auf und wiederholen, solange `next_cursor` gesetzt ist. Für Importe senden Sie `multipart/form-data` mit einer
binären Eigenschaft für `file` und einem Formularfeld `preset`.

**Make**

Nutzen Sie die App **HTTP** und legen Sie den Schlüssel in einem Keychain vom Typ **API key** ab, der den Header
`Authorization` mit `Bearer bp_live_…` setzt ([Make: HTTP](https://apps.make.com/http)). Keychains halten das
Geheimnis aus dem Szenario-Export heraus.

Abfragen: ein geplantes Szenario, der Cursor in einem **Data Store**; der **Repeater** oder ein Iterator geht die
Seiten durch, bis `next_cursor` leer ist.

**Power Automate und Azure Logic Apps**

Benutzerdefinierte Konnektoren akzeptieren **nur Definitionen in OpenAPI 2.0 (Swagger)**, und die Datei muss kleiner
als 1 MB sein; Authentifizierung per API-Schlüssel wird unterstützt
([Microsoft: FAQ zu benutzerdefinierten Konnektoren](https://learn.microsoft.com/en-us/connectors/custom-connectors/faq)).
BatteryPass veröffentlicht heute OpenAPI 3.0.3; unseren Vertrag können Sie also nicht direkt als
benutzerdefinierten Konnektor importieren. Ein Export des Integrationsvertrags in Swagger 2.0 ist als nächster
Schritt geplant.

Bis dahin nutzen Sie die eingebaute Aktion **HTTP**: Legen Sie den Schlüssel in Azure Key Vault ab, lesen Sie ihn
mit dem Key-Vault-Konnektor (markieren Sie die Ausgabe als sicher, damit sie nicht im Ausführungsverlauf erscheint)
und setzen Sie den Header `Authorization: Bearer @{…}`. Abfragen: ein Trigger **Wiederholung**, der Cursor in einer
Tabelle in Dataverse oder Azure Table Storage und eine Schleife **Do until** über die Seiten.

**MuleSoft Anypoint**

**REST Connect** in Anypoint Exchange erzeugt einen Konnektor aus einer Spezifikation in OpenAPI 2.0 oder 3.0
([MuleSoft: REST Connect](https://docs.mulesoft.com/exchange/to-deploy-using-rest-connect)); das veröffentlichte
`openapi.json` kann also die Quelle sein. Alternativ rufen Sie die API mit dem Konnektor HTTP Request auf.

Halten Sie den Schlüssel in verschlüsselten Konfigurationseigenschaften oder einem Secrets-Manager und setzen Sie
ihn als Header `Authorization` der Konnektor-Konfiguration. Abfragen: eine Quelle **Scheduler** mit dem Cursor in
einem Object Store.

**Boomi**

Der Konnektor **OpenAPI** importiert OpenAPI 3.0 und neuer
([Boomi: OpenAPI-Konnektor](https://help.boomi.com/docs/Atomsphere/Integration/Connectors/int-OpenAPI_connector_6766251b-b601-41f5-8c13-86d79faf52b9)).
Importieren Sie den veröffentlichten Vertrag oder nutzen Sie den Konnektor HTTP Client. Speichern Sie den Schlüssel
als verschlüsseltes Verbindungsfeld oder in einer als Passwort markierten Extension und senden Sie ihn als Header
`Authorization`.

Abfragen: ein geplanter Prozess mit dem Cursor in einer persistenten Prozesseigenschaft.

**Workato**

Nutzen Sie den Konnektor **HTTP** mit einer Verbindung, die den Header `Authorization: Bearer …` setzt; Workato
verschlüsselt Verbindungsfelder. Trigger, die Webhooks empfangen, brauchen einen eigenen Konnektor aus dem
Connector-SDK ([Workato: dynamische Webhook-Trigger](https://docs.workato.com/en/developing-connectors/sdk/guides/building-triggers/dynamic-webhook.html));
weil BatteryPass noch keine Webhooks hat, nutzen Sie ein **geplantes Rezept**, das `GET /changes` abfragt und den
Cursor in einer Lookup-Tabelle hält.

**Zapier**

Die Sofort-Trigger von Zapier nutzen **REST Hooks**, die auf API-Seite Endpunkte zum An- und Abmelden brauchen
([Zapier: REST-Hook-Trigger](https://docs.zapier.com/integrations/build/hook-trigger)). BatteryPass bietet sie noch
nicht an. Nutzen Sie stattdessen einen abfragenden Trigger: **Webhooks by Zapier** (Retrieve Poll) oder den
Polling-Trigger einer privaten App gegen `GET /changes`, mit dem Schlüssel in einem Authentifizierungsfeld für
API-Schlüssel. Zapier erkennt abgefragte Einträge an ihrer `id` wieder, die jede Änderung trägt.

**SAP Integration Suite (Cloud Integration)**

Nutzen Sie den **HTTP-Receiver-Adapter**. Legen Sie den Schlüssel als sicheren Parameter im Security Material des
Tenants ab und setzen Sie den Header `Authorization` daraus in einem Content Modifier oder Skript, nie als
einfachen externalisierten Parameter.

Achtung: Cloud Integration kann eigene Header aus der Nachricht entfernen, wenn sie nicht erlaubt sind. Tragen Sie
`Authorization` (oder den Header, den Sie setzen) unter **Allowed Header(s)** in der Laufzeitkonfiguration des
Integrationsflusses ein; der SAP-Hinweis 3075702 beschreibt das Symptom nicht gesendeter Header. Abfragen: ein
Start-Ereignis **Timer**, der Cursor in einem Data Store oder einer globalen Variablen und ein Looping Process Call
über die Seiten.

## Importe von einer Plattform hochladen

[Einheiten aus der Fertigung](https://passport.kabin.sh/docs/de/integrations/workflows/units-from-production) braucht
`multipart/form-data`: die Datei im Teil `file` (mit Dateiname und Inhaltstyp `text/csv` oder dem XLSX-Typ) und die
Kennung der Importvorlage im Teil `preset`. Jede Plattform oben kann Multipart-Anfragen aus ihrem HTTP-Konnektor
senden; bauen Sie die CSV im Flow und hängen Sie sie als binären Inhalt an. Fragen Sie danach `GET /imports/{id}` ab,
bis `status` den Wert `validated` oder `failed` hat.
