DPD API vs GLS API for EU Return Labels

DPD and GLS return-label APIs compared: endpoint design, pickup vs shop-return, sandbox access, and webhooks, with a verdict for EU reverse logistics.

Share
DPD API vs GLS API for EU Return Labels

DPD API vs GLS API for EU Return Labels

Return labels break more direct-carrier integrations than outbound labels ever do. The outbound path is well-trodden on every carrier's docs site. Return labels — generated at order time, on-demand post-delivery, or triggered by a customer self-service portal — expose the seams in each carrier's API design. This post tests only the native REST return-label mechanics of DPD's and GLS's own APIs, not an aggregator or multi-carrier platform sitting in front of them. If you're building an in-house reverse-logistics flow for an EU shipper and need to decide which carrier's direct API is less painful to integrate against, this is the comparison you want.

Criteria: what actually matters for a return-label integration

Six things determine whether a return-label integration takes an afternoon or a sprint. We picked these because they map directly onto engineering decisions you have to make before writing a single line of integration code.

  • Return label trigger mechanism — is it a flag, a suffix, a separate service block, or a dedicated endpoint? This determines how much you have to reshape your existing outbound-shipment payload builder.
  • Return service types supported — pickup-at-customer-address vs. drop-off at a shop/locker. Most EU returns programs need both, so partial support means a second integration later.
  • Dedicated endpoint vs. parameter flag — a standalone endpoint is easier to test and log in isolation; a flag buried in a shared endpoint means your monitoring has to parse response fields to tell outbound and return traffic apart.
  • Sandbox/test environment availability — self-service registration vs. contracted access changes your time-to-first-return-label from hours to weeks.
  • Webhook/status-push support for the return leg — whether you get pushed status on the return parcel or have to poll tracking for it.
  • Documentation consistency across countries — a shipper serving five EU markets may need five different credential sets and five different field names for what is conceptually the same return.

DPD vs GLS: the comparison table

Criteria DPD (direct REST APIs) GLS (ShipIT / Shipping API)
Return trigger mechanism Suffix on an existing field: -RETURN appended to parcel_type in the Baltics API, or a dedicated RET service code in the newer Swiss Label Print API A named service block (PickAndReturn, ShopReturn) attached to the shipment object, or a standalone CreateShopReturn-style call for post-delivery returns
Pickup-return support Yes, via DPD Pickup return service; label used to send the shipment back to sender, availability limited by country Yes, Pick&ReturnService picks up at the customer's address, scheduled for the next working day, with a 60-day return window from the outbound date
Shop/drop-off return support Yes in NL (service code 332, DPD Shop Return) and Baltics (PS-RETURN parcel type); not uniformly named across stacks Yes, ShopReturnService covers drop-off at any GLS ParcelShop in the network
Dedicated endpoint vs. flag Flag/parameter pattern across all four DPD stacks tested (Baltics, NL, CH, Cloud Service) — no standalone return endpoint Return service is a block inside the same createParcels call, but GLS's address-swap logic (below) functions like a dedicated mode within one endpoint
Address handling Manual: DPD NL explicitly notes you don't have to reverse sender and receiver sections for a return parcel — the carrier does not auto-swap Automatic: consignee and shipper data sections are automatically switched on the return label, using the consignee address as the pickup address
Sandbox access Self-service: register a free developer account and sandbox credentials match what you see after registering with DPD Entwickler Contracted: centrally hosted endpoints can be obtained from your primary GLS contact and are given with your Service credentials
Webhook support for return leg Not published as a dedicated return-leg push; status codes include a returned state polled via the standard parcel-status method Yes, in the e-commerce API: a hash is calculated by concatenating the status id, tracking code and callback URL, then HMAC SHA256 signed and base64 encoded
Documentation consistency across countries Fragmented — Baltics, NL, CH and Cloud Service each use different field names and payload shapes for the same return concept More consistent — ShipIT's REST API is one group-wide spec, though NL runs a separate Azure-hosted portal with its own field names
Published rate limits Not published Not published
Published SLA for return-label generation Not published Not published

DPD deep dive: one brand, several REST dialects

DPD's biggest problem for a European shipper isn't any single endpoint, it's that "DPD API" means at least four different things depending on the market. In the Baltics API, return labels are created during shipment creation by adding -RETURN to already existing parcel_type parameter value, with examples like D-RETURN, D-B2C-RETURN, and PS-RETURN. There's a standalone variant too: RET cannot be used without RETURN, it is empty standalone service, created solely so customer can print return labels only, and it's currently available only in Lithuania and Latvia.

DPD's newer Swiss Label Print API takes a cleaner approach: it defines a discrete RET service code for "Return goods" sitting alongside the regular B2B/B2C/HOME codes, rather than mutating an existing field. This is the most modern-feeling of DPD's REST surfaces, which makes sense given it's the newest build.

DPD NL runs yet another dialect. Its Shipment Service documents a boolean returns field on the parcel block, and explicitly states that the return parcel must be the only parcel or be next in order to the corresponding outbound parcel, and critically, this means that you don't have to reverse the sender and receiver sections — the opposite default from GLS's automatic address swap. DPD NL's Shop Return (service code 332) is handled as a separate product value, and format quirks bite here too: for direct printing the format has to be set to A6, A7 only for return labels.

The legacy Cloud Service, which still underpins a lot of DPD DE integrations, uses a SOAP/REST hybrid with a staging host at cloud-stage.dpd.com. Sandbox onboarding is genuinely low-friction here: test webservice credentials correspond to the sandbox credentials visible after registering with DPD Entwickler under "Benutzerdaten ändern." You register, you get a partner/user token pair, you're testing within the hour.

GLS deep dive: dedicated return services and HMAC webhooks

GLS's ShipIT REST API treats return services as first-class service blocks rather than parameter mutations. Two services matter for most EU reverse-logistics flows. Pick&ReturnService picks up the parcel at the customer's address, scheduled for the next working day, with a 60-day return window from the outbound date. ShopReturnService covers drop-off at any GLS ParcelShop in the network. Both are attached to the shipment payload as named service objects, for example "Service":[{"PickAndReturn":{"ServiceName":"service_pickandreturn","PickupDate":"2020-11-11"}}], pulled straight from GLS's own request samples.

The most useful design decision in GLS's whole return story is the automatic address swap. GLS's documentation is explicit: in case of shipments with return services assigned, the consignee and shipper data sections will automatically be switched on the return label, meaning the consignee address you provide becomes the pickup address on the return label, and the shipper address becomes the delivery address. You build one payload shape; GLS flips the roles server-side. This is the opposite of the DPD NL model, where you keep sender/receiver as-is and a flag tells the system what to do with them. Neither approach is objectively better, but if you're building a shared payload builder across carriers, GLS's auto-swap means fewer conditional branches in your mapping code — you don't need carrier-specific logic for "did I already flip these addresses."

On webhooks, GLS's e-commerce API (a separate surface from ShipIT, used more by shop-return flows) signs its status push requests. The mechanics: we concatenate the status id, the tracking code and the registered callback url, then select the correct secret key and use this to create a HMAC SHA256 hash, and make this base64 encoded. That's a workable, standard signing scheme — nothing exotic, and easy to verify server-side once you know the field order.

Portal fragmentation exists on GLS's side too, just less severely than DPD's. GLS Netherlands runs its own Azure API Management portal, and group-wide, the GLS ShipIT REST/SOAP web services are fully documented in public Doxygen reference pages, yet the base URL itself is handed out only with credentials by a customer's primary GLS contact. You can read every endpoint spec before you have an account; you just can't call anything until GLS issues you a Contact ID and HTTP Basic auth credentials.

Sandbox access and onboarding friction, side by side

This is where the two carriers diverge sharply in practice. DPD's Cloud Service lets you self-register at the DPD Entwickler portal and start hitting the cloud-stage.dpd.com endpoint with sandbox credentials the same day. No sales call, no contract review. GLS requires a contracted-access model: credentials for the ShipIT Service, including the sandbox host, come from your primary GLS contact, not from a public signup form.

If your team values being able to prototype against a live sandbox before signing anything, DPD's Cloud Service and Entwickler portal win outright. If you already have a GLS commercial contract in place and just need technical onboarding, the friction difference mostly disappears — it becomes an email to your account manager rather than a blocker.

Neither carrier publishes rate limits for return-label calls in the documentation we reviewed. Both cells in the table above read "Not published" for a reason: don't plan burst capacity around assumed numbers. Log your own throttling behavior in sandbox and prod before you commit to a retry/backoff design — this is the kind of gap that causes idempotency bugs later if you guess wrong.

Verdict, scoped to returns-specific integration

GLS wins for shippers who need both pickup-return and shop-return in a payload-consistent way. The automatic address swap and named service blocks mean less branching logic in your shipment builder, and the group-wide ShipIT spec is more consistent across markets than anything DPD currently offers. The tradeoff is contracted sandbox access — budget a lead time of days to weeks to get credentials rather than minutes.

DPD wins if you operate primarily in the Baltics or Switzerland, where the suffix pattern (-RETURN) or the newer RET service code is already simple, and where self-service sandbox registration through DPD Entwickler matters more to your team's workflow than long-term payload consistency. If your shipper footprint is DE/NL/CH/Baltics simultaneously, expect to maintain four slightly different DPD return-label payload shapes, which is real ongoing maintenance cost that doesn't show up until you're six months in.

For shippers running both DPD and GLS plus two or three more carriers, the calculus changes. A normalization layer — Cargoson, Sendcloud, or ShippyPro — maps each carrier's return mechanics (DPD's suffix, GLS's auto-swap) behind one schema, trading direct-API control for fewer carrier-specific edge cases in your own code. That trade only pays off once you're past two or three direct carrier integrations; below that, the direct APIs reviewed here are worth owning yourself, if only so you can see exactly where each one breaks.