To integrate Replit with the DHL API, register a DHL developer account, generate an API key for the Shipment Tracking or Express APIs, store it in Replit Secrets (lock icon π), and call DHL's REST APIs from Python or Node.js to track shipments and get express quotes. DHL provides the strongest international shipping coverage, making it ideal for global e-commerce backends.
Why Connect Replit to DHL?
DHL is the world's largest international logistics company, operating in over 220 countries. For e-commerce platforms and order management systems built on Replit, the DHL API enables real-time shipment tracking, rate calculations, label generation, and pickup scheduling. If your customers or products cross international borders, DHL's API coverage is unmatched compared to domestic-focused carriers.
The DHL developer portal (developer.dhl.com) provides access to several distinct APIs: the Shipment Tracking API for tracking parcels by waybill number across all DHL service lines (Express, eCommerce, Parcel), the Express API for creating shipments with DHL Express and generating labels, and the eCommerce API for lower-cost international parcel services. Each API has its own authentication and endpoint structure.
Replit is well-suited for building DHL integrations because it provides always-on deployment for webhook receivers, supports both Python and Node.js for calling DHL's REST endpoints, and makes it easy to test API calls in the Shell before deploying. Store your DHL API key in Replit Secrets (lock icon π) to keep it out of your codebase and safe from Replit's built-in Secret Scanner.
Integration method
You connect Replit to DHL by registering at developer.dhl.com, subscribing to the APIs you need (Tracking, Express, or eCommerce), generating an API key, storing it in Replit Secrets, and calling DHL's REST endpoints from your server-side Python or Node.js code. DHL uses API key authentication for tracking and OAuth for some Express endpoints. All API calls should originate from your backend to protect credentials.
Prerequisites
- A Replit account with a Python or Node.js project created
- A DHL developer account registered at developer.dhl.com
- An active DHL business account (required for Express shipment creation β tracking API is available without a business account)
- Basic familiarity with REST APIs and HTTP authentication headers
- Node.js 18+ or Python 3.10+ (both available on Replit by default)
Step-by-step guide
Register at DHL Developer Portal and Get API Keys
Register at DHL Developer Portal and Get API Keys
Navigate to developer.dhl.com and create a developer account using your email address. Once registered, you will see the API catalog listing all available DHL APIs. For tracking shipments, subscribe to the 'DHL Shipment Tracking' API β this is free for tracking queries and does not require a DHL business account. Click 'Subscribe' and choose the 'Free' plan. After subscribing, go to your account dashboard and find the 'My Applications' section. Create a new application and select the Shipment Tracking API. Your API key (also called a DHL-API-Key) will be displayed on the application page. For creating shipments with DHL Express, you will need to subscribe to the 'DHL Express β MyDHL API'. This API requires an active DHL Express account number (account number from your DHL billing). The Express API uses Basic Authentication with your DHL account credentials rather than a standalone API key. Copy your API key from the developer portal β it will look like a long alphanumeric string. You will use this as the DHL-API-Key header in all tracking requests.
Pro tip: DHL provides sandbox environments for testing. Use the sandbox base URL (https://api-mock.dhl.com/ or similar) during development to avoid consuming production rate limits. Check the developer portal documentation for the current sandbox URL for each API.
Expected result: You have a DHL developer account, a subscribed application, and an API key copied from the developer portal dashboard.
Store DHL Credentials in Replit Secrets
Store DHL Credentials in Replit Secrets
Open your Replit project and click the lock icon π in the left sidebar to open the Secrets pane. Add your DHL credentials: - Key: DHL_API_KEY β Value: your DHL API key from the developer portal - Key: DHL_ACCOUNT_NUMBER β Value: your DHL Express account number (if using Express shipment creation) For the Express API (which uses Basic Auth), you may also need: - Key: DHL_EXPRESS_USER β Value: your DHL Express username - Key: DHL_EXPRESS_PASSWORD β Value: your DHL Express password Click 'Add Secret' after each entry. In Python, access these with os.environ['DHL_API_KEY']. In Node.js, use process.env.DHL_API_KEY. DHL API keys grant access to tracking data for any shipment β treat them with the same care as any production API credential. Replit's Secret Scanner will alert you if a key is accidentally written to a code file.
Pro tip: Create separate DHL developer applications for your sandbox/development environment and production environment. Store sandbox keys in Replit Secrets with a SANDBOX_ prefix (e.g., DHL_SANDBOX_API_KEY) so you can easily switch between environments.
Expected result: DHL_API_KEY and other DHL credentials appear in Replit Secrets with masked values.
Track Shipments with Python
Track Shipments with Python
The DHL Shipment Tracking API v2 is straightforward β send a GET request to https://api-eu.dhl.com/track/shipments with the trackingNumber query parameter and the DHL-API-Key header. The response returns a detailed tracking object with events, estimated delivery, and current status. The API supports tracking across all DHL service lines (DHL Express, DHL eCommerce, DHL Parcel) using the same endpoint. Multiple tracking numbers can be queried in a single request by passing them as a comma-separated string. The Python code below implements tracking, batch tracking, and event parsing utilities. It also handles the most common API responses including not-found errors and incomplete data scenarios.
1import os2import requests3from typing import Optional45DHL_API_KEY = os.environ["DHL_API_KEY"]6BASE_URL = "https://api-eu.dhl.com"78HEADERS = {9 "DHL-API-Key": DHL_API_KEY,10 "Accept": "application/json"11}1213def track_shipment(tracking_number: str) -> dict:14 """15 Track a DHL shipment by waybill/tracking number.16 Returns the full tracking response including events and status.17 """18 params = {"trackingNumber": tracking_number}19 response = requests.get(20 f"{BASE_URL}/track/shipments",21 headers=HEADERS,22 params=params23 )24 response.raise_for_status()25 return response.json()2627def track_multiple(tracking_numbers: list) -> dict:28 """29 Track multiple shipments in one request (up to 10 numbers).30 Pass a list of tracking number strings.31 """32 numbers_str = ",".join(tracking_numbers[:10]) # API limit: 10 per request33 params = {"trackingNumber": numbers_str}34 response = requests.get(35 f"{BASE_URL}/track/shipments",36 headers=HEADERS,37 params=params38 )39 response.raise_for_status()40 return response.json()4142def get_latest_status(tracking_number: str) -> Optional[dict]:43 """44 Get the latest tracking event and overall status for a shipment.45 Returns None if the tracking number is not found.46 """47 try:48 data = track_shipment(tracking_number)49 shipments = data.get("shipments", [])50 if not shipments:51 return None52 shipment = shipments[0]53 events = shipment.get("events", [])54 latest_event = events[0] if events else {}55 return {56 "tracking_number": tracking_number,57 "status": shipment.get("status", {}).get("status"),58 "description": shipment.get("status", {}).get("description"),59 "estimated_delivery": shipment.get("estimatedTimeOfDelivery"),60 "latest_location": latest_event.get("location", {}).get("address", {}).get("addressLocality"),61 "latest_timestamp": latest_event.get("timestamp"),62 "latest_description": latest_event.get("description"),63 "event_count": len(events)64 }65 except requests.exceptions.HTTPError as e:66 if e.response.status_code == 404:67 return None68 raise6970if __name__ == "__main__":71 # Replace with a real DHL tracking number for testing72 test_tracking = "1234567890"73 result = get_latest_status(test_tracking)74 if result:75 print(f"Tracking {test_tracking}:")76 print(f" Status: {result['status']} β {result['description']}")77 print(f" Latest location: {result['latest_location']}")78 print(f" Estimated delivery: {result['estimated_delivery']}")79 else:80 print(f"Tracking number {test_tracking} not found")Pro tip: DHL's Tracking API rate limit is 250 requests per 60 seconds on the free tier. For batch processing many tracking numbers, implement a rate limiter using time.sleep() and process numbers in groups of 10 using the multi-tracking endpoint.
Expected result: Running the script with a valid DHL tracking number prints the shipment status, latest location, and estimated delivery date.
Build a Node.js Tracking Proxy with Express
Build a Node.js Tracking Proxy with Express
For web applications, a Node.js Express server acts as a secure proxy between your frontend and the DHL API. This is important because exposing your DHL API key in browser-side JavaScript would allow anyone to make unlimited tracking queries with your credentials. The Express server below exposes a clean /track/:waybill endpoint that your frontend can call. It also includes a /rates endpoint stub for integrating the DHL Express rates API, which requires Basic Authentication with your DHL Express account credentials instead of the standard API key. Install axios with npm install express axios in the Replit Shell. The server binds to 0.0.0.0:3000 for Replit's port routing. For production deployment, use Autoscale to handle variable tracking query loads, especially if your storefront has traffic spikes around shipping cut-off times.
1const express = require('express');2const axios = require('axios');34const app = express();5app.use(express.json());67const DHL_API_KEY = process.env.DHL_API_KEY;8const DHL_EXPRESS_USER = process.env.DHL_EXPRESS_USER;9const DHL_EXPRESS_PASSWORD = process.env.DHL_EXPRESS_PASSWORD;10const DHL_ACCOUNT_NUMBER = process.env.DHL_ACCOUNT_NUMBER;1112const trackingClient = axios.create({13 baseURL: 'https://api-eu.dhl.com',14 headers: {15 'DHL-API-Key': DHL_API_KEY,16 Accept: 'application/json'17 }18});1920const expressClient = axios.create({21 baseURL: 'https://express.api.dhl.com/mydhlapi',22 auth: {23 username: DHL_EXPRESS_USER,24 password: DHL_EXPRESS_PASSWORD25 },26 headers: { Accept: 'application/json' }27});2829// GET /track/:waybill β track a DHL shipment30app.get('/track/:waybill', async (req, res) => {31 try {32 const response = await trackingClient.get('/track/shipments', {33 params: { trackingNumber: req.params.waybill }34 });35 const shipments = response.data.shipments || [];36 if (!shipments.length) {37 return res.status(404).json({ error: 'Shipment not found' });38 }39 const shipment = shipments[0];40 res.json({41 trackingNumber: req.params.waybill,42 status: shipment.status?.status,43 description: shipment.status?.description,44 estimatedDelivery: shipment.estimatedTimeOfDelivery,45 events: (shipment.events || []).map(e => ({46 timestamp: e.timestamp,47 location: e.location?.address?.addressLocality,48 description: e.description49 }))50 });51 } catch (err) {52 const status = err.response?.status || 500;53 res.status(status).json({ error: err.response?.data?.detail || err.message });54 }55});5657// POST /rates β get DHL Express shipping rates58// Body: { fromCountry, toCountry, weight, length, width, height, plannedShipDate }59app.post('/rates', async (req, res) => {60 const { fromCountry, toCountry, weight, length, width, height, plannedShipDate } = req.body;61 try {62 const response = await expressClient.get('/rates', {63 params: {64 accountNumber: DHL_ACCOUNT_NUMBER,65 originCountryCode: fromCountry,66 destinationCountryCode: toCountry,67 weight,68 length,69 width,70 height,71 plannedShippingDateAndTime: plannedShipDate || new Date().toISOString()72 }73 });74 res.json(response.data);75 } catch (err) {76 res.status(err.response?.status || 500).json({ error: err.message });77 }78});7980app.listen(3000, '0.0.0.0', () => {81 console.log('DHL API proxy server running on port 3000');82});Pro tip: DHL has separate API base URLs for different regions β api-eu.dhl.com for European-origin requests and api-mock.dhl.com for sandbox testing. Switch the base URL via an environment variable (DHL_API_BASE) so you can toggle between sandbox and production without code changes.
Expected result: The server starts on port 3000. A GET request to /track/1234567890 returns structured tracking data for the waybill.
Common use cases
Order Tracking Page Backend
Build a Replit-hosted API that accepts a DHL waybill number from your storefront and returns the full shipment tracking history β including timestamps, locations, and delivery status. Your frontend calls this proxy endpoint rather than DHL directly, keeping your API key hidden from browser users.
Build a Flask server with a GET /track/:waybill endpoint that fetches tracking events from the DHL Shipment Tracking API using DHL_API_KEY from Replit Secrets and returns the events as structured JSON.
Copy this prompt to try it in Replit
Automated Shipping Rate Calculator
Integrate DHL Express rates into your checkout flow so customers see live shipping costs before placing an order. Your Replit backend queries DHL's Express rates API with package dimensions, weight, origin, and destination, then returns available service options and prices.
Create a Node.js Express server with a POST /shipping-rates endpoint that accepts origin, destination, weight, and dimensions in the request body, queries the DHL Express Rates API, and returns available shipping options with estimated prices and delivery times.
Copy this prompt to try it in Replit
Bulk Shipment Status Sync
Build a scheduled Replit script that reads open order IDs and DHL waybill numbers from your database, queries the DHL Tracking API for each in batches, and updates the order status in your system. This keeps your customer-facing order portal in sync with real DHL delivery data without customer-triggered polling.
Write a Python script that reads a list of DHL tracking numbers from a CSV file, queries the DHL Tracking API for each number with a 0.5-second delay between requests, and writes the latest shipment status and estimated delivery date back to the CSV.
Copy this prompt to try it in Replit
Troubleshooting
API returns 401 Unauthorized with 'Invalid API Key' message
Cause: The DHL-API-Key header value is incorrect, the API key belongs to a different environment (sandbox vs production), or the key has not been associated with a subscribed application in the developer portal.
Solution: Log in to developer.dhl.com and verify your application is active and subscribed to the Shipment Tracking API. Copy the API key directly from the application page β do not type it manually. Ensure DHL_API_KEY in Replit Secrets matches exactly, with no extra spaces or newline characters.
1# Python: verify API key is loaded correctly2api_key = os.environ.get('DHL_API_KEY', '')3print(f'API key length: {len(api_key)}, starts with: {api_key[:8]}...')4# Should print a non-zero length and a recognizable prefixTracking returns 404 for a valid DHL tracking number
Cause: The tracking number may be for a DHL service line not covered by the standard Tracking API, the shipment is too new (not yet scanned into the system), or the number format is incorrect.
Solution: DHL tracking numbers vary by service line β Express waybills are typically 10 digits starting with a letter, Parcel numbers follow a different format. Verify the format for your service line in the DHL developer documentation. New shipments may take 2-4 hours to appear in the tracking API after label creation.
1# Python: check response for additional error details2try:3 response = requests.get(url, headers=HEADERS, params=params)4 print('Status:', response.status_code)5 print('Response:', response.json())6except requests.exceptions.HTTPError as e:7 print('HTTP error:', e.response.json())DHL Express API returns 403 Forbidden for rate requests
Cause: The Express API (MyDHL API) uses Basic Auth with your DHL account username and password, not the API key. Using the API key in the Authorization header for Express endpoints will cause a 403.
Solution: The DHL Express (MyDHL API) and the Tracking API use different authentication mechanisms. Configure a separate axios/requests client for Express with Basic Auth credentials (DHL_EXPRESS_USER and DHL_EXPRESS_PASSWORD from Replit Secrets). The tracking API uses the DHL-API-Key header, while Express uses standard HTTP Basic Authentication.
1# Python: separate auth for Express vs Tracking APIs2import requests3from requests.auth import HTTPBasicAuth45# Tracking API β API key header6tracking_headers = {'DHL-API-Key': os.environ['DHL_API_KEY']}78# Express API β Basic Auth9express_auth = HTTPBasicAuth(os.environ['DHL_EXPRESS_USER'], os.environ['DHL_EXPRESS_PASSWORD'])Rate limit errors (429) when tracking many shipments
Cause: The free DHL Tracking API plan allows 250 requests per minute. Bulk tracking operations that exceed this limit will be throttled.
Solution: Implement rate limiting in your code β process tracking numbers in batches of 10 (the API allows up to 10 comma-separated numbers per request) and add a delay between batches. Apply for a higher-tier API plan in the developer portal if you consistently hit rate limits.
1import time23def batch_track(tracking_numbers: list, batch_size: int = 10) -> list:4 results = []5 for i in range(0, len(tracking_numbers), batch_size):6 batch = tracking_numbers[i:i + batch_size]7 data = track_multiple(batch)8 results.extend(data.get('shipments', []))9 if i + batch_size < len(tracking_numbers):10 time.sleep(0.25) # Stay under 250 req/min11 return resultsBest practices
- Store DHL_API_KEY and any Express credentials in Replit Secrets (lock icon π) β never hardcode them in source files or expose them to frontend clients.
- Use separate API clients for the DHL Tracking API (DHL-API-Key header) and the DHL Express API (Basic Auth) β mixing authentication methods will cause 401/403 errors.
- Batch tracking requests using comma-separated tracking numbers (up to 10 per request) to stay within rate limits when processing large order volumes.
- Cache tracking results for 15-30 minutes in a database or key-value store β shipment status rarely changes more frequently than that, and caching reduces API consumption.
- Use the DHL sandbox (api-mock.dhl.com) for development and testing β switch to production (api-eu.dhl.com) only when ready to process real shipments.
- Always handle 404 responses gracefully for tracking queries β not-found does not necessarily mean an invalid number, just that the shipment is not yet in the system.
- Deploy with Autoscale for customer-facing tracking features; use Reserved VM if your integration processes continuous inbound webhooks from DHL eCommerce.
- Log raw API responses during initial integration to understand the exact response structure before building parsing logic β DHL responses can vary between API versions.
Alternatives
FedEx is the stronger choice for US domestic shipping with same-day and overnight options, while DHL leads for international delivery coverage across 220+ countries.
WooCommerce includes built-in shipping plugins including DHL integration, making it a better choice if you want a full store platform rather than building a custom shipping API integration.
eBay includes built-in shipping label generation for sellers, making it the simpler choice if you are shipping exclusively from eBay orders rather than a custom platform.
Frequently asked questions
How do I store my DHL API key in Replit?
Click the lock icon π in the Replit left sidebar to open Secrets. Add DHL_API_KEY with your API key value from the DHL developer portal. Access it in Python with os.environ['DHL_API_KEY'] and in Node.js with process.env.DHL_API_KEY. Never paste the key directly into your code files.
Does the DHL Tracking API require a DHL business account?
No. The DHL Shipment Tracking API is available on a free plan at developer.dhl.com and does not require a DHL business shipping account. You can track any DHL shipment worldwide using just the API key. Creating shipments and generating labels with the DHL Express API does require an active DHL business account with an account number.
How do I track a DHL shipment from Replit?
Store your DHL_API_KEY in Replit Secrets, then make a GET request to https://api-eu.dhl.com/track/shipments?trackingNumber=YOUR_NUMBER with the DHL-API-Key header. The response returns the shipment status, all tracking events with timestamps and locations, and the estimated delivery date. Use the Python requests library or Node.js axios for the HTTP call.
Can I use DHL to create shipping labels from Replit?
Yes, through the DHL Express MyDHL API, which supports creating shipments, generating labels, scheduling pickups, and getting rates. This API requires a DHL Express business account and uses Basic Authentication with your DHL Express username and password β separate from the API key used for tracking. Subscribe to the 'DHL Express β MyDHL API' in the developer portal.
Why does DHL tracking return empty events for a new shipment?
New DHL shipments may take 2-4 hours after label creation before they appear in the Tracking API. The status will show as 'pre-transit' or similar until the first scan occurs at a DHL facility. This is normal behavior β implement retry logic with exponential backoff or check again after a few hours.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation