Document toolboxDocument toolbox

API & OTA-Integration

profacto bietet einen token-gesicherten Zugriff auf ausgewählte Tabellen, Felder und Funktionen mit sehr flexibler Architektur. Bei Wünschen für zusätzliche Tabellen, API-Sets, bestimmte Funktionen oder als externer Entwickler mit einem größeren Projekt, um größere Zusammenhänge und Prozesse mit profacto digital zu integrieren: sprich uns gerne an. 

Lizenz

  • Ein API-Access beinhaltet einen parallelen Zugriff je API-Token + IP-Adress-Kombination für ein Zeitfenster von 15 Minuten ab dem erstem Aufruf.
  • Jeder neue Aufruf innerhalb dieses Zeitfenster verlängert die Nutzungsphase dieses API-Accesses um weitere 15 Minuten.
  • Je profacto Lizenz (exkl. TZE-Clients) ist ein freier Zugriff bereits integriert. In profacto SmallBusiness ist die API für die Zeiterfassung und Integration (s.u.) reduziert - Sonderfall ist die Craftboxx-Anbindung.
  • Zusätzlich erhält jede profacto Lizenz (inkl. Small Business, StartUp) einen parallelen OTA-Integration Zugriff, der wie ein zweckbestimmter API-Zugriff ebenso berechnet wird.
  • Weitere API-Accesses (auch für die OTA-Integration) können ab profacto 2021 für profacto (exkl. StartUp) separat erworben werden. Bis dahin wird kein erweitertes Entgelt erhoben, selbst wenn man mehr Zugänge nutzen möchte.

Limitierung

Sobald man das Limit der Lizenzen erreicht, wird der Aufruf umgeleitet. Man erhält je nach Aufruf der eigentlichen Zielseite eine Webseite mit weiteren Infos

HTML

JSON

{
"error":"licenses_exceeded",
"url":"http://meinServer:8080/4DAction/api_license_redirect?response=HTML",
"errorMsg":"Lizenzen für API oder OTA erschöpft, weitere Infos unter http://meinserver:8080/4DAction/api_license_redirect?response=HTML",
"clients":3,
"otaAvailable":3,
"apiAvailable":5,
"AddOnAPICalls":2,
"otainUse":0,
"apiInUse":1,
"otatokenslots":[],
"apitokenslots":[
{
"timestamp":5649041,
"iptoken":"192.168.2.1038E39C4BA44C643BBAA78DE0B80DBE3D4"
}]
}




OTA-Integration

Die Over the Air-Integration mit einem CAD ist aufgrund der Entwicklungsbasis jenseits von profacto, als offenem Standard für ERP und CAD, gesondert dokumentiert: CAD ERP Integration

API - Wieso, weshalb, warum?

Access Protocol Interface - oder einfach formuliert, eine Softwareschnittstelle mit einem einheitlichen Zugriffsprotokoll für alle. 

Im Gegensatz zu einfachen Datenimporten aus zB per Excel vorbereiteten .csv-Dateien, einem manuellen Export in .csv-Datein oder dem Zugriff per ODBC bietet das profacto API einen umfassend lesenden Zugriff, der keinen profacto Client voraussetzt und keinen profacto-Client (Stand 23.09.2019) oder eine ähnliche Lizenz benötigt. Zudem erlaubt der API-Zugriff, daß die Datenintegrität  innerhalb  der Anwendung gesichert ist.

Dafür aber einen durch einen selbst erzeugten Token einen gesicherten Zugriff von außen auf bestimmte Bereiche von profacto erlaubt, die man für bestimmte Aufgaben nunmal benötigt.

Der ODBC-Zugriff erlaubt hier ein zuviel an Zugriffsrechten und hat keine Option Inhalte zu schreiben oder ändern. Zudem ist er beschränkt auf profacto Server-Installationen auf Windows und braucht zusätzliche Treiber-Updates, die wir auch mit profacto 2021 nicht mehr als Teil des Produkts ausliefern.

