What is EUDR and Why Should You Care?
The European Union Deforestation Regulation (EUDR) is a game-changing environmental law that came into effect in June 2023. It's designed to stop the import of products that contribute to deforestation and forest degradation worldwide. But here's the kicker: it affects any business that imports or exports certain commodities to/from the EU market.
🌍 The EUDR Impact
EUDR covers seven key commodities:
- Timber and wood products
- Coffee and cocoa
- Soybeans and palm oil
- Beef and leather
- Rubber products
If your business deals with any of these products, you're now legally required to prove they're "deforestation-free" through comprehensive due diligence statements. Failure to comply can result in hefty fines, product seizures, and even market exclusion.
💡 How We're Solving the Problem
This is where www.eudr-api.eu comes in. We've built a production-ready, developer-friendly API that transforms the complex EUDR compliance process into simple REST endpoints. Instead of spending months building compliance systems from scratch, you can integrate our API in days and start submitting due diligence statements immediately.
Our platform handles:
- ✅ Automated validation of EUDR requirements
- ✅ Standardized data formats for all compliance documents
- ✅ Real-time submission to EU authorities
- ✅ Comprehensive tracking and amendment capabilities
- ✅ Developer-friendly REST API with clear documentation
Who This Guide Is For
This comprehensive guide is designed for:
- Developers building compliance applications
- Business analysts implementing EUDR workflows
- Compliance officers looking for technical solutions
- Product managers planning EUDR integration
- Anyone who needs to understand EUDR compliance from a technical perspective
What You'll Learn
By the end of this guide, you'll be able to:
- Understand EUDR compliance requirements and how our API addresses them
- Integrate all EUDR services into your applications
- Handle the complete compliance workflow from submission to amendment
- Implement proper error handling and validation
- Build production-ready EUDR compliance systems
🚀 Quick Start Guide
Prerequisites
Before you can use our API, you need:
- EUDR Web Service credentials from the EUDR Traces system
- API key from www.eudr-api.eu
Step 1: Get Your API Key
- Register for a free account at www.eudr-api.eu
- Verify your email address to activate your account
- Complete your profile setup to access the API
- Go to your API Keys Dashboard
- Create a new API key for either Test (Acceptance) environment
- Copy your API key - you'll need it for all requests
Step 2: Choose API Version
The API supports two versions with different DDS submission formats:
- Version 1: Legacy EUDR compliance
- Version 2: Latest EUDR standards (default and recommended)
Version Header (Optional):
x-api-eudr-version: 2
If no version header is provided, Version 2 is automatically selected.
Step 3: Make Your First API Call
Test your setup with the Echo Service - a simple connectivity verification endpoint:
Echo Service Endpoint:
GET /api/eudr/echo?message=Hello EUDR API
Complete Request Examples:
cURL:
curl -X GET "https://www.eudr-api.eu/api/eudr/echo?message=Hello EUDR API" \
-H "x-api-key: YOUR_API_KEY_HERE" \
-H "x-api-eudr-version: 2"
JavaScript:
const response = await fetch('/api/eudr/echo?message=Hello EUDR API', {
method: 'GET',
headers: {
'x-api-key': 'YOUR_API_KEY_HERE',
'x-api-eudr-version': '2'
}
});
const data = await response.json();
console.log(data);
Python:
import requests
url = "https://www.eudr-api.eu/api/eudr/echo"
params = {"message": "Hello EUDR API"}
headers = {
"x-api-key": "YOUR_API_KEY_HERE",
"x-api-eudr-version": "2"
}
response = requests.get(url, params=params, headers=headers)
data = response.json()
print(data)
R:
library(httr)
url <- "https://www.eudr-api.eu/api/eudr/echo"
query <- list(message = "Hello EUDR API")
headers <- add_headers(
"x-api-key" = "YOUR_API_KEY_HERE",
"x-api-eudr-version" = "2"
)
response <- GET(url, query = query, headers)
data <- content(response, "parsed")
print(data)
.NET:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY_HERE");
client.DefaultRequestHeaders.Add("x-api-eudr-version", "2");
var response = await client.GetAsync("https://www.eudr-api.eu/api/eudr/echo?message=Hello EUDR API");
var content = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<dynamic>(content);
Console.WriteLine(data);
API Overview
Base Configuration
-
Base URL:
https://www.eudr-api.eu/api
-
EUDR base path:
/eudr
-
API versions:
1
and2
(defaults to2
if not specified) -
Authentication: API key required via
x-api-key
header
Required Headers
x-api-key: <YOUR_API_KEY>
x-api-eudr-version: 2 # Optional, defaults to '2'
Content-Type: application/json # For POST/PUT/DELETE requests
Response Format
All endpoints return responses in this consistent format:
{
"status": "success|error",
"httpStatus": 200|201|400|401|500,
"data": { /* response data */ },
"message": "Error message if applicable",
"code": "ERROR_CODE if applicable",
"details": { /* additional error details */ }
}
Authentication Headers Reference
Header | Description | Example | Required |
---|---|---|---|
x-api-key |
Your API authentication key | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... |
✅ Required |
x-api-eudr-version |
API version (1 or 2) | 2 |
⚠️ Optional |
Authorization |
Alternative auth method (legacy) | Bearer YOUR_API_KEY |
⚠️ Optional |
Response Codes
Code | Status | Description |
---|---|---|
200 | Success | Request completed successfully |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | EUDR credentials not configured |
408 | Request Timeout | Timestamp window expired |
500 | Server Error | Internal server error |
1. Echo Service - Connectivity Testing
Purpose: Test API connectivity and verify credentials
Endpoints:
-
GET /eudr/echo
- Query parameter based -
POST /eudr/echo
- Body parameter based
Validation Rules:
-
message
parameter is required - For GET:
?message=<string>
- For POST:
{"message": "<string>"}
Request Examples:
GET:
curl -X GET \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/echo?message=ping"
POST:
curl -X POST \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message":"ping"}' \
"https://www.eudr-api.eu/api/eudr/echo"
Response:
{
"status": "success",
"httpStatus": 200,
"data": {
"message": "ping"
}
}
Error Response (400):
{
"status": "error",
"httpStatus": 400,
"message": "Message is required"
}
2. DDS Submission Service
Purpose: Create new Due Diligence Statement (DDS) submissions
Endpoint: POST /eudr/dds
Validation Rules:
- Request body must not be empty
- Full DDS statement data required
- API version affects validation schema
Request Example:
{
"operatorType": "OPERATOR",
"statement": {
"internalReferenceNumber": "HR-000002",
"activityType": "DOMESTIC",
"borderCrossCountry": "FR",
"comment": "Test submission",
"commodities": [
{
"position": 1,
"descriptors": {
"descriptionOfGoods": "Timber products",
"goodsMeasure": {
"volume": 20,
"netWeight": 40,
"supplementaryUnit": 10,
"supplementaryUnitQualifier": "MTQ"
}
},
"hsHeading": "4401",
"speciesInfo": {
"scientificName": "Carpinus betulus",
"commonName": "Hornbeam"
},
"producers": [
{
"country": "FR",
"name": "Producer 1",
"geometryGeojson": "<BASE64_ENCODED_GEOJSON>"
}
]
}
],
"geoLocationConfidential": false
}
}
Response (201):
{
"status": "success",
"httpStatus": 201,
"data": {
"ddsIdentifier": "UUID-12345-67890"
}
}
Error Response (400):
{
"status": "error",
"httpStatus": 400,
"message": "DDS statement data is required"
}
3. DDS Retrieval Services
3.1 Get DDS Info by UUIDs
Purpose: Retrieve DDS information using UUID identifiers
Endpoints:
GET /eudr/dds/info?uuids=UUID1,UUID2,UUID3
POST /eudr/dds/info
Validation Rules:
- GET:
uuids
as comma-separated string - POST:
uuids
as array in request body - At least one UUID required
- All UUIDs must be strings
Request Examples:
GET:
curl -X GET \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/dds/info?uuids=UUID1,UUID2,UUID3"
POST:
curl -X POST \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"uuids": ["UUID1", "UUID2", "UUID3"]}' \
"https://www.eudr-api.eu/api/eudr/dds/info"
Response:
{
"status": "success",
"httpStatus": 200,
"data": [
{
"uuid": "UUID1",
"info": { /* DDS information */ }
},
{
"uuid": "UUID2",
"info": { /* DDS information */ }
}
]
}
3.2 Search by Internal Reference Number
Purpose: Find DDS statements using internal reference numbers
Endpoints:
GET /eudr/dds/info/search?internalReferenceNumber=REF123
POST /eudr/dds/info/search
Validation Rules:
-
internalReferenceNumber
is required - Must be a string
Request Examples:
GET:
curl -X GET \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/dds/info/search?internalReferenceNumber=HR-000002"
POST:
curl -X POST \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"internalReferenceNumber": "HR-000002"}' \
"https://www.eudr-api.eu/api/eudr/dds/info/search"
3.3 Get Statement by Identifiers
Purpose: Retrieve final DDS statements using reference and verification numbers
Endpoints:
GET /eudr/dds/statement?referenceNumber=REF001&verificationNumber=VER001
POST /eudr/dds/statement
Validation Rules:
- Both
referenceNumber
andverificationNumber
are required - Both must be strings
Request Examples:
GET:
curl -X GET \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/dds/statement?referenceNumber=REF001&verificationNumber=VER001"
POST:
curl -X POST \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"referenceNumber": "REF001", "verificationNumber": "VER001"}' \
"https://www.eudr-api.eu/api/eudr/dds/statement"
4. DDS Amendment Service
Purpose: Modify existing DDS statements
Endpoint: PUT /eudr/dds
Validation Rules:
-
ddsIdentifier
is required (string) -
statement
object is required and must not be empty
Request Example:
{
"ddsIdentifier": "UUID-12345-67890",
"statement": {
"comment": "Updated comment",
"commodities": [
{
"position": 1,
"descriptors": {
"descriptionOfGoods": "Updated timber description"
}
}
]
}
}
Response:
{
"status": "success",
"httpStatus": 200,
"data": {
"ddsIdentifier": "UUID-12345-67890",
"message": "Amendment successful"
}
}
Error Response (400):
{
"status": "error",
"httpStatus": 400,
"message": "DDS identifier is required"
}
5. DDS Retraction Service
Purpose: Withdraw existing DDS statements
Endpoint: DELETE /eudr/dds
Validation Rules:
-
ddsIdentifier
is required (string)
Request Example:
{
"ddsIdentifier": "UUID-12345-67890"
}
Response:
{
"status": "success",
"httpStatus": 200,
"data": {
"ddsIdentifier": "UUID-12345-67890",
"message": "Retraction successful"
}
}
6. HS Codes Service
Purpose: Look up Harmonized System codes for product classification
Endpoints:
GET /eudr/hscodes?section=timber
POST /eudr/hscodes
Validation Rules:
-
section
parameter is optional - Uses regex for partial matching (case-insensitive)
- Returns all codes if no section specified
Request Examples:
GET:
curl -X GET \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/hscodes?section=timber"
POST:
curl -X POST \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"section": "timber"}' \
"https://www.eudr-api.eu/api/eudr/hscodes"
Response:
{
"status": "success",
"data": [
{
"code": "4401",
"section": "Fuel wood, in logs, in billets, in twigs, in faggots or in similar forms"
},
{
"code": "4402",
"section": "Wood charcoal (including shell or nut charcoal), whether or not agglomerated"
}
]
}
API Versioning
The API supports two versions with the x-api-eudr-version
header:
- Version 1: Legacy EUDR compliance
- Version 2: Latest EUDR standards (default)
Version Selection:
# Use version 1
curl -H "x-api-eudr-version: 1" \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/echo?message=test"
# Use version 2 (default)
curl -H "x-api-eudr-version: 2" \
-H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/echo?message=test"
# Omit header (defaults to version 2)
curl -H "x-api-key: YOUR_API_KEY" \
"https://www.eudr-api.eu/api/eudr/echo?message=test"
Error Handling
Common HTTP Status Codes
- 200: Success (GET, PUT, DELETE)
- 201: Created (POST)
- 400: Bad Request (validation errors)
- 401: Unauthorized (invalid/missing API key)
- 500: Internal Server Error
Error Response Structure
{
"status": "error",
"httpStatus": 400,
"message": "Validation error",
"code": "VALIDATION_ERROR",
"details": {
"field": "uuids",
"value": "",
"msg": "Array of UUIDs is required"
}
}
Validation Error Examples
Missing Required Fields:
{
"status": "error",
"httpStatus": 400,
"message": "Reference number and verification number are required"
}
Invalid API Version:
{
"status": "error",
"httpStatus": 400,
"message": "Invalid API version. Must be 1 or 2.",
"code": "INVALID_API_VERSION",
"details": {
"providedVersion": "3",
"allowedVersions": ["1", "2"],
"defaultVersion": "2"
}
}
Complete Integration Example
Here's a full workflow example using all services:
#!/bin/bash
# Set your API key
export EUDR_API_KEY="your-api-key-here"
export API_BASE="https://www.eudr-api.eu/api/eudr"
echo "🔍 Testing connectivity..."
curl -X POST \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message":"ping"}' \
"$API_BASE/echo"
echo -e "\n📝 Submitting DDS..."
curl -X POST \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d @statement.json \
"$API_BASE/dds"
echo -e "\n🔍 Retrieving DDS info..."
curl -X POST \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"uuids":["UUID1","UUID2"]}' \
"$API_BASE/dds/info"
echo -e "\n📋 Getting statement..."
curl -X POST \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"referenceNumber":"REF001","verificationNumber":"VER001"}' \
"$API_BASE/dds/statement"
echo -e "\n✏️ Amending DDS..."
curl -X PUT \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ddsIdentifier":"UUID123","statement":{"comment":"Updated"}}' \
"$API_BASE/dds"
echo -e "\n🗑️ Retracting DDS..."
curl -X DELETE \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ddsIdentifier":"UUID123"}' \
"$API_BASE/dds"
echo -e "\n🏷️ Looking up HS codes..."
curl -X POST \
-H "x-api-key: $EUDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"section":"timber"}' \
"$API_BASE/hscodes"
Rate Limiting & Usage Tracking
- Echo Service: No rate limits
- HS Codes: No rate limits (metered usage)
- All Other Services: There is a rate limit policy in place, but it is not strictly enforced. If you exceed your tier's limits, you will only receive warning notifications—no automatic blocking occurs. For higher or sustained usage, please contact us for an enterprise agreement. This generous approach ensures uninterrupted access while encouraging responsible use. 🚦
- Usage Tracking: All requests are logged
Best Practices
-
Always include API key: Every request requires
x-api-key
header - Use appropriate HTTP methods: GET for retrieval, POST for creation, PUT for updates, DELETE for removal
- Handle errors gracefully: Check HTTP status codes and error messages
- Validate data: Ensure required fields are present before sending
-
Use versioning: Specify
x-api-eudr-version
if you need specific behavior - Monitor usage: Track your API calls to stay within limits
Helpful Resources
- Website: www.eudr-api.eu - Main platform and documentation
- Registration: www.eudr-api.eu/register - Get your free API key
- Dashboard: www.eudr-api.eu/dashboard - Manage your API keys and usage
- Medium Tutorial: "How to Integrate with the EUDR Traces API using Node.js" - provides background context and integration patterns with our open source eudr-api-client
- Open Source Client: eudr-api-client - Node.js library for EUDR TRACES system integration with automatic endpoint generation and comprehensive validation
- API Documentation: Interactive docs available at www.eudr-api.eu/api-docs
Conclusion
The www.eudr-api.eu platform provides a comprehensive, production-ready solution for EUDR compliance. With standardized endpoints, consistent response formats, and robust validation, you can integrate EUDR compliance into your applications quickly and reliably.
The API handles the complexity of EUDR requirements while providing a clean, RESTful interface that developers can easily work with. Whether you're building compliance dashboards, integrating with existing systems, or creating new compliance workflows, this API gives you the tools you need.
Start with the echo endpoint to test connectivity, then explore the DDS services to understand the full compliance workflow. The comprehensive validation and error handling ensure you'll get clear feedback on any issues, making integration straightforward and reliable.
Ready to get started? Register for free at www.eudr-api.eu and begin your EUDR compliance journey today!
*This guide covers the complete www.eudr-api.eu EUDR API based on the actual implementation. For more information about our solutions or to discuss how we can help with your compliance needs, visit our website or reach out to our team.
Top comments (0)