Returns API Edit the file on GitHub
Returns API allows Skroutz Merchants to retrieve and manage their returns.
Returns API is currently under development.
Table of Contents
Setup
Obtaining an API token
In order to be able to use the API, you need to generate an API token from within Smart Cart settings page in merchant's panel (Merchants > Services > Skroutz Marketplace).
There can only be one active API key per shop at a certain time. Creating a new API key will expire any previous one.
The same API token used for the Orders API is used here.
Authorization
Pass in a valid API token in the Authorization header, prefixed with Bearer
as in the following curl example.
A specific Accept header is also required.
curl -X GET https://api.skroutz.gr/merchants/ecommerce/returns/R-111111-1111111 \ -H 'Accept: application/vnd.skroutz+json; version=3.0' \ -H 'Authorization: Bearer your_access_token_here'
Endpoints
Retrieve a single return
Fetch the details of a single return, identified by its return_code.
GET /merchants/ecommerce/returns/:return_code
Example
curl -X GET https://api.skroutz.gr/merchants/ecommerce/returns/R-111111-1111111 \ -H 'Accept: application/vnd.skroutz+json; version=3.0' \ -H 'Authorization: Bearer your_access_token_here'
Response
{
"return": {
"return_code": "R-111111-1111111",
"state": "returning",
"order_code": "DEMO-OPEN",
"created_at": "2026-01-01T10:00:00Z",
"courier_tracking_ids": ["DEMO-RET-TRACK-1", "DEMO-RET-TRACK-2"],
"courier": "ACS",
"returning_address": {
"street_name": "Demo Street",
"street_number": "1",
"zip": "11111",
"city": "Demo City",
"region": "Demo Region",
"country_code": "GR"
},
"return_line_items": [
{
"id": "DEMO-ITEM-1",
"ean": "1234567890123",
"product_name": "Demo Product",
"returning_quantity": 1,
"return_reason": "damaged_product",
"user_comment": "This is a demo comment explaining the return.",
"user_photos": [
"https://a.scdn.gr/demo/return_photo_1.jpg"
]
}
]
}
}Handle a return waiting for review
Some returns wait for the merchant's review before Skroutz schedules them: a faulty product, a
missing part, or a withdrawal or wrong size outside the return policy. Such a return is in state
pending_merchant_review and carries a review with its deadline and the
handle_options it accepts.
Send one of the handle_options as option, with the params it takes. The response is the
updated return.
POST /merchants/ecommerce/returns/:return_code/handle
| Option | Params |
|---|---|
approve |
None |
A rejection reason, e.g. not_faulty |
comment, required when the option's comment_required is true, up to 1000 characters. proposed_part_url, optional and only when the option's supports_proposed_part_url is true: a link on Skroutz to the part, e.g. when it is sold separately |
send_missing_part |
See Send the missing part |
Every option resolves the review, so the return leaves pending_merchant_review (e.g. to rejected
after a rejection) and Skroutz sends a return updated webhook.
Example: approve
curl -X POST https://api.skroutz.gr/merchants/ecommerce/returns/R-111111-1111111/handle \
-H 'Accept: application/vnd.skroutz+json; version=3.0' \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer your_access_token_here' \
-d '{ "option": "approve" }'
Example: reject
curl -X POST https://api.skroutz.gr/merchants/ecommerce/returns/R-111111-1111111/handle \
-H 'Accept: application/vnd.skroutz+json; version=3.0' \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer your_access_token_here' \
-d '{ "option": "not_faulty", "comment": "The product works according to its specifications." }'
POST https://api.skroutz.gr/merchants/ecommerce/returns/DEMO-RETURN-REVIEW/handle
View Response Params{
"option": "not_faulty",
"comment": "The product works according to its specifications."
}Status: 200
{
"return": {
"return_code": "DEMO-RETURN-REVIEW",
"state": "pending_merchant_review",
"order_code": "DEMO-OPEN",
"created_at": "2026-01-01T10:00:00Z",
"courier_tracking_ids": [
"DEMO-RET-TRACK-1",
"DEMO-RET-TRACK-2"
],
"courier": "ACS",
"returning_address": {
"street_name": "Demo Shop",
"street_number": "7",
"zip": "18531",
"city": "Piraeus",
"region": "Attica",
"country_code": "GR"
},
"return_line_items": [
{
"id": "demo-rli-1",
"ean": "1234567890123",
"product_name": "Demo return item",
"returning_quantity": 1,
"return_reason": "faulty",
"user_comment": "Demo customer comment about the return",
"user_photos": [
"https://demo.scdn.gr/ds/ecommerce/return_request_line_item_images/demo-img-1.jpeg",
"https://demo.scdn.gr/ds/ecommerce/return_request_line_item_images/demo-img-2.jpeg"
]
}
],
"review": {
"review_type": "faulty",
"expires_at": "2026-01-01T21:00:00+02:00",
"holiday_auto_approval": false,
"customer_conversation_open": false
},
"handle_options": [
{
"option": "approve"
},
{
"option": "contact_manufacturer",
"comment_required": true
},
{
"option": "usability_suggestions",
"comment_required": true
},
{
"option": "not_faulty",
"comment_required": true
},
{
"option": "resolved_via_customer_communication",
"comment_required": false
}
]
}
}Send the missing part
For a missing_part review, the merchant can send the missing part to the customer instead of
receiving the product back. Skroutz creates an additional delivery of the part, at the shop's
cost, and the return moves to resolved_without_return: the product is not returned.
Pick the values from the option's delivery, as when
accepting an order. All params are required.
| Param | Type | Description |
|---|---|---|
pickup_location |
String | The id of one of the delivery.pickup_location |
cargo |
Boolean | true to book the cargo carrier, using the location's cargo_pickup_window. false otherwise, using its pickup_window |
pickup_window |
String | The id of one of the chosen list's windows. The window books its own courier |
weight |
Integer | Kilos, within delivery.weight |
number_of_parcels |
Integer | One of delivery.number_of_parcels |
items_description |
String | What is being sent, up to 250 characters |
delivery_reason |
String | Why it is being sent, up to 250 characters |
A window that is no longer available is rejected, never replaced with another one. Fetch the return again for the current windows: the windows in a webhook payload are those available when it was sent.
curl -X POST https://api.skroutz.gr/merchants/ecommerce/returns/R-111111-1111111/handle \
-H 'Accept: application/vnd.skroutz+json; version=3.0' \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer your_access_token_here' \
-d '{
"option": "send_missing_part",
"pickup_location": "YlpD0KROym",
"cargo": false,
"pickup_window": "20261029T1000-20261029T1400",
"weight": 2,
"number_of_parcels": 1,
"items_description": "Mounting accessories",
"delivery_reason": "Sending the missing part"
}'
Handle errors
| Status | Code | When |
|---|---|---|
400 |
ParameterMissing |
option is missing |
404 |
return_error |
The return does not exist or does not belong to your shop |
422 |
review_state |
The return is not waiting for your review: it was already handled, its deadline passed, or it never needed one |
422 |
option |
The return does not offer this option, e.g. contact_customer |
422 |
The param's name, e.g. comment, pickup_window |
The param is missing or invalid |
{
"errors": [
{
"code": "pickup_window",
"messages": [
"is not an available pickup window"
]
}
]
}Watch a customer video
The url and thumbnail_url of a line item's user_videos point to the
following endpoints. Each takes your API token and redirects to the video's player page or its
thumbnail image, on a link signed for a short time. Request them when you need to show the video,
rather than storing the link they redirect to.
GET /merchants/ecommerce/returns/:return_code/videos/:id GET /merchants/ecommerce/returns/:return_code/videos/:id/thumbnail
| Status | When |
|---|---|
302 |
Redirects to the player page or the thumbnail |
404 |
The video does not exist, is not yet uploaded, or does not belong to your return |
429 |
More than 60 video requests in a minute |
503 |
The video could not be signed. Try again later |
Error handling
In case of errors, the response will have a representative HTTP status code
in the 4xx range. The body would contain an array of errors.
For example, if the requested return code does not exist (or does not belong to your shop),
you will get a 404 HTTP status code (Not Found):
{
"errors": [
{
"code": "not_found",
"messages": [
"Return not found"
]
}
]
}Test requests (sandbox)
The following demo return code is available on production for testing reasons.
It is safe to issue requests for the following demo return code multiple times for testing, since it does not reference any real data.
DEMO-RETURN
A demo return with a single returning line item, courier tracking ids and a returning address.
GET /merchants/ecommerce/returns/DEMO-RETURN
GET https://api.skroutz.gr/merchants/ecommerce/returns/DEMO-RETURN
View ResponseStatus: 200
{
"return": {
"return_code": "DEMO-RETURN",
"state": "returning",
"order_code": "DEMO-OPEN",
"created_at": "2026-01-01T10:00:00Z",
"courier_tracking_ids": [
"DEMO-RET-TRACK-1",
"DEMO-RET-TRACK-2"
],
"courier": "ACS",
"returning_address": {
"street_name": "Demo Shop",
"street_number": "7",
"zip": "18531",
"city": "Piraeus",
"region": "Attica",
"country_code": "GR"
},
"return_line_items": [
{
"id": "demo-rli-1",
"ean": "1234567890123",
"product_name": "Demo return item",
"returning_quantity": 1,
"return_reason": "damaged_product",
"user_comment": "Demo customer comment about the return",
"user_photos": [
"https://demo.scdn.gr/ds/ecommerce/return_request_line_item_images/demo-img-1.jpeg",
"https://demo.scdn.gr/ds/ecommerce/return_request_line_item_images/demo-img-2.jpeg"
]
}
]
}
}DEMO-RETURN-REVIEW
A demo return of a faulty product, waiting for the merchant's review, with its review and
handle_options.
GET /merchants/ecommerce/returns/DEMO-RETURN-REVIEW POST /merchants/ecommerce/returns/DEMO-RETURN-REVIEW/handle
Handling it with any of its handle_options answers with the same return, unchanged.
GET https://api.skroutz.gr/merchants/ecommerce/returns/DEMO-RETURN-REVIEW
View ResponseStatus: 200
{
"return": {
"return_code": "DEMO-RETURN-REVIEW",
"state": "pending_merchant_review",
"order_code": "DEMO-OPEN",
"created_at": "2026-01-01T10:00:00Z",
"courier_tracking_ids": [
"DEMO-RET-TRACK-1",
"DEMO-RET-TRACK-2"
],
"courier": "ACS",
"returning_address": {
"street_name": "Demo Shop",
"street_number": "7",
"zip": "18531",
"city": "Piraeus",
"region": "Attica",
"country_code": "GR"
},
"return_line_items": [
{
"id": "demo-rli-1",
"ean": "1234567890123",
"product_name": "Demo return item",
"returning_quantity": 1,
"return_reason": "faulty",
"user_comment": "Demo customer comment about the return",
"user_photos": [
"https://demo.scdn.gr/ds/ecommerce/return_request_line_item_images/demo-img-1.jpeg",
"https://demo.scdn.gr/ds/ecommerce/return_request_line_item_images/demo-img-2.jpeg"
]
}
],
"review": {
"review_type": "faulty",
"expires_at": "2026-01-01T21:00:00+02:00",
"holiday_auto_approval": false,
"customer_conversation_open": false
},
"handle_options": [
{
"option": "approve"
},
{
"option": "contact_manufacturer",
"comment_required": true
},
{
"option": "usability_suggestions",
"comment_required": true
},
{
"option": "not_faulty",
"comment_required": true
},
{
"option": "resolved_via_customer_communication",
"comment_required": false
}
]
}
}Return object attributes appendix
Return object
| Name | Type | Values | Description |
|---|---|---|---|
return_code |
String | Return Code | |
state |
String | pending_merchant_review, returning, pending_physical_review, pending_service_inspection, returned, rejected, expired, cancelled, resolved_without_return |
Current lifecycle state of the return. One of the return states. |
order_code |
String | The code of the order this return belongs to | |
created_at |
Date String in formatYYYY-MM-DDTHH:MM:SSZ |
Return creation date | |
courier_tracking_ids |
Array of Strings | (Optional) | Deduplicated tracking IDs across current shipments |
courier |
String | (Optional) | Human-readable name of the courier (e.g. ACS) |
returning_address |
Object | (Optional) | Returning address — the address the merchant should receive the return at |
return_line_items |
Array | Return line items — the products being returned | |
review |
Object | (Optional) | Review — the review waiting for the merchant |
handle_options |
Array | (Optional) | Handle options — the ways the merchant can handle the review |
courier_tracking_ids, courier and returning_address are omitted entirely (not sent as null)
when not applicable — e.g. virtual returns with no shipment.
review and handle_options are present only while the return is in state pending_merchant_review
and waits for the merchant's review. They are omitted once the review is handled or its deadline passes.
Return states
The state field is one of the following string values:
| State | Description |
|---|---|
pending_merchant_review |
The customer submitted a return request and the merchant needs to review it. |
returning |
The package is in transit back to the merchant. |
pending_physical_review |
The package arrived at the merchant and must perform physical inspection. |
returned |
The package was delivered back to the merchant. |
rejected |
The return was rejected. |
expired |
The merchant never responded to the return request within the deadline. |
cancelled |
The return was cancelled. |
pending_service_inspection |
A technician or an authorised service is to inspect the product. |
resolved_without_return |
The merchant sent the customer the missing part, so the product is not returned. |
Returning address
Present only when the return has a shipment.
| Name | Type | Description |
|---|---|---|
returning_address.street_name |
String | Street/road name |
returning_address.street_number |
String | Building number |
returning_address.zip |
String | Postal code |
returning_address.city |
String | City |
returning_address.region |
String | Region/state |
returning_address.country_code |
String | Country code (e.g. GR) |
Return line items
Each element of the return_line_items array represents one product line being returned.
| Name | Type | Values | Description |
|---|---|---|---|
id |
String | ID of the order line item being returned | |
ean |
String | EAN code of the product being returned | |
product_name |
String | Product display name | |
returning_quantity |
Integer | How many units of this product the customer is returning | |
return_reason |
String | faulty, wrong_product, withdrawal, damaged_product, expired_product, authenticity_doubt, delivery_issues, other (Optional) |
Reason the customer selected |
sub_reason |
String | different_product, missing_line_item, missing_part, wrong_delivered_size, content_mistake, damaged_courier_fault, damaged_merchant_fault (Optional) |
A more specific reason, e.g. missing_part for a wrong_product return |
requested_compensation |
String | refund, replace, repair, gift_card, none, consolation_coupon (Optional) |
What the customer asked for |
user_comment |
String | (Optional) | Free-text comment left by the customer explaining the return |
user_photos |
Array of Strings | (Optional) | Full URLs of photos uploaded by the customer as evidence |
user_videos |
Array | (Optional) | Videos uploaded by the customer as evidence |
User videos
| Name | Type | Description |
|---|---|---|
id |
String | The video ID |
url |
String | Watch the video (requires your API token) |
thumbnail_url |
String | The video's thumbnail (requires your API token) |
Review
Present while the return waits for the merchant's review.
| Name | Type | Values | Description |
|---|---|---|---|
review_type |
String | faulty, missing_part, out_of_policy_withdrawal, unopened_category_withdrawal, out_of_policy_wrong_size, unopened_category_wrong_size |
Why the return needs the merchant's review |
expires_at |
Date String in ISO 8601 format | Until when the merchant can handle the review. Afterwards Skroutz handles it, and the merchant may lose their right to compensation | |
holiday_auto_approval |
Boolean | Whether the withdrawal is out of policy only because of the holiday period, so Skroutz approves it when the deadline passes | |
customer_conversation_open |
Boolean | Whether a conversation with the customer about the product is open in the merchant panel |
Handle options
The options to send to handle the return:
approve, then send_missing_part, then the rejection reasons. Each option resolves the review. Contacting the customer,
which only extends the deadline, is available in the merchant panel only.
| Name | Type | Description |
|---|---|---|
option |
String | The value to send as option: approve, send_missing_part or a rejection reason |
comment_required |
Boolean | Rejection reasons only: whether comment is required |
supports_proposed_part_url |
Boolean | Rejection reasons only, present only when true: whether proposed_part_url can be sent |
delivery |
Object | send_missing_part only: the delivery options |
Rejection reasons
| Review type | Rejection reasons |
|---|---|
faulty |
contact_manufacturer (not offered while the product is within the dead on arrival period), usability_suggestions, not_faulty, resolved_via_customer_communication |
missing_part |
part_not_included, not_missing_part, resolved_via_customer_communication |
out_of_policy_withdrawal, unopened_category_withdrawal, out_of_policy_wrong_size, unopened_category_wrong_size |
out_of_policy_withdrawal |
| Option | Meaning |
|---|---|
approve |
The merchant accepts the return |
send_missing_part |
The merchant sends the missing part to the customer with an additional delivery, at the shop's cost, and the product is not returned. Offered for missing_part reviews when the order can get an additional delivery, but not for a product the merchant delivered with their own cargo carrier |
contact_manufacturer |
The customer needs to contact the manufacturer or the authorised service provider |
usability_suggestions |
The product has been used in a way that affects how it works |
not_faulty |
The product is not faulty: it works according to its specifications |
part_not_included |
The product was delivered complete as described: no part is missing. The merchant can point the customer to the part on Skroutz, e.g. when it is sold separately, with proposed_part_url |
not_missing_part |
The product page on Skroutz has wrong content that needs a correction |
resolved_via_customer_communication |
The merchant already contacted the customer and the issue has been resolved |
out_of_policy_withdrawal |
The withdrawal is outside the return policy |
Delivery options
The choices for the missing part's delivery, named after the params of
send_missing_part, as in an order's
accept options.
| Name | Type | Example | Description |
|---|---|---|---|
delivery.pickup_location |
Array | Pickup locations, the order's own first | |
delivery.weight |
Object | { "min": 1, "max": 50 } |
Valid weight range, in whole kilos |
delivery.number_of_parcels |
Array | [1, 2, 3] |
Valid values for number_of_parcels |
Delivery option: Pickup location
| Name | Type | Description |
|---|---|---|
pickup_location.id |
String | The location ID to send as pickup_location. The same IDs as in an order's accept options |
pickup_location.label |
String | A human readable address |
pickup_location.pickup_window |
Array | Pickup windows to send with cargo: false |
pickup_location.cargo_pickup_window |
Array | Pickup windows to send with cargo: true. Present only for an order shipped as a cargo item |
Delivery option: Pickup window
| Name | Type | Example | Description |
|---|---|---|---|
pickup_window.id |
String | "20261029T1000-20261029T1400" |
The pickup window ID to send as pickup_window |
pickup_window.label |
String | "10:00 - 14:00, Πέμ 29/10/26" |
A human readable time range |
As in an order's accept options, the id identifies the window by its start and end time
(YYYYMMDDTHHMM-YYYYMMDDTHHMM, local Greek time). Each window books its own courier, so there is
no courier to choose. The same id can appear in both lists of a location, so cargo tells which
one you picked.