EUDR TRACES API: ERP-Integration erfolgreich umsetzen – Herausforderungen und Alternativen

EUDR und TRACES API verstehen
Die EU Deforestation Regulation (EUDR) ist ein wegweisendes Gesetz, das Unternehmen verpflichtet nachzuweisen, dass bestimmte Rohstoffe (z. B. Holz, Kaffee, Soja usw.) entwaldungsfrei sind. Zur Einhaltung müssen Betreiber und Händler für jede relevante Lieferung oder Charge eine Due Diligence Statement (DDS) einreichen. Alle DDS-Einreichungen erfolgen über die TRACES-Plattform der EU (Trade Control and Expert System), ein Online-System, in dem Unternehmen Registrierungen vornehmen und Compliance-Erklärungen an Behörden übermitteln.
Wenn Ihr Unternehmen EUDR-pflichtig ist, werden Sie Ihre internen Systeme – insbesondere Ihr ERP – mit der EUDR TRACES API verbinden müssen, um die Übermittlung der DDS-Formulare zu automatisieren.
Die Arbeit mit der offiziellen TRACES API ist jedoch alles andere als trivial. Die Dokumentation ist sehr lückenhaft, und die Schnittstelle basiert auf dem ausgesprochen sperrigen SOAP-Standard. Das bedeutet: Die Integration Ihres ERP-Systems mit der EUDR TRACES API wird schnell zu einem erheblichen Entwicklungs- und Wartungsaufwand.
EUDR TRACES: Warum die Integration der API herausfordernd ist
Aus Entwicklersicht ist die Integration mit der TRACES SOAP API mühsam und komplex. Das Alter und der Aufbau der API zeigen sich in mehreren Aspekten:
- Veraltetes SOAP- & XML-Protokoll: Die TRACES API basiert auf SOAP – einem Protokoll, das heute als überholt gilt. Moderne Entwickler, die JSON/REST gewohnt sind, empfinden SOAP als umständlich und unflexibel, da sämtliche Daten in umfangreiche XML-Envelopes eingebettet werden müssen. Das Parsen und Generieren von XML erzeugt zusätzlichen Aufwand und fühlt sich wie ein technischer Rückschritt an.
- Komplexe Authentifizierung (WS-Security): Die Authentifizierung erfolgt nicht über ein simples API-Token im Header. Stattdessen müssen Hashes berechnet und exakt definierte Security-Header und Tokens nach dem WS-Security-Standard in das SOAP-XML eingebettet werden. Diese Header (mit Timestamps, Benutzernamen und Password Tokens) korrekt zu erstellen, ist nicht trivial und führt häufig zu Integrationsfehlern.
- Manuelle XML-Erstellung: Jede DDS-Übermittlung muss exakt dem XML-Schema entsprechen, das TRACES erwartet. Diese manuelle XML-Erstellung ist mühsam und fehleranfällig. Schon geringfügige Formatierungsprobleme führen zu vollständigen Request-Fehlern. Viele Entwickler verbringen mehr Zeit mit dem Debuggen von XML-Schemas als mit der eigentlichen Business-Logik.
- Schwieriges Error Handling: Im Fehlerfall liefert die TRACES API SOAP Faults, eingebettet in verschachteltes XML. Diese Fehlermeldungen sind oft kryptisch und schwer zu interpretieren. Das Debuggen (z. B. warum eine Einreichung abgelehnt wurde) dauert deutlich länger als bei modernen JSON-basierten REST-APIs und verlangsamt Entwicklungs- und Testzyklen.
- Begrenzte Dokumentation & starre Workflows: Die TRACES-Dokumentation ist sehr spärlich und hat sich in der Vergangenheit mehrfach geändert. Jede Aktualisierung seitens der EU kann bedeuten, dass SOAP-Clients neu generiert oder XML-Strukturen angepasst werden müssen – ein äußerst lästiger Prozess.
Versionen und Updates der TRACES API
Eine weitere Schwierigkeit besteht darin, dass die EUDR TRACES API mehrfach geändert wurde – und sich voraussichtlich weiter ändern wird. Da die Einführung von EUDR noch frisch ist, aktualisiert die Europäische Kommission die technischen Spezifikationen fortlaufend. Frühe Implementierer wurden explizit gewarnt, dass die Spezifikationen nicht final sind und Änderungen zu erwarten sind. Das bedeutet: XML-Schemas oder Methoden, gegen die Sie vor einigen Monaten noch entwickelt haben, können kurzfristig überholt sein.
Auch regulatorische Anpassungen können neue Anforderungen erzeugen. Beispielsweise wurde 2025 über eine „vereinfachte“ Due Diligence für bestimmte Händler diskutiert. Aktuell existiert jedoch ausschließlich der ursprüngliche SOAP-Service zur Automatisierung der EUDR-Compliance. Sobald neue Endpunkte oder Felder für vereinfachte Verfahren eingeführt werden, müssen Unternehmen ihre Integrationen erneut anpassen.Mit anderen Worten: Die Integration mit TRACES ist kein einmaliges Projekt, sondern ein fortlaufender Wartungsprozess, der an den Zyklus regulatorischer Änderungen gebunden ist.
Integration eines ERP-Systems mit TRACES via SOAP
Trotz aller Herausforderungen ist die direkte Integration eines ERP-Systems mit der EUDR TRACES API machbar – vorausgesetzt, sie wird sauber geplant. Ziel ist, dass Ihr ERP automatisch Due Diligence Statements an TRACES übermittelt, sobald relevante Lieferungen bewegt werden. Typischerweise umfasst eine ERP–TRACES-Integration:
- Datenextraktion aus dem ERP: Ermittlung aller benötigten DDS-Daten (Rohstoff, Menge/HS-Code, Lieferant, Geokoordinaten, referenzierte DDS) und ggf. Erweiterung des ERP-Datenmodells.
- Erstellung des SOAP-Requests: Aufbau der SOAP-XML-Nachricht gemäß TRACES-WSDL inklusive WS-Security-Header (Username, API-Key im
<UsernameToken>), entweder über generierte Clients oder manuell per XML-Library. - Versand & Response-Verarbeitung: Versand der SOAP-Message per HTTPS an den jeweiligen Endpoint (ACCEPTANCE/Produktion), Auslesen und Speichern der DDS Reference Number im ERP; bei SOAP Faults Logging, Fehlerbehandlung und ggf. Retry/Manuell-Workflow.
- Updates und Abfragen: Nutzung verfügbarer API-Operationen zum Abrufen/Aktualisieren von DDS sowie laufende Anpassung an neue API-Versionen und zusätzliche Funktionen (z. B. Abfragen per Reference Number).
Beispiel: Direkte Erstellung eines Due Diligence Statements mit der TRACES API in Java
Um die Komplexität zu veranschaulichen, folgt ein vereinfachter Java-Snippet, der eine SOAP-Message für einen einzelnen Endpoint der TRACES API erstellt.
In diesem Beispiel werden die SOAP-Libraries von Java verwendet, um einen submitDDS-Request mit einer Dummy-Struktur zu konstruieren. In einem realen Szenario würden Sie tatsächliche Feldwerte aus Ihrem ERP sowie die offiziellen Namespace- und Elementnamen aus der WSDL verwenden. (Hinweis: In der Praxis würden Sie häufig Proxy-Klassen aus der WSDL generieren – hier zeigen wir zur Einordnung bewusst die rohe SOAP-Struktur.)
import javax.xml.soap.*;
import javax.xml.namespace.QName;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;
public class TracesEudrClient {
private static final String TRACES_BASE_URL = "https://acceptance.eudr.webcloud.ec.europa.eu";
private static final String SUBMISSION_SERVICE_PATH = "/tracesnt/ws/EUDRSubmissionServiceV2";
private static final String WEB_SERVICE_CLIENT_ID = "eudr-test"; // "eudr-repository" for production
private static final int TIMESTAMP_VALIDITY_SECONDS = 60;
private static final int TIMEOUT_MS = 10000;
private final String username;
private final String authenticationKey;
public TracesEudrClient(String username, String authenticationKey) {
this.username = username;
this.authenticationKey = authenticationKey;
}
private String generatePasswordDigest(byte[] nonceBytes, String created) throws Exception {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(nonceBytes);
digest.update(created.getBytes("UTF-8"));
digest.update(authenticationKey.getBytes("UTF-8"));
byte[] hash = digest.digest();
return Base64.getEncoder().encodeToString(hash);
}
public SOAPMessage submitDDS(String operatorType, String statementXml) throws Exception {
String soapEndpointUrl = TRACES_BASE_URL + ":443" + SUBMISSION_SERVICE_PATH;
String soapAction = "http://ec.europa.eu/tracesnt/certificate/eudr/submission/v2/submitDds";
// 1. Generate security tokens
SecureRandom random = new SecureRandom();
byte[] nonceBytes = new byte[16];
random.nextBytes(nonceBytes);
String nonceBase64 = Base64.getEncoder().encodeToString(nonceBytes);
Date now = new Date();
String created = formatISO8601(now);
Calendar cal = Calendar.getInstance();
cal.setTime(now);
cal.add(Calendar.SECOND, TIMESTAMP_VALIDITY_SECONDS);
String expires = formatISO8601(cal.getTime());
String passwordDigest = generatePasswordDigest(nonceBytes, created);
// Generate unique IDs for security elements
String timestampId = "TS-" + UUID.randomUUID().toString();
String usernameTokenId = "UsernameToken-" + UUID.randomUUID().toString();
// 2. Create SOAP Connection
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = scf.createConnection();
// 3. Construct the SOAP Message
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
// Add namespaces
envelope.addNamespaceDeclaration("v2", "http://ec.europa.eu/tracesnt/certificate/eudr/submission/v2");
envelope.addNamespaceDeclaration("v21", "http://ec.europa.eu/tracesnt/certificate/eudr/model/v2");
envelope.addNamespaceDeclaration("v4", "http://ec.europa.eu/sanco/tracesnt/base/v4");
// 4. Build SOAP Header with WS-Security
SOAPHeader header = envelope.getHeader();
// Add Security element with mustUnderstand="1"
SOAPElement security = header.addChildElement("Security", "wsse",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
security.addNamespaceDeclaration("wsu",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
security.addAttribute(envelope.createQName("mustUnderstand", "soapenv"), "1");
// Add Timestamp
SOAPElement timestamp = security.addChildElement("Timestamp", "wsu");
timestamp.addAttribute(new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
"Id", "wsu"), timestampId);
timestamp.addChildElement("Created", "wsu").addTextNode(created);
timestamp.addChildElement("Expires", "wsu").addTextNode(expires);
// Add UsernameToken
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
"Id", "wsu"), usernameTokenId);
usernameToken.addChildElement("Username", "wsse").addTextNode(username);
// Add Password with Type attribute
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.addAttribute(new QName("Type"),
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
password.addTextNode(passwordDigest);
// Add Nonce with EncodingType attribute
SOAPElement nonce = usernameToken.addChildElement("Nonce", "wsse");
nonce.addAttribute(new QName("EncodingType"),
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonce.addTextNode(nonceBase64);
// Add Created timestamp to UsernameToken
usernameToken.addChildElement("Created", "wsu").addTextNode(created);
// Add WebServiceClientId header (CRITICAL - required by TRACES)
SOAPElement clientId = header.addChildElement("WebServiceClientId", "v4");
clientId.addTextNode(WEB_SERVICE_CLIENT_ID);
// 5. Build SOAP Body
SOAPBody body = envelope.getBody();
SOAPElement submitRequest = body.addChildElement("SubmitStatementRequest", "v2");
submitRequest.addChildElement("operatorType", "v2").addTextNode(operatorType); // OPERATOR, TRADER, etc.
// Add statement element - you would insert your generated XML here
SOAPElement statementElement = submitRequest.addChildElement("statement", "v2");
// Note: You need to parse and insert the statementXml properly
// This is a simplified example - in practice you'd need to parse the XML
// and add it as child elements or use a DOM approach
statementElement.addTextNode(statementXml);
// Set SOAPAction header
MimeHeaders mimeHeaders = soapMessage.getMimeHeaders();
mimeHeaders.addHeader("SOAPAction", soapAction);
soapMessage.saveChanges();
// Optional: Print request for debugging
System.out.println("=== SOAP Request ===");
soapMessage.writeTo(System.out);
System.out.println("\n");
// 6. Send the SOAP request and get the response
SOAPMessage response = connection.call(soapMessage, soapEndpointUrl);
connection.close();
// 7. Process the response
System.out.println("=== SOAP Response ===");
response.writeTo(System.out);
System.out.println("\n");
if (response.getSOAPBody().hasFault()) {
SOAPFault fault = response.getSOAPBody().getFault();
String faultCode = fault.getFaultCode();
String faultString = fault.getFaultString();
System.err.println("SOAP Fault - Code: " + faultCode + ", String: " + faultString);
if ("env:Client".equals(faultCode) && "UnauthenticatedException".equals(faultString)) {
throw new TracesApiException("UNAUTHENTICATED", "Authentication failed");
}
// Check for BusinessRulesValidationException in fault detail
Detail detail = fault.getDetail();
if (detail != null) {
// Parse detail for BusinessRulesValidationException
// This would require additional XML parsing logic
}
throw new TracesApiException("SOAP_FAULT", faultString);
}
return response;
}
/**
* Custom exception class for TRACES API errors
*/
public static class TracesApiException extends Exception {
private final String code;
public TracesApiException(String code, String message) {
super(message);
this.code = code;
}
public String getCode() {
return code;
}
}
/**
* Example usage
*/
public static void main(String[] args) {
try {
String username = System.getenv("TRACES_ACCEPTANCE_EUDR_USERNAME");
String authKey = System.getenv("TRACES_ACCEPTANCE_AUTHENTICATION_KEY");
if (username == null || authKey == null) {
throw new IllegalArgumentException(
"TRACES_ACCEPTANCE_EUDR_USERNAME and TRACES_ACCEPTANCE_AUTHENTICATION_KEY must be set");
}
TracesEudrClient client = new TracesEudrClient(username, authKey);
// You would generate this XML using a service similar to TracesStatementXMLService
String statementXml = "IMPORT ...";
SOAPMessage response = client.submitDDS("OPERATOR", statementXml);
System.out.println("✅ DDS submitted successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Eine moderne Alternative: Die Tanso EUDR API
Angesichts der Herausforderungen der offiziellen TRACES API bietet Tanso eine moderne REST API als Alternative an. Damit können Sie Ihr ERP-System mit dem EUDR-TRACES-System verbinden, ohne direkt mit der TRACES-Schnittstelle arbeiten zu müssen. Als API Gateway wandelt Tansos Lösung nicht nur die komplexen SOAP-Aufrufe in schlanke RESTful Endpoints um, sondern stellt zusätzlich weitergehende Funktionen bereit – etwa die automatische Prüfung von Lieferantendaten, Validierung von EUDR-relevanten Informationen oder unterstützende Services zur Qualitätssicherung Ihrer DDS-Einreichungen.
Beispiel: Erstellung einer Sorgfältigkeitserklärung mit der Tanso EUDR API
Hier ein minimalistisches Java-Beispiel, das zeigt, wie eine DDS über die Tanso REST API erstellt wird:
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpClient.Version;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class TansoEudrClient {
private final String apiKey;
private final HttpClient httpClient;
public TansoEudrClient(String apiKey) {
this(apiKey, HttpClient.newBuilder()
.version(Version.HTTP_2)
.connectTimeout(Duration.ofMillis(TIMEOUT_MS))
.build());
}
public String createDds(String ddsJson) {
String url = TANSO_EUDR_BASE_URL + EUDR_DDS_PATH;
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.tanso.de/v2/eudr/dds"))
.header("Content-Type", "application/json")
.header("X-API-Key", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(ddsJson))
.build();
HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
String body = response.body();
return body;
}
public static void main(String[] args) {
try {
TansoEudrClient client = new TansoEudrClient(System.getenv("TANSO_EUDR_API_KEY"));
String ddsJson = """
{
"operatorType": "OPERATOR",
"statement": {
"activityType": "IMPORT"
// ... rest of your DDS data ...
}
}
""";
String responseBody = client.createDds(ddsJson);
System.out.println("✅ DDS created successfully");
System.out.println("Response from Tanso EUDR API:");
System.out.println(responseBody);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Statt XML zu erzeugen und Versionsänderungen nachzuverfolgen, kann Ihr ERP (oder Ihre Middleware) JSON-Requests an eine klar dokumentierte und stabile REST API senden. Das Gateway übernimmt anschließend die SOAP-Kommunikation mit TRACES im Hintergrund. Das bringt mehrere entscheidende Vorteile:
- Schnellere Integration: Eine REST API mit JSON reduziert den Entwicklungsaufwand deutlich. Ihr Team arbeitet mit vertrauten JSON-Payloads und normalen HTTP-Requests, die von modernen ERP-Systemen und Integrationsplattformen nativ unterstützt werden.
- Entwicklerfreundliches Design: Tansos EUDR API ist auf Nutzungskomfort ausgelegt – mit klarer Dokumentation und konsistenten RESTful Endpoints. Das Einreichen einer neuen Sorgfaltserklärung kann beispielsweise ein einfacher HTTP-
POSTauf/api/eudr/v1/ddsmit einem JSON-Body sein. Die Plattform übernimmt die korrekte Transformation in die verlangte TRACES SOAP-Struktur. - Wegfall von Boilerplate: Das REST Gateway kapselt die komplette Authentifizierung und alle technischen Details. Es übernimmt WS-Security, Session Handling und die Übersetzung von Fehlern. Sie erhalten stattdessen klare Erfolgs- oder Fehlermeldungen mit hilfreichen Hinweisen. Dadurch können sich Ihre Entwickler auf die Business-Logik konzentrieren statt auf Infrastruktur-Code.
- Erweiterte Funktionen: Tansos Lösung bietet ein Dashboard zur Nachverfolgung von Einreichungen, vollständige Logs aller API Calls sowie Suchfunktionen, um DDS Reference Numbers in Ihrer Lieferkette zu prüfen. Diese Funktionen unterstützen insbesondere neue Anforderungen wie die Pflicht, DDS- oder Referenznummern von Lieferanten zu verifizieren und weiterzugeben.
Ein gemanagtes REST API Gateway ist ein effizienter Weg, Ihre EUDR-ERP-Integration zukunftssicher zu gestalten. Sie vermeiden die Komplexität direkter SOAP-Interaktion, sparen Entwicklungszeit und erhalten eine Lösung, die sich automatisch an Regulatorik Änderungen anpasst. Tansos Plattform bietet die Zuverlässigkeit und Skalierbarkeit einer professionell betriebenen Lösung, sodass sich Ihr Team auf Kernprozesse konzentrieren kann, statt auf Low-Level-Integrationen.
Fazit
Die Anbindung Ihres ERP-Systems an die EUDR TRACES API ist zentral für eine pragmatische und rechtskonforme Implementierung der Entwaldungsverordnung (EUDR). Doch die offizielle SOAP-Schnittstelle ist technisch veraltet, schwer zu integrieren und aufwendig zu warten. XML-Overhead, komplexe Authentifizierung und häufige Änderungen machen eine direkte Implementierung für viele Unternehmen unnötig kostspielig.
Eine moderne Alternative bietet Tansos REST API für EUDR: eine klar dokumentierte, ERP-freundliche Schnittstelle, die die Eigenheiten der Traces API vollständig abstrahiert. Damit reduzieren Sie Entwicklungsaufwand, vermeiden Integrationsfehler und bleiben trotz zukünftiger TRACES-Updates flexibel und stabil angebunden.
Der beste Zeitpunkt zu handeln ist jetzt: Eine robuste, zukunftssichere Integrationsstrategie spart Zeit, reduziert Risiken und stellt sicher, dass Ihre EUDR-Prozesse zuverlässig laufen – ohne Ihre operativen Abläufe zu belasten.
Entdecken Sie Tanso –
Ihre Komplettlösung für Nachhaltigkeit
Andere Artikel, die für Sie interessant sein könnten
Erfahren Sie Neuigkeiten aus dem Tansoversum.











































.avif)







.jpg)
.jpg)





















-p-800.webp.avif)
-min-p-800.webp.avif)






-p-800.webp.avif)