CSV-Dateien müssen manuell erzeugt werden und erfordern eine Übertragung von Dateien, somit einen Speicherort. profacto API erfolgt über HTTP-Aufrufe und liefert Daten im JSON-Format, welches sich insbesondere für Webseiten und Drittsoftware sehr einfach verarbeiten lässt.

Man kann die Daten mittels eines Standard-Browsers abrufen und sofort sehen. Man muß sich nicht allein im Firmennetzwerk bewegen. Zugleich setzt die API ein tieferes technisches Verständnis von HTTP/REST-Zugriffen voraus und dient in erster Linie der Kommunikation von Anwendung zu Anwendung. 

Dazu bieten wir aber auch die Option die API im Hintergund zu nutzen, um Webinhalte (zB Zeiterfassung, Lagerbestellung) bereitzustellen, also einen unmittelbaren Zugriff ermöglichen auf quasi jedem modernen mobilen Gerät mit einem Standardbrowser.

Architektur

Im Kern setzt das API auf einem aufgaben- oder rollenbasierten Spektrum an Zugriffen, wie zB die Zeiterfassung oder die CAD-Integration (die künftig als Sonder-API im Bereich der Integration beschrieben wird).

Folgende APIs sind bereits für alle kostenpflichtigen profacto-Versionen zugänglich:

  • Integration
  • Zeiterfassung
  • Administration
  • API Pinger (rein technischer Zugriff zu Testzwecken von Entwicklern)

Nur für die Standard-Version von profacto sind diese APIs verfügbar:

  • Produktion sowie ProduktionSchreiben
  • Kontakte sowie KontakteSchreiben
  • Kunden sowie KundenSchreiben
  • Aktivitäten sowie AktivitätenSchreiben
  • Lieferanten sowie LieferantenSchreiben
  • Projekte sowie ProjekteSchreiben
  • Artikel sowie ArtikelSchreiben
  • Personal sowie PersonalSchreiben
  • Lager
  • Bestellung sowie BestellungSchreiben
  • Dateien
  • Buchhaltung
  • Kalkulation
  • Konstanten

Diese APIs befinden sich weiterhin im Aufbau, der sich nach aktuellen Anforderungen richtet. Seit profacto 2024.1 differenzieren wir dort, wo eine entsprechende Funktion zur Verfügfung steht, zwischen Lesetoken und Schreibtoken. Dies erlaubt es, Mitarbeitern Leserechte auf bestimmte Tabellen zu gewähren, nicht aber das Recht, diese Daten auch zu modifizieren. Da die APIs inzwischen sehr leistungsfähig sind und durchaus auch außerhalb des lokalen Netzwerks eingesetzt werden können, erhöht diese Maßnahme die Zugriffssicherheit auf Ihre Daten.

Dazu gehört, daß man bestimmten Mitarbeitern (ein Personal-Datensatz ist Voraussetzung) ein Token gibt, mit dem der Zugriff gewährt, aber eben auch zeitlich limitiert oder entzogen werden kann. 

Zugriff

In den Voreinstellungen, profacto API und OTA werden die Tokens vergeben. 

Das eindeutige Token wird einer Personalnummer wie ein Fingerabdruck zugeordnet und danach der gewünschten API. Für diverse APIs muß man auch verschiedene Tokens erstellen. Standard ist eine Laufzeit von 5 Jahren, die email dient dazu es auch direkt übermitteln zu können.

Mittels Token wird zugleich identifiziert, welche API von wem aufgerufen wird.

“token is invalid” hier handelt sich um einen Hinweis, der darauf aufmerksam machen möchte, dass die Voreintellungen noch göffnet sind. Bitte Diese Schließen und den Link (Token) nochmal laden.



Entwickler-Paket

Entwicklungsumgebung

Du hast eine Idee die profacto API für Deine Firma zu nutzen und möchtest jemanden beauftragen es zu entwicklen? Wir stellen gerne den Kontakt zu Entwicklern her.

Für Entwickler stellen wir gerne eine profacto Lizenz und Entwicklungsumgebung bereit.

macOS: profacto Installer
Windows: profacto Installer

Die zugehörige Lizenz und Zugang zum API-Netzwerk mit Kunden und anderen Entwicklern stellen wir dir gerne auf Anfrage bereit: am besten gleich das hier verlinkte FairUseAgreement profactoDeveloper vorausgefüllt mitsenden bereit. 

 Auf GitHub stellen wir einerseits HTML-Templates und auch Scripts zum Zugriff auf die API bereit.

Wenn du dort eigene Scripte der Öffentlichkeit zur Verfügung stellen möchtest, ist das herzlich willkommen und wir unterstützen den Austausch dazu sehr gerne. Die Scripts und Templates werden unter der MIT-Lizenz verfügbar gemacht.

Aufruf

API-Basis = http://<Servername im LAN | IP im LAN | WAN-Domain bzw. IP|>:8080/4DAction/<api-Methode>?token=<Token>

An die API-Basis werden dann mit &Attribut=Wert weitere Parameter übergeben.


Begrifflichkeiten und Vorgaben

LAN = Local Area Network - Also über das lokale Netzwerk oder das lokale WLAN

WAN = Wide Area Network - Also über das Internet, öffentliche WLAN HotSpots oder Mobilfunk

Der Port 8080 ist hart vorgegeben und darf nicht geändert werden.

Das 4DAction ist einfach Teil der Struktur und kann nicht geändert werden.


Tabellen und Feld-Namen

Die Namen aller Tabellen und Felder in profacto können hier eingesehen werden

Link: Datenbankstruktur

Die APIs haben jeweils auch Felder, die nicht unterstützt werden, insbesondere BLOB- und Bild-Felder, aber auch unzulässige Felder. So braucht man für Zeiterfassung bestimmte Personal-Informationen, jedoch nicht das Gehalt oder andere private Informationen.

Für verschiedene Szenarien kann es daher sein, daß ein Aufruf abgelehnt wird, wenn man unzulässige Felder verwendet hat.

Daten  lesen mit api_get

Mögliche Parameter:

table = je nach API eine darin zulässige Tabelle  - Beispiel API-Basis&table=Ansprechpartner

fields = eine kommagetrennte Liste von auszugebenden Feldern der Standardtabelle des APIs oder der per table-Parameters gewünschten Tabelle - Beispiel API-Basis&fields=KundenNr,Ort,PLZ,Name1

query = Ein query-String, der per URL-Encoding mit Prozentzeichen übergeben werden muss, also zB %20  für ein Leerzeichen, etc. siehe hier in Wikipedia: https://de.wikipedia.org/wiki/URL-Encoding#Relevante_ASCII-Zeichen_in_Prozentdarstellung - Beispiel 

API-Basis&query=KundenNr%3D131%20AND%20Ort%3DHildesheim

  (entspricht KundenNr=131 AND Ort=Hildesheim)

Vollständiges Beispiel: 

http://meinServer:8080/4DAction/api_get?token=124&table=Ansprechpartner&fields=Anrede,Geschlecht,Name,VorName,email,Telefon,MobilTel,isInaktiv,Suchfeld1&query=TypNr%3D131

Operatoren

Für eine Übersicht der query-Syntax bitte folgende Darstellung verwenden (Übersetzung folgt).

  • Symbole zum Vergleichen von Attribut und Value. Es gibt folgende Symbole:

    VergleichSymbol(e)Kommentar
    Ist gleich=, ==Erhält passende Daten, unterstützt den Joker @, berücksichtigt weder Groß- und Kleinschreibung noch diakritische Zeichen.

    ===, ISErhält passende Daten, bewertet @ als Standardzeichen und nicht als Joker, berücksichtigt weder Groß- und Kleinschreibung noch diakritische Zeichen.
    Ungleich zu#, !=unterstützt den Joker (@)

    !==, IS NOTbewertet @ als Standardzeichen und nicht als Joker
    Kleiner als<
    Größer als>
    Kleiner als oder gleich<=
    Größer als oder gleich>=
    Enthalten inINErhält Daten, die mit mindestens einem Wert in einer Collection bzw. einem Satz Werte übereinstimmt
    Nicht enthalten in einer AnweisungNOTKlammern sind zwingend, wenn NOT vor einer Anweisung mit mehreren Operatoren verwendet wird
    Enthält Schlüsselwort%Schlüsselwörter lassen sich in Attributen vom Typ String oder Bild verwenden
  • Value: Wert zum Vergleichen mit dem aktuellen Wert der Eigenschaft. 
    Für eine Suche nach einem String innerhalb eines anderen String (eine Suche "Enthalten in") verwenden Sie den Joker (@) in value, um den zu suchenden String zu isolieren, zum Beispiel: "@Schmi@", um alle Schmid, Schmied, Schmitt und so weiter zu finden.
  • Für numerische Werte dient Punkt als Dezimaltrenner.
  • Datumsangeben müssen im Format "YYYY-MM-DD" sein.
    Bei einer Suche mit einem IN Vergleichsoperator muss value eine Collection sein bzw. Werte, die zum Typ des Attributspfads zwischen eckigen Klammern [] passen, getrennt durch Kommas (bei Strings müssen Anführungszeichen " mit "\" abschließen).
  • LogicalOperator: verbindet mehrere Bedingungen in der Suche (optional). Es gibt folgende logische Operatoren (Sie können Name oder Symbol übergeben):

    KonjunktionSymbol(e)
    AND&, &&, and
    OR|, ||, or
  • order by Attribut: Sie können eine Anweisung order by Attribute in der Suche hinzufügen, so dass die Ergebniswerte sortiert werden. Sie können mehrere Sortieranweisungen, durch Komma getrennt, verwenden, (z.B. order by Attribut1 desc, Attribut2 asc). Die Sortierung ist standardmäßig aufsteigend. Übergeben Sie 'desc' für absteigende Reihenfolge und 'asc' für aufsteigende Reihenfolge 

Die Tabellen- und Feldnamen für table und fields müssen nicht exakt der Groß-Kleinschreibung der Struktur folgen, für query ist dies jedoch zwingend.


Stringsuche mit Leerzeichen

Suchen Sie Strings, die Leerzeichen enthalten, müssen Sie diese mit hochgestellten einzelnen Anführungszeichen kapseln, um zu verhindern, dass intern der Suchstring falsch interpretiert wird.


Ausgabe der Daten

Die Daten werden als JSON-String zurückgegeben. 

Dazu gibt es stets initiale Objekte: Error, success, errorType und der aufgerufene Tabellenname.

Im Error steht  - möglichst menschenfreundlich in einem Satz formuliert - welche Fehler es gab. Gab es keine Fehler, enthält das Feld eine leere Kette.

In dem Objekt success steckt eine boolesche Variable mit true oder false, die bestimmt, ob der api_get Aufruf  erfolgreich war.

In dem Objekt errorType steht (falls es einen Fehler gab) ein oder mehrere Schlüsselwörter, die den Fehler beschreiben.

Danach kommen die eigentlichen Daten im Format Feldname:Feldinhalt.

Das sieht bei einem Aufruf mit einem nicht vorhandenen Quatschfeld wie folgt aus:

http://meinserver:8080/4DAction/api_get?token=5E05A427CD134432A28F2DAF11EC500E&table=Kunden&fields=KundenNr,Quatschfeld

JSON-Response:

{"Error":["Das Feld Quatschfeld ist nicht vorhanden."],"Kunden":[{"KundenNr":"100001"},{"KundenNr":"100019"},{"KundenNr":"100003"},{"KundenNr":"131"},{"KundenNr":"130"},{"KundenNr":"129"},{"KundenNr":"128"},{"KundenNr":"127"},{"KundenNr":"125"},{"KundenNr":"124"},{"KundenNr":"123"},{"KundenNr":"100018"},{"KundenNr":"100015"},{"KundenNr":"1000012"},{"KundenNr":"126"},{"KundenNr":"100013"},{"KundenNr":"100009"},{"KundenNr":"100008"},{"KundenNr":"100012"},{"KundenNr":"100006"},{"KundenNr":"100005"},{"KundenNr":"100003"},{"KundenNr":"100004"},{"KundenNr":"100002"}]}

Man sieht, daß trotzdem alle zulässigen Felder unterstützt werden, die Abfrage deswegen nicht komplett scheitert.

BestellNr, ArtikelNr, LfdNr


Pagination

Mittels der Pagination kann man sich die Daten in einzelnen Blöcken darstellen lassen.

Dafür werden die Parameter zum api_get-Befehl übergeben:

ParameterFormatDefault
offsetInteger0
limitInteger0

offset definiert ab welchem Datensatz weitergelesen werden soll

limit wiederum begrenzt die Anzahl der Datensätze die ausgegeben werden sollen

Da jeder neue Abschnitt auch die Daten neu liest kann es zu Verschiebungen kommen, wenn im Verlauf einer Abfrage Daten in einer bestimmten Ordnung hinzugefügt oder gelöscht werden.

In der Rückmeldung wird immer angeben, wieviele records vorhanden sind: 

{"total_in_query":25,"offset":0} - wenn es weder limit noch offset gab

{"total_in_query":25,"offset":25,"total_in_page":0} - wenn limit und offset angegeben waren.

Werte, die nicht erfüllt werden können, werden dabei ohne Fehlermeldung auf das mögliche reduziert, was ggf. auch in einer leeren Rückgabe münden kann.

Fehlermeldungen

"error":"" - immer am Anfang der JSON-Response
"errorMsg":"" - immer am Ende der JSON-Response
"structure_access_info":[] - vor den Nutzdaten

Neue Daten schreiben mit api_put_*

API-Basis = http://<Servername im LAN oder WAN |LAN oder WAN-IP|>:8080/4DAction/api_put_<areaname>

weitere Parameter:

update - Werte: True oder False. Regelt, ob ein vorhandener Datensatz aktualisiert werden soll oder nicht. Bei Neuanlage kann dieses Flag weggelassen werden.

response - Werte: HTML oder JSON. Regelt, ob die Rückmeldung als HTML-Seite oder als JSON-Objekt erfolgen soll. Lassen Sie dieses Flag weg, wird JSON rückgeliefert.

Exklusiv für api_put_bestellpos und api_put_projectpos:

append - Werte: True oder False. Bestimmt ob die gegenwärtige Positionsnummer hochgezählt werden soll, ist das der Fall gibt man bei Positionsnummer (api_put_projectpos) bzw. LfdNr (api_put_bestellpos) 0 an.

Ausgeschlossene Parameter:

host - Dieser Parameter wird intern verwendet und kann nicht übergeben werden

Die obigen Angaben gelten für alle api_put_*-Aufrufe bis auf api_put_time, das einen Sonderstatus einnimmt.

Für die verschiedenen put-Befehle wird auf jeweils eine Tabelle schreibend zugriffen. Bestimmte Felder dürfen nicht geschrieben werden, dies ist unten in der Dokumentation jeweils aufgeführt.

Beispiel Templates (api_put_*)

Wir haben für das Testen der API-Methoden ein kleines Template-Paket auf GitHub bereitgestellt, ebenso stehen die Templates auch als Zip-Datei zur Verfügung. Die konkreten Beispiele sind auf den jeweiligen API-Seite mit Screenshot und Direktverlinkung verfügbar.

Verhalten bei gesperrten Datensätzen

Versuchen Sie mit einem api_put_* Aufruf Daten zu verändern die gerade in Profacto geöffnet sind schlägt der Aufruf fehl.

Daraufhin wird eine Response zurückgegeben die das ganz klar kommuniziert und ermöglicht automatisiert auf solche Situationen einzugehen.

Beispiel einer entsprechenden Response:

{"success":false,"error":"Datensatz der Tabelle Kunden mit Schlüssel KundenNr:100019 ist gesperrt und kann nicht geschrieben werden.","processingTime":7575,"errorMsg":"Datensatz der Tabelle Kunden mit Schlüssel KundenNr:100019 ist gesperrt und kann nicht geschrieben werden."}