Skip to content
Farhat Ullah.
Writing

Why your DHL plugin fails in the Czech Republic

Off-the-shelf DHL shipping connectors are built against DHL's general API. DHL's Czech Republic operation runs a local variant that most connectors don't cover — and the failure doesn't show up until a shipment is already at the border.

Published
02 Jul 2026
Updated
04 Aug 2026
Reading time
4 min
Tags
Odoo · e-commerce · logistics · Czech Republic · integration

A recurring conversation I have with clients running e-commerce or ERP-integrated shipping in Central Europe goes roughly like this: "We already have a DHL plugin, why do we need custom work for the Czech market?" The honest answer is that the plugin they have was almost certainly built and tested against DHL's general international API, and DHL's Czech Republic operation doesn't run purely on that API. It runs a local variant with its own label formats, its own service codes, and its own quirks — and a generic connector that never accounted for that variant will look like it works right up until a shipment hits a step the connector didn't anticipate.

Why "DHL" isn't one integration

DHL is a federation of largely independent country operations sharing a brand, not a single API surface. DHL Express International has its own API. DHL eCommerce (used heavily for smaller parcel and domestic-style shipping) has a different one. And several national operations — Czech Republic among them — layer local requirements on top: specific label formats for domestic depots, service codes that map to local delivery options that don't exist in DHL's international product catalog, address validation rules tuned to Czech postal conventions, and customs/documentation handling that differs depending on whether the shipment is domestic, intra-EU, or genuinely international.

A shipping connector built to the general DHL API — which is what most off-the-shelf Odoo, WooCommerce, and Shopify DHL plugins are — handles the common case well: create a shipment, get a label, get a tracking number, done. It falls over on the local case, because the local case expects a different request shape, a different set of service codes, or a document the general API doesn't ask for at all.

What the failure actually looks like

The failure mode is what makes this expensive rather than merely annoying: it's not a build-time error. The plugin installs cleanly, the test shipment in the sandbox environment often works, and the first several real shipments might go out fine if they happen to match the paths the connector was built for. Then a shipment hits a case the connector doesn't handle — a domestic Czech delivery routed through a depot that expects the local label format, or a customs document field the general API doesn't populate — and it doesn't fail with a clear error back in the ERP. It fails at DHL's depot or at the border, as a shipment that's stuck, misrouted, or held for a document nobody was told to attach.

By the time that surfaces, the order has already shipped from the merchant's side, the customer is waiting, and the person debugging it is doing so from a support ticket and a tracking number that stopped updating — not from a stack trace. That's a categorically worse debugging position than a failed API call at checkout, and it's the direct cost of a connector that was never built against the variant actually being used.

The research-before-build principle

This is really a specific case of a general rule I apply to any third-party integration: before writing or buying a connector, confirm which actual API variant the counterparty uses for the specific country, service tier, and shipment type in question — don't assume "DHL" or "the standard plugin" is a sufficient specification. That means pulling the actual API documentation for the country operation involved, checking service code tables against what the business actually needs to offer (domestic next-day, EU standard, international express are frequently different code sets), and testing against realistic address and customs scenarios, not just the sandbox happy path the plugin's own documentation demonstrates.

For DHL Czech Republic specifically, that research step means verifying up front whether the plugin under consideration was built and tested against the Czech local API or only against DHL's general international one, and if it's the latter, treating that as a scoping gap to close before launch rather than a risk to discover in production. It's a half-day of verification against months of a plugin quietly mishandling a subset of shipments.

Why the cheap answer is the expensive one

The economics here are what make this worth writing about. A generic plugin is cheap and fast to install, and for a business that ships almost entirely within the general API's coverage, it's the right call — there's no reason to over-engineer an integration a business doesn't need. The trap is installing the generic plugin without checking whether the business's actual shipping mix includes the local-variant cases, and finding out only when a shipment fails somewhere the merchant can't easily see or fix.

The fix isn't necessarily "always build custom." It's "know which variant you're actually shipping against before you commit to a connector," because the cost of that verification is trivial compared to the cost of a shipment stuck at a Czech depot with a customer asking where their order is and a support team with no visibility into why. Research before build isn't a slogan — for a shipping integration, it's the difference between a connector that quietly works and one that quietly fails at the one point where quiet failure is most expensive.

Have a system that needs to work in production?

Tell me what's breaking — or what you're building.

Chat on WhatsApp