Getting started
The Drelife customer API is the API behind the return portals of the shops that use Drelife. An integration (a chat, a helpdesk, a mobile app) uses it to do what a shopper does on the portal: check what an order can return or exchange, list the shipping options, create the return or the exchange and follow it until it is refunded.
This guide walks through that flow end to end. The API reference documents every endpoint, field and error.
Environments
| Environment | Base URL | Purpose |
|---|---|---|
| Production | https://customer.services.drelife.com | Real shops and real orders |
| Demo | https://customer.services.demo.drelife.com | Sandbox where the integration is tested before going live, with a demo shop and orders provided by Drelife or by the merchant |
Every request and response is JSON (Content-Type: application/json). Dates are ISO 8601 in UTC. Amounts are decimal numbers in the currency of the order.
The flow in one look
- Authenticate: get your partner API key from the merchant, then open a session for a shopper with the email and the number of an order.
- Read the order: every line item says whether it can be returned or exchanged, and which reasons apply.
- Read the policy of the shop: windows, refund methods, terms.
- List the shipping methods and their price for the items being returned.
- Create the return or the exchange, and hand the shopper the payment link when the exchange leaves an amount to pay.
- Follow it: label, QR code, tracking and refund status, by polling or through webhooks.
The other Drelife products have their own pages: Second life (Circular), where the shopper offers products back to the shop, and Repairs. Attachments explains how pictures and videos are uploaded in every flow, and Pre-validation the shops that review a request before accepting it.
Authentication
Two credentials are involved, and both travel on every request after the login.
The partner API key
The merchant creates an API key for your integration from their Drelife dashboard (or asks Drelife to do it) and hands it to you; the dashboard asks which API a key is for, and yours must be created for the customer API. It looks like drk_ followed by 40 letters and digits, it belongs to one shop (marketplace), and it can be revoked at any time by the merchant. A key created for the merchant API is refused here.
Send it in the X-Api-Key header of every request:
X-Api-Key: drk_4Fh9Kz2QpL8mN3vB6xC1dE5fG7hJ9kM2nP4qR6sTWith the key:
- the login below works from a server: without it, the API only accepts logins sent by a browser from the Drelife portals of the shop (
400 Domain is not allowedfrom any other site), and answers401 ApiKeyRequiredto a call with no browser origin at all; - your requests get their own rate limit (600 per minute per key by default) instead of the per-IP limit every visitor shares;
- you can only open sessions for orders of the shop the key belongs to (or of its child shops).
Keep the key secret. If it leaks, ask the merchant to revoke it and issue a new one: the sessions opened with the revoked key stop working within a minute.
The session token
A session is always about one shopper and one order: every later call reads the order of the token, so a shopper with two orders needs two logins. Open it with the email of the customer of the order in Shopify and the order name, exactly as the shopper would do on the portal:
POST /login
Content-Type: application/json
X-Api-Key: drk_4Fh9Kz2QpL8mN3vB6xC1dE5fG7hJ9kM2nP4qR6sT
{
"email": "[email protected]",
"orderName": "#1001",
"mode": "Returns"
}{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": "2026-09-16T11:12:00.000Z"
}orderNameaccepts the order name as Shopify shows it, with or without the#(#1001,1001); when the shop uses a prefix with a dash (SHOP-1001), the part after the dash is compared with the order number.emailis compared, lower-cased, with the email of the customer of the order; a different email of the same person does not log in.modeisReturnsfor returns and exchanges.Circular(second-hand sales) andRepairare other Drelife products with their own portals; they are not covered by this guide.- The token expires at
expiresIn(one hour by default). Open a new session when it does: there is no refresh call. - The login answers
401without further detail when the order does not exist in the shop, the email does not match, the shop is inactive, returns are disabled for it or the shopper is excluded by the access lists of the shop, on purpose: an integration should not reveal which one failed. The only detailed401messages are about the key:InvalidApiKey,ApiKeyMarketplaceMismatchandApiKeyRequired(no key and no browserOrigin). - Logins are limited to twenty per minute per IP and email, with or without the key; the key adds its own budget of six hundred requests per minute for everything else.
Send the token as a Bearer token, together with the key, on every other request:
GET /orders
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
X-Api-Key: drk_4Fh9Kz2QpL8mN3vB6xC1dE5fG7hJ9kM2nP4qR6sTLogin errors:
| HTTP | errorCode | Meaning |
|---|---|---|
| 401 | Unauthorized | No order with that number for that email in the shop, or returns are disabled for the shop |
| 401 | InvalidApiKey | The key is unknown, has been revoked or was created for another API |
| 401 | ApiKeyMarketplaceMismatch | Defensive check: the order found is outside the scope of the key. Orders of other shops normally end in Unauthorized, since the lookup is already limited to the shop of the key |
| 400 | ValidationFailed | A field is missing or malformed; message lists the fields |
| 429 | TooManyRequests | Too many logins for that email or too many attempts with unknown keys |
| 503 | ServiceUnavailable | The API is under maintenance |
Which identifiers you need
The API is built around the identifiers of the shop platform, so an integration that knows the Shopify order can work without any lookup table:
| Identifier | Comes from | Used in |
|---|---|---|
Order name (with or without #) and customer email | Shopify order | POST /login |
| Line item id | Shopify order (items[].id of GET /orders) | items[].id of the creation, /products/{id}/options, /products/{id}/search |
| Fulfillment id | The Shopify fulfillment id, or items[].fulfillmentId of GET /orders (a Drelife id) | items[].fulfillmentId of the creation: both values are accepted |
| Product id and variant id | Shopify catalog (/products/{id}/options, /search) | change.productId, change.variantId of an exchange |
| Reason id | items[].reasons[].id of GET /orders | reasonId |
Shipping method (id and shippingMethodId) | POST /carriers/methods | methodId, shippingMethodId |
| Uploaded file id | POST /returns/confirm-upload | customerImageNames |
| Return id | id of the creation response | Every /returns/{id} call |
Languages
Endpoints that return texts shown to the shopper accept a lang query parameter with an ISO 639-1 code (en, es, fr, de, it, pt, ca). The detail of a return falls back to the language it was created in, then to the language of the shop, then to English. Some fields are maps of translations ({ "en": "...", "es": "..." }), such as product names, reasons and instructions: pick the language yourself from the map.
Errors
Every error has the same body:
{
"statusCode": 400,
"errorCode": "OutOfDate",
"message": "OutOfDate",
"path": "/returns/create"
}Handle errorCode, never message: the code is stable and documented in the API reference, the message is for humans and may change. The Follow a return page lists the codes you will meet when creating returns and what to do with each one.
Updated 24 days ago
