NAV Navbar
shell python haskell
  • Introduction
  • Orders
  • Offers
  • Returns
  • Sandbox Testing
  • Errors
  • Transporters
  • import json
    import requests
    
    {-# LANGUAGE OverloadedStrings #-}
    
    import           Control.Lens         ((&), (.~), (^.))
    import           Data.Aeson           (object, toJSON, (.=))
    import qualified Data.ByteString      as SBS
    import qualified Data.ByteString.Lazy as LBS
    import           Data.Monoid          ((<>))
    import           Network.Wreq         (Options, Response, defaults, getWith,
                                           header, postWith, responseBody)
    
    

    Introduction

    Welcome to the Channable API v1.

    This version of the Channable API allows you to:

    Details

    Key Value
    Api version v1
    Protocol HTTPS
    Hostname api.channable.com
    Common Path /v1/companies/:company_id/projects/:project_id

    Taxonomy

    Term Description
    Platform A webshop platform, such as WooComerce, Lightspeed, etc.
    Marketplace A place where you can sell your products, such as Google, Amazon, eBay, etc. Sometimes referred to as channel.
    Order A purchase of any products made by a client.
    Offer A selling proposal made by a seller over any class of products. It includes price, stock and other seller-dependent values.

    Rate Limiting

    The Channable API has a rate limiting policy to which you must comply to.
    It is defined on a per-company basis, meaning that generating new API tokens will not circumvent our rate-limiting.

    Frequency Burst
    Max 2 requests per second Burst of 100 requests

    Note: We use the Leaky Bucket algorithm for rate-limiting.

    Getting started

    To get started you need to:

    Find your project ids

    To find the project ids you are interested in:

    1. Log in to the Channable app
    2. Select a project
    3. Open the project Settings
    4. Copy the Project id value

    Generate an Api Token for your company

    To both find your Channable company_id and to generate a new API token for your company, go to app.channable.com and sign in.

    On the main page hover your mouse over your account name and a drop down menu will show, as seen on the screenshot:

    From here you can see your company id, as well as generate your api token:

    Notes:

    How to include the token in your requests:

    # Headers method: Authorization: Bearer
    curl "api_endpoint_here"
      -H "Authorization: Bearer your_api_token"
    
    # URL method: ?access_token parameter
    curl "api_endpoint_here?access_token=your_api_token"
    
    apiToken :: ByteString
    apiToken = your_api_token
    
    reqOptions :: Options
    reqOptions = defaults & header "Authorization" .~ ["Bearer " <> apiToken]
    
    api_token = <api_token>
    headers = {'Authorization': "Bearer {}".format(api_token)}
    

    Using the API Token

    You must include your API token in every request you make to Channable.
    The token can be included either in the:

    After generating your API token you are ready to try out the endpoints and build your integration using the Channable Sandbox. More information on how to start testing using the Channable Sandbox can be found here: Testing with the Channable Sandbox.

    Orders

    Get all orders

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/orders?offset=50&limit=1' \
        -H 'authorization: Bearer api_key'
    
    getAllOrders =
       getWith reqOptions $ "https://api.channable.com/v1/companies/123/projects/456/orders?offset=50&limit1"
         where reqOptions = defaults & header "Authorization" .~ ["Bearer " <> apiToken]
    
    def get_all_orders():
      return requests.get("https://api.channable.com/v1/companies/123/projects/456/orders?offset=50&limit=1",
                          headers={'Authorization': "Bearer {}".format(api_token)},
                         ).json()
    
    

    Response

    {
      "total": 1,
      "error_count": 0,
      "orders": [
        {
          "channel_id": "123",  # The order id of the marketplace
          "channel_name": "bol",
          "created": "2017-08-02T14:31:48",
          "data": {
            "billing": {
              "address1": "Billingstraat 1",
              "address2": "Onder de brievenbus huisnummer 1 extra adres info",
              "address_supplement": "Onder de brievenbus huisnummer 1 extra adres info",
              "city": "Amsterdam",
              "company": "Bol.com",
              "country_code": "NL",
              "email": "dontemail@me.net",
              "first_name": "Jans",
              "house_number": 1,
              "house_number_ext": "",
              "last_name": "Janssen",
              "middle_name": "",
              "region": "",
              "street": "Billingstraat",
              "zip_code": "5000 ZZ"
            },
            "customer": {
              "company": "Bol.com",
              "email": "dontemail@me.net",
              "first_name": "Jans",
              "gender": "male",
              "last_name": "Janssen",
              "middle_name": "",
              "mobile": "",
              "phone": "0201234567"
            },
            "extra": {
              "comment": "Bol.com order id: 123",
              "memo": "Order from Channable \n Bol.com order id: 123\n Customer receipt: https:\/\/www.bol.com\/sdd\/orders\/downloadallpackageslips.html"
            },
            "price": {
              "commission": 1.5,
              "currency": "EUR",
              "payment_method": "bol",
              "shipping": 0,
              "subtotal": 123.45,
              "total": 123.45,
              "transaction_fee": 0
            },
            "products": [
              {
                "commission": 1.5,
                "delivery_period": "2017-08-02+02:00",
                "ean": "9789062387410",
                # The official identifier of the product, depending on the marketplace. For example GTIN, ISBN or in the case of Amazon the ASIN.
                "article_number":  "9789062387410",
                "id": "11693020",
                "price": 61.725,
                "quantity": 2,
                "reference_code": "123",
                "shipping": 0,
                "title": "Harry Potter"
              }
            ],
            "shipping": {
              "address1": "Shipmentstraat 42 bis",
              "address2": "",
              "address_supplement": "3 hoog achter extra adres info",
              "city": "Amsterdam",
              "company": "The Company",
              "country_code": "NL",
              "email": "nospam4me@myaccount.com",
              "first_name": "Jan",
              "house_number": 42,
              "house_number_ext": "bis",
              "last_name": "Janssen",
              "middle_name": "",
              "region": "",
              "street": "Shipmentstraat",
              "zip_code": "1000 AA"
            },
            "delivery_request": {
              "method": "Shipping method",
              "carrier": "Shipping carrier",
              "promise": "Shipping promise"
            }
          },
          "error": false,
          "fulfillment": {},
          "id": 299623,
          "modified": "2017-08-10T18:08:13.699449",
          "platform_id": "299623",
          "platform_name": "channable",
          "project_id": 6496,
          "status_paid": "paid",  # This is always paid, because the marketplace handles payments
          "status_shipped": "not_shipped"
        }
      ]
    }
    

    This endpoint retrieves all orders for a given project of your company, sorted from most recent to oldest. Optionally, you can pass query parameters to customize the query and response content.
    Note that the order data itself (like address information) can not be modified.

    Request

    Method GET
    Endpoint /orders
    Headers none
    Query parameters see below

    Query parameters

    Parameter Type Default Description
    offset Int 0 Defines the starting position, in which position 0 resembles the most recent order.
    limit Int 15, max = 100 The number of orders to retrieve after offset.
    search String empty Search term used to filter the orders list.
    errors Bool False Choose to only retrieve orders with errors.
    Note: true, True, and 1 evaluate to True, everything else is considered False.
    status String empty Search on shipment status, possible values: not_shipped, shipped, cancelled, waiting
    start_date* String empty Search for orders with a creation date after this date, in format YYYY-MM-DD
    end_date* String empty Search for orders with a creation date before this date, in format YYYY-MM-DD
    Timezones*

    When using the start_date and end_date parameters please keep in mind that the created date of the order has a CET timezone.

    Example

    Suppose the following scenario for a given project of yours:

    Request parameters Response
    none {"orders": [o4, o3, o2, o1], "error_count": 1, "total": 4}
    ?errors=true {"orders": [o3], "error_count": 1, "total": 4}
    ?limit=2 {"orders": [o4, o3], "error_count": 1, "total": 4}
    ?offset=1 {"orders": [o3, o2, o1], "error_count": 1, "total": 4}
    ?offset=4 {"orders": [], "error_count": 1, "total": 4}
    ?offset=1&limit=1 {"orders": [o3], "error_count": 1, "total": 4}
    ?offset=1&limit=2 {"orders": [o3, o2], "error_count": 1, "total": 4}
    ?offset=1&limit=2&errors=true {"orders": [o3], "error_count": 1, "total": 4}
    ?search=t {"orders": [o4, o1], "error_count": 1, "total": 4}
    ?search=t&errors=true {"orders": [], "error_count": 1, "total": 4}
    ?search=tE {"orders": [o3], "error_count": 1, "total": 4}
    ?search=tE&errors=true {"orders": [o3], "error_count": 1, "total": 4}
    ?offset=1&limit=2&search=t&errors=true {"orders": [], "error_count": 1, "total": 4}
    ?status=not_shipped {"orders": [o4], "error_count": 1, "total": 4}
    ?start_date=2018-01-01 {"orders": [o4, o3, o2], "error_count": 1, "total": 4}
    ?start_date=2018-01-01&end_date=2018-02-28 {"orders": [o3, o2], "error_count": 1, "total": 4}

    Response

    The response body is a JSON object containing the following fields:

    You can see at your right a real example of such return value.

    Get an order by id

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/orders/7' \
        -H 'authorization: Bearer api_key'
    
    getOrderById :: Int -> IO (Response ByteString)
    getOrderById id =
      getWith reqOptions $ "https://api.channable.com/v1/companies/123/projects/456/orders/" <> show id
        where reqOptions = defaults & header "Authorization" .~ ["Bearer " <> apiToken]
    
    
    def get_order_by_id():
      return requests.get("https://api.channable.com/v1/companies/123/projects/456/orders/7",
                          headers={'Authorization': "Bearer {}".format(api_token)},
                         ).json()
    

    Response

    {
      "order": {
        "channel_id": "123",
        "channel_name": "bol",
        "created": "2017-08-02T14:31:48",
        "data": {
          "billing": {
            "address1": "Billingstraat 1",
            "address2": "Onder de brievenbus huisnummer 1 extra adres info",
            "address_supplement": "Onder de brievenbus huisnummer 1 extra adres info",
            "city": "Amsterdam",
            "company": "Bol.com",
            "country_code": "NL",
            "email": "dontemail@me.net",
            "first_name": "Jans",
            "house_number": 1,
            "house_number_ext": "",
            "last_name": "Janssen",
            "middle_name": "",
            "region": "",
            "street": "Billingstraat",
            "zip_code": "5000 ZZ"
          },
          "customer": {
            "company": "Bol.com",
            "email": "dontemail@me.net",
            "first_name": "Jans",
            "gender": "male",
            "last_name": "Janssen",
            "middle_name": "",
            "mobile": "",
            "phone": "0201234567"
          },
          "extra": {
            "comment": "Bol.com order id: 123",
            "memo": "Order from Channable \n Bol.com order id: 123\n Customer receipt: https:\/\/www.bol.com\/sdd\/orders\/downloadallpackageslips.html"
          },
          "price": {
            "commission": 1.5,
            "currency": "EUR",
            "payment_method": "bol",
            "shipping": 0,
            "subtotal": 123.45,
            "total": 123.45,
            "transaction_fee": 0
          },
          "products": [
            {
              "commission": 1.5,
              "delivery_period": "2017-08-02+02:00",
              "ean": "9789062387410",
              "id": "11693020",
              "price": 61.725,
              "quantity": 2,
              "reference_code": "123",
              "shipping": 0,
              "title": "Harry Potter"
            }
          ],
          "shipping": {
            "address1": "Shipmentstraat 42 bis",
            "address2": "",
            "address_supplement": "3 hoog achter extra adres info",
            "city": "Amsterdam",
            "company": "The Company",
            "country_code": "NL",
            "email": "nospam4me@myaccount.com",
            "first_name": "Jan",
            "house_number": 42,
            "house_number_ext": "bis",
            "last_name": "Janssen",
            "middle_name": "",
            "region": "",
            "street": "Shipmentstraat",
            "zip_code": "1000 AA"
          },
          "delivery_request": {
            "method": "Shipping method",
            "carrier": "Shipping carrier",
            "promise": "Shipping promise"
          }
        },
        "error": false,
        "fulfillment": {},
        "id": 299623,
        "modified": "2017-08-10T18:08:13.699449",
        "platform_id": "299623",
        "platform_name": "channable",
        "project_id": 6496,
        "status_paid": "paid",  # This is always paid, because the marketplace handles payments
        "status_shipped": "shipped"
      },
      "events": [
        {
          "created": "2016-10-20T10:55:08.507355",
          "id": 1234545,
          "message": "Sent shipment update to Amazon",
          "modified": "2016-10-20T10:55:08.507378",
          "order_id": 299623,
          "project_id": 91919,
          "status": "info"
        },
        {
          "created": "2016-10-20T10:54:53.074700",
          "id": 2370337,
          "message": "Changed shipping status: not_shipped -> shipped",
          "modified": "2016-10-20T10:54:53.074705",
          "order_id": 299623,
          "project_id": 91919,
          "status": "info"
        },
        {
          "created": "2016-10-19T10:54:15.008544",
          "id": 1407404,
          "message": "Channable order processed: 299623",
          "modified": "2016-10-19T10:54:15.008551",
          "order_id": 299623,
          "project_id": 91919,
          "status": "info"
        }
      ]
    }
    

    This endpoint retrieves an order, and its events, based on the order_id.

    Request

    Method GET
    Endpoint /orders/:order_id
    Headers none
    Query parameters none

    Response

    The response body is a JSON object containing the following fields:

    You can see at your right a real example of such return value.

    Understanding the address fields

    There are two ways of storing the address information for order billing and shipping:

    1. Using the fields street, house_number, house_number_ext, and address_supplement
    2. Using the fields address1 and address2

    The first is more used in the Netherlands, where an address requires a house number, while the second version is more used abroad. We support both cases, and, in the example to the right, you see how to translate one into the other.

    Understanding the price fields

    An order contains a list of products purchased by a customer.
    The product.quantity stores the quantity of products of a given kind were purchased. The product.price is per product, not product.quantity * price_per_unit. The order.price.total is the sum of all purchased products' price, shipping costs, and other applicable fees.

    Shipment update

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/orders/7/shipment' \
        -H 'authorization: Bearer api_key' \
        -H 'content-type: application/json' \
        -X POST -d '{"tracking_code": "3S93829038223232", "transporter": "DHL"}'
    
    updateOrderShipment :: Int -> IO (Response ByteString)
    updateOrderShipment id =
      postWith reqOptions ("https://api.channable.com/v1/companies/123/projects/456/orders/" <> show id <> "/shipment") reqBody
        where reqBody = object ["tracking_code" .= ("3S93829038223232" :: String)]
    
    def update_order_shipment():
      request_body = json.dumps({'tracking_code': '3S93829038223232', 'transporter': 'DHL'})
      return requests.post("https://api.channable.com/v1/companies/123/projects/456/orders/7/shipment",
                           headers={'Authorization': "Bearer {}".format(api_token), 'Content-Type': 'application/json'},
                           data=request_body
                          )
    

    This endpoint allows you to update an order shipment status.
    We will then propagate the update to the involved marketplaces.

    Request

    Method POST
    Endpoint /orders/:order_id/shipment
    Headers Content-Type: application/json
    Query parameters none

    Request body scheme

    {
        "type": "object",
        "properties": {
            "tracking_code": {"type": ["string", "null"]},
            "transporter": {"type": ["string", "null"]}
        }
    }
    

    Body

    We expect a JSON body containing the following optional fields:

    Field Expected Type
    tracking_code String or null
    transporter String or null

    Response

    Response

    {
      "status": "success",
      "message": "Processed 1 shipment"
    }
    

    The response body is a JSON object containing the following fields:

    Field Type Value
    status String "success"
    message String "Processed 1 shipment"

    Cancellation update

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/orders/7/cancel' \
        -H 'authorization: Bearer api_key' \
        -H 'content-type: application/json'
    
    updateOrderShipment :: Int -> IO (Response ByteString)
    updateOrderShipment id =
      postWith reqOptions ("https://api.channable.com/v1/companies/123/projects/456/orders/" <> show id <> "/cancel")
    
    def update_order_shipment():
      return requests.post("https://api.channable.com/v1/companies/123/projects/456/orders/7/cancel",
                           headers={'Authorization': "Bearer {}".format(api_token), 'Content-Type': 'application/json'},
                          )
    

    This endpoint allows you to update an order status and set it to cancelled. We will then propagate the update to the involved marketplaces.
    Note that this only covers the case where the seller wants to cancel an order. If the buyer cancels an order, the marketplace requires the seller to manually confirm this cancellation in the marketplace seller account.

    Request

    Method POST
    Endpoint /orders/:order_id/cancel
    Headers Content-Type: application/json
    Query parameters none

    Response

    Response

    {
      "status": "success",
      "message": "Processed 1 cancellation"
    }
    

    The response body is a JSON object containing the following fields:

    Field Type Value
    status String "success"
    message String "Processed 1 cancellation"

    Offers

    Get all offers

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/offers?limit=3' \
        -H 'authorization: Bearer api_key'
    
    getAllOffers :: IO ()
    getAllOffers =
      getWith reqOptions ("https://api.channable.com/v1/companies/123/projects/456/offers?limit=3")
        where reqOptions = defaults & header "Authorization" .~ ["Bearer " <> apiToken]
    
    def get_all_offers():
      return requests.get("https://api.channable.com/v1/companies/123/projects/456/offers",
                          headers={'Authorization': "Bearer {}".format(api_token)},
                         ).json()
    

    Response

    {
        "offers": [
            {
                "stock": 9,
                "created": "2017-09-18T18:42:22.082110",
                "price": "16.50",
                "id": 13,
                "client_id": "28996383",
                "available": true,
                "stock_tracking": true,
                "project_id": 6496,
                "modified": "2017-09-18T18:42:22.082116",
                "title": "A Deeper Understanding",
                "gtin": "57492975777038"
            },
            {
                "stock": 9,
                "created": "2017-09-18T18:42:22.076744",
                "price": "9.99",
                "id": 12,
                "client_id": "28996382",
                "available": true,
                "stock_tracking": true,
                "project_id": 6496,
                "modified": "2017-09-18T18:42:22.076755",
                "title": "Medicine Music",
                "gtin": "8459297524058"
            },
            {
                "stock": 9,
                "created": "2017-09-18T18:06:04.649664",
                "price": "12.99",
                "id": 11,
                "client_id": "28996383",
                "available": true,
                "stock_tracking": true,
                "project_id": 6496,
                "modified": "2017-09-18T18:06:04.649671",
                "title": "Smoke Ring for my Halo",
                "gtin": "635964745195"
            }
        ],
        "total": 9
    }
    

    This endpoint retrieves all offers for a given project of your company, sorted from most recent to oldest. Offers are the product updates that you posted. These are found under "Orders" > "Product updates" in the Channable tool.
    Optionally, you can pass query parameters to customize the query and response content.

    Request

    Method GET
    Endpoint /offers
    Headers none
    Query parameters see below

    Query parameters

    Parameter Type Default Description
    offset Int 0 Defines the starting position
    limit Int 15, max = 100 The number of offers to retrieve after offset.
    search String empty Search term used to filter the offers list.
    start_date String empty Search for offers with a creation date after this date, in format YYYY-MM-DD
    end_date String empty Search for offers with a creation date before this date, in format YYYY-MM-DD

    Example

    Suppose the following scenario for a given project of yours:

    Request parameters Response
    none {"offers": [o4, o3, o2, o1], "total": 4}
    ?limit=2 {"offers": [o4, o3], "total": 4}
    ?offset=4 {"offers": [], "total": 4}
    ?offset=1 {"offers": [o3, o2, o1], "total": 4}
    ?offset=1&limit=1 {"offers": [o3], "total": 4}
    ?offset=1&limit=2 {"offers": [o3, o2], "total": 4}
    ?search=t {"offers": [o4, o1], "total": 4}
    ?search=tE {"offers": [o3], "total": 4}
    ?start_date=2018-01-01 {"offers": [o4, o3, o2], "total": 4}
    ?start_date=2018-01-01&end_date=2018-02-28 {"offers": [o3, o2], "total": 4}

    Response

    The response body is a JSON object containing the following fields:

    You can see at your right a real example of such return value.

    Update project offers

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/offers' \
      -H 'authorization: Bearer api_key' \
      -H 'content-type: application/json' \
      -X POST -d '[{"id": "123", "title": "abc", "price": 123.45, "stock": 9}]'
    
    updateOffersStock =
      postWith reqOptions "https://api.channable.com/v1/companies/123/projects/456/offers" requestBody
        where
          reqOptions = defaults & header "Authorization" .~ ["Bearer " <> apiToken]
          requestBody = toJSON [object [ "id" .= ("123" :: String)
                                           , "title".= ("abc" :: String)
                                           , "price" .= (123.45 :: Double)
                                           , "stock" .= (9 :: Int)
                                           ]
                                   ]
    
    def update_offers_stock():
      request_body = json.dumps([{"id": "123",
                                  "title": "abc",
                                  "price": 123.45,
                                  "stock": 9
                                }])
      return requests.post("https://api.channable.com/v1/companies/123/projects/456/offers",
                           headers={'Authorization': "Bearer {}".format(api_token), 'Content-Type': 'application/json'},
                           data=request_body
                          ).json()
    

    This endpoint allows you to update the offers' stock of a selected project.
    We will then propagate the update to all the marketplaces of the targeted project.

    Request

    Method POST
    Endpoint offers
    Headers Content-Type: application/json
    Query parameters none
    Limit 50 offers per request

    Body

    Request body JSON schema

    {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "price", "stock", "title"],
        "properties": {
          "id": {"oneOf": [{"type": "string"}, {"type": "number"}]},
          "title": {"type": "string"},
          "price": {"type": "number", "minLength": 1},
          "discount_price": {"oneOf": [{"type": "number"}, {"type": "null"}]},
          "stock": {"type": "number"},
          "gtin": {"type": "string"}
        }
      }
    }
    

    The request body is expected to be a list of offers (max. 50 per request) with the following fields and types specification:

    Field Type Required
    id String / number
    title String
    price number
    discount_price number
    stock number
    gtin String

    Response

    Response

    {
        "status": "success",
        "message": "1 offers sent",
        "content": [
            {
                "id": "123",
                "status": "success",
                "message": "OK"
            }
        ]
    }
    

    The response body is a JSON object containing the following fields:

    Field Value
    status success
    message <number_of> offers sent (e.g., "3 offers sent")
    content list containing the result of updating each offer, per marketplace.

    Returns

    Get all returns

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/returns?limit=1' \
        -H 'authorization: Bearer api_key'
    
    getAllOffers :: IO ()
    getAllOffers =
      getWith reqOptions ("https://api.channable.com/v1/companies/123/projects/456/returns?limit=1")
        where reqOptions = defaults & header "Authorization" .~ ["Bearer " <> apiToken]
    
    def get_all_offers():
      return requests.get("https://api.channable.com/v1/companies/123/projects/456/returns?limit=1",
                          headers={'Authorization': "Bearer {}".format(api_token)},
                         ).json()
    

    Response

    {
        "returns": [
            {
                "status": "new",
                "channel_name": "bol",
                "channel_id": "61284922",
                "channable_id": 151,
                "data": {
                    "item": {
                        "id": "11694321",
                        "order_id": "4522232111",
                        "gtin": "0884500642113",
                        "title": "Nike Air Force 1 Winter Premium GS Flax Pack",
                        "quantity": 1,
                        "reason": "Anders, namelijk:",
                        "comment": "De schoenen vielen te groot."
                    },
                    "customer": {
                        "gender": "male",
                        "first_name": "Jans",
                        "last_name": "Van Janssen",
                        "email": "2ixee2337ca74m23423uu@verkopen.bol.com"
                    },
                    "address": {
                        "first_name": "Jans",
                        "last_name": "Van Janssen",
                        "email": "2ixee2337ca74m23423uu@verkopen.bol.com",
                        "street": "Teststraat",
                        "house_number": 12,
                        "address1": "Teststraat 12",
                        "adderss2": "",
                        "city": "Utrecht",
                        "country_code": "NL",
                        "zip_code": "1234 XZ"
                    }
                }
            }
        ],
        "total": 9
    }
    

    This endpoint retrieves all returns for a given project of your company, sorted from most recent to oldest.
    Optionally, you can pass query parameters to customize the query and response content.

    Request

    Method GET
    Endpoint /returns
    Headers none
    Query parameters see below

    Query parameters

    Parameter Type Default Description
    offset Int 0 Defines the starting position
    limit Int 15, max = 100 The number of returns to retrieve after offset.
    search String empty Search term used to filter the returns list.
    start_date String empty Search for returns with a creation date after this date, in format YYYY-MM-DD
    end_date String empty Search for returns with a creation date before this date, in format YYYY-MM-DD

    Example

    Suppose the following scenario for a given project of yours:

    Request parameters Response
    none {"returns": [o4, o3, o2, o1], "total": 4}
    ?limit=2 {"returns": [o4, o3], "total": 4}
    ?offset=4 {"returns": [], "total": 4}
    ?offset=1 {"returns": [o3, o2, o1], "total": 4}
    ?offset=1&limit=1 {"returns": [o3], "total": 4}
    ?offset=1&limit=2 {"returns": [o3, o2], "total": 4}
    ?search=t {"returns": [o4, o1], "total": 4}
    ?search=tE {"returns": [o3], "total": 4}
    ?start_date=2018-01-01 {"returns": [o4, o3, o2], "total": 4}
    ?start_date=2018-01-01&end_date=2018-02-28 {"returns": [o3, o2], "total": 4}

    Return status update

    Request

    $ curl 'https://api.channable.com/v1/companies/123/projects/456/returns/7/status' \
        -H 'authorization: Bearer api_key' \
        -H 'content-type: application/json' \
        -X POST -d '{"status": "accepted"}'
    
    updateReturnStatus:: Int -> IO (Response ByteString)
    updateReturnStatus id =
      postWith reqOptions ("https://api.channable.com/v1/companies/123/projects/456/returns/" <> show id <> "/status") reqBody
        where reqBody = object ["status" .= ("accepted" :: String)]
    
    def update_return_status():
      request_body = json.dumps({'status': 'accepted'})
      return requests.post("https://api.channable.com/v1/companies/123/projects/456/returns/7/status",
                           headers={'Authorization': "Bearer {}".format(api_token), 'Content-Type': 'application/json'},
                           data=request_body
                          )
    

    This endpoint allows you to update a return status. We will then propagate the update to the involved marketplaces.
    Depending of the return status the end customer does or does not get their money back.

    Request

    Method POST
    Endpoint /returns/:return_id/status
    Headers Content-Type: application/json
    Query parameters none

    The return_id is the Channable id of the return.

    Request body scheme

    {
        "type": "object",
        "required": ["status"],
        "properties": {
            "status": {"type": "string", "minLength": 1, "enum": ["accepted", "rejected", "repaired", "keeps", "exchanged", "cancelled"]},
        }
    }
    

    Body

    We expect a JSON body containing the required shipment information:

    Field Type Required
    status String

    Possible values for status

    Value Description
    accepted Accept the return, the end customer gets their money back.
    rejected Reject the return, the end customer does not get their money back.
    repaired The product is repaired and send back to the customer, they do not get their money back.
    keeps The customer keeps the product but does get their money back.
    exchanged A different product is sent to the customer, they do not get their money back.
    cancelled The return is cancelled, the end customer does not get their money back.

    Response

    Response

    {
      "status": "success",
      "message": "Processed 1 return status update"
    }
    

    The response body is a JSON object containing the following fields:

    Field Type Value
    status String "success"
    message String "Processed 1 return status updates"

    Sandbox Testing

    The channable api sandbox lets you test your order integration with the channable api in a safe environment without sending requests to the marketplaces you want to connect to. All data is mocked but the structure of the data and api calls needed to manage your orders are the same no matter which marketplace you end up connecting with.

    Setup

    To setup a test environment with the Channable Sandbox you must first make a connection with the Sandbox. This can be done in the same way as all other conenctions within Channable by going to user_name -> connections and clicking on "+ Add new connection".

    Select "Channable Sandbox", give the connection a label and click on the blue "Create" button. No further information is needed.

    Once you have made a connection, navigate to the project you want to use and click on "Setup" -> "Setup orders" > "+ Setup orders".

    From here make an order connection between the "Channable API" and the "Channable Sandbox" and activate the order connection. You are now ready to start testing.

    Orders

    To create a test order, navigate to "Setup" -> "Setup orders" -> "Settings" of the Channable Sandbox order connection. From here click on the gear in the top right and "Send test order".

    In the popup fill in an item id and click the blue "Send test order" button. A test order has now been created and you can use all request methods described in "Orders" above to interact with it.

    Shipments/Cancellations

    Once one or more testorders have been created, use the request methods described in "Shipment update" and "Cancellation update" under "Orders" above to mark an order as "shipped" and to give it track & trace information or to mark the order as "cancelled".

    Offers

    To test sending offer updates, that is updating the stock value on all marketplaces that you have an order connection to, you can use the request methods described in "Offers" above. You do not need to have created a test order to test this as you can update the stock value of any product in your store, also products that you have not received an order for through Channable.

    Returns

    Returns come from the marketplaces you will connect to. In order to test this, navigate to "Setup" -> "Setup orders" -> "Settings" of the Channable Sandbox order connection. From here click on the gear in the top right and "Send test return".

    In the popup fill in a Channable order id and click the blue "Send test return" button. A test return has now been created for the order id you filled in. You can now use all request methods described in "Returns" above to handle the return.

    When you are done testing

    Once you are satisfied with your Channable api setup and want to go live, contact our support department and they will help you setup the order connections.

    Errors

    The response body in this case will be:

    {
      "status": "error",
      "message": "explanation of what went wrong"
    }
    

    The exception to the rule is the 401, whose body is:

    {
      "error": "explanation of what went wrong",
      "data": null
    }
    

    The Channable API uses the following error codes:

    Code Meaning Reason
    400 Bad Request The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)
    401 Unauthorized You are using an invalid or already revoked API token.
    403 Forbidden You are not allowed to access the resources your request targets.
    404 Not Found The targeted resources could not be found.
    405 Method Not Allowed You tried to access an endpoint with an invalid HTTP method.
    406 Not Acceptable You requested a format that isn't json.
    409 Conflict Your request could not be completed due to a conflict with the current state of the target resource.
    422 Unprocessable Entity We could understand the content type of the request entity, but we are unable to process the contained instructions.
    429 Too Many Requests You have sent too many requests in a given amount of time, thus exceeding our rate-limiting policy. Please try again later.
    500 Internal Server Error We had a problem with our server. Please try again later.
    503 Service Unavailable We are temporarily offline for maintenance. Please try again later.

    Transporters

    This is a list of all standardized codes to identify transporters. Please use the value that is in the "code" column as transporter code. When sending a shipment update Channable will ensure that this code is translated to the correct transporter code for the channel that you are using, as every channel users different transporter codes. When a channel does not support your transporter, Channable will default to the "OTHER" transporter code.

    Code Label
    OTHER Other (Use if your transporter is not in this list)
    OTHER_INTERNATIONAL Other (Use if your transporter is not in this list and you're shipping internationally)
    4PX 4PX
    4PX_EXPRESS 4PX Express
    4PX_BPOST_RU 4PX Bpost to Russia
    4PX_POSTPY 4PX Postpy
    4PX_PAQ24 4PX Correos PAQ24
    4PX_ESPOST_EU 4PX Espost EU
    4PX_TR72_PACKET 4PX TR72-Packet
    4PX_SEUREU 4PX SEUR EU
    4PX_SEUR24 4PX SEUR (24 Hours Delivery)
    4PX_GLSEU_SMALL 4PX GLS EU Small
    4PX_GLSEU_LARGE 4PX GLS EU Large
    4PX_SDA 4PX SDA
    A1 A1
    ABF ABF Freight
    ADREXO Adrexo
    ADRIATIC Adriatic
    AEROPOST AeroPost
    AFL_FEDEX AFL/Fedex
    AFTERSHIP Aftership
    ALIANCA Alianca
    ALLIED_EXPRESS Allied Express
    AMATI Amati
    AMAZON_LOGISTICS Amazon Logistics
    AMAZON_SHIPPING Amazon Shipping
    AMWST AMWST
    ANPOST An Post
    APC APC Postal Logistics
    ARAMEX Aramex
    ARCO Arco
    ARVATO Arvato
    ASENDIA Asendia
    ASM ASM
    ATS ATS
    AUSTRALIAN_AIR_EXPRESS Australian Air Express
    AUSTRALIA_POST Australia Post
    AUSTRIA_POST Austria Post
    AVRT Averitt Express
    B2C B2C
    BALAJI_SHIPPING Balaji Shipping
    BARTOLINI BRT Bartolini
    BKNS BKNS
    BLUEDART BlueDart
    BLUE_PACKAGE Blue Package
    BLUESKY Bluesky
    BONNARD Bonnard
    BPOST Bpost
    BPOST_LETTER Bpost letter post
    BRING Bring
    BRT Bartolini
    BRTID BRT id collo cliente
    BRTRIFMIT BRT riferimento mittente
    BRTSPED BRT numero di spedizione
    BURSPED Bursped
    BUSINESS_POST BusinessPost
    CAINIAO_WH Cainiao Warehouse Standard
    CAINIAO_WH_EXPRESS Cainiao Warehouse Express
    CANADA_POST Canada Post
    CANPAR CanPar Courier
    CARGO Cargo
    CARGOLINE Cargoline
    CCHEZVOUS C Chez Vous
    CELERITAS Celeritas
    CENF Central Freight Lines
    CEVA CEVA Logistics
    CHINA_POST China Post
    CHINA_SHIPPING China Shipping
    CHRONO_EXPRESS Chrono Express
    CHRONOPOST Chronopost
    CHRONOPOST_INTERNATIONAL Chronopost International
    CHUKOU1 Chukou1
    CHUNGHWA_POST Chunghwa Post
    CITIPOST CitiPost
    CITYLINK Citylink
    CLICK_AND_QUICK Click & Quick
    CMACGM CMA CGM
    CNE_EXPRESS CNE Express
    COLIPOSTE Coliposte
    COLIPOSTE_INTERNATIONAL Coliposte International
    COLIS_PRIVE Colis Prive
    COLISSIMO Colissimo
    COLISSIMO_ACCESS Colissimo Access
    COLISSIMO_EXPERT Colissimo Expert
    COLLECTPLUS CollectPlus
    COMPUTER_UNIVERSE Computeruniverse
    CORREIOS Correios
    CORREOS Correos
    CORREOS_PAQ Correos Paquetería
    CORREOS_EXPRESS Correos Express
    COURIER Delivery appointment
    COURIERSPLEASE CouriersPlease
    COURRIER Courrier
    COURRIER_SUIVI Courrier Suivi
    CPC_LOGISTICS CPC Logistics
    CTT CTT
    CTT_EXPRESS CTT Express
    DAC DAC
    DACHSER Dachser
    DAI_POST DAI Post
    DAY_AND_ROSS Day & Ross
    DBSCHENKER DB Schenker
    DELHIVERY Delhivery
    DELNEXT Delnext
    DER_COURIER Der Courier
    DEUTSCHE_POST Deutsche Post
    DHL DHL
    DHL_2_MH DHL 2 MH
    DHL_DEUTSCHE_POST DHL Deutsche Post
    DHL_ECOMMERCE_ASIA DHL Ecommerce Asia
    DHL_EKB DHL EKB
    DHL_EXPRESS DHL Express
    DHL_FOR_YOU DHL For You
    DHL_FREIGHT DHL Freight
    DHL_GLOBAL_MAIL DHL Global Mail
    DPD DPD
    DPX_THAILAND DPX Thailand
    DRAGON_STAR Dragon Star
    DSV DSV
    DTDC DTDC
    DTL DTL
    DUCROS Ducros
    DYNALOGIC Dynalogic
    EGO E-go
    EMONS Emons
    ENDOPACK Endopack
    ENERGO Energo
    ENVIALIA Envialia
    EPARCEL Eparcel
    EUB EUB
    EUROMATIC Euromatic
    EXAPAQ Exapaq
    FASTWAY Fastway
    FASTWAY_COURIERS Fastway Couriers
    FEDEX FedEx
    FEDEX_SMARTPOST FedEx SmartPost
    FERCAM Fercam
    FIEGE Fiege
    FIETSKOERIERS Fietskoeriers
    FIRST_FLIGHT First Flight
    FLYT Flyt
    FLYT_EXPRESS Flyt Express
    FRANCE_EXPRESS France Express
    FWL Fast World Logistic
    GDSK GdSK
    GEFCO GEFCO
    GEL GEL
    GEODIS Geodis
    GEODISC_ALBERSON Geodis Calberson
    GLS GLS
    GLS_EU GLS International
    GLS_IDC GLS id collo
    GO GO!
    GO_EXPRESS Go Express
    HELLMANN Hellmann
    HENRI_DUCROS Henri Ducros
    HEPPNER Heppner
    HERMES Hermes
    HERMES_2_MH Hermes 2 MH
    HK_POST Hongkong Post
    HUNTER_EXPRESS Hunter Express
    ICP ICP
    IDS_LOGISTIK IDS Logistik
    ILOXX Iloxx
    INDIA_POST India Post
    INDONESIA_POST Indonesia Post
    INTERLINK Interlink Express
    INTERNATIONAL_BRIDGE International Bridge Domestic delivery
    INTERPOST InterPost
    IOINVIO IoInvio
    ISRAEL_POST Israel Post
    ITALY_POST Poste Italiane
    JAPAN_POST Japan Post
    JCO JCO
    JP_EXPRESS JP Express
    KDZ KDZ
    KIALA Kiala
    KN Kuehne & Nagel
    KOREA_POST Korea Post
    LANDMARK Landmark Global
    LA_POSTE La Poste
    LASERSHIP Lasership
    LETTER Letter post
    LETTER_TRACKED Letter post tracked
    LOGOIX LogoiX
    LPS LPS
    MALAYSIA_POST Malaysia Post
    MANNA_FREIGHT Manna Distribution Services
    MARKTANLIEFERUNG Marktanlieferung
    METAPACK Metapack
    MIDWAY Midway
    MNG_KARGO MNG Kargo
    MOBEL Mobel
    MONDIAL_RELAY Mondial Relay
    MORYDUCROS Mory Ducros
    MRW MRW
    MSI_TRANSPORTATION MSI Transportation
    MXD_GROUP MXD_GROUP
    NACEX Nacex
    NEMF New England Motor Freight
    NEMO_EXPRESS Nemo Express
    NEWGISTICS Newgistics
    NEXIVE Nexive
    NIPPON_EXPRESS Nippon Express
    NITTSU Nittsu
    NOXX_LOGISTIC Noxxs Logistic
    ODFL Old Dominion Freight Line
    ONTRAC OnTrac
    OSM OSM
    OVERNITE_EXPRESS Overnite Express
    P2P_TRAKPAK P2P TrakPak
    PACKLINK PackLink
    PACKS Packs
    PAKET Paket.ag
    PANTHER_LOGISTICS Panther Logistics
    PARCEL Parcel.nl
    PARCELFORCE Parcelforce
    PARCELNET Parcelnet
    PFW Parcel Force Worldwide
    PHILIPPINE_POST PHLPost
    PILOT_FREIGHT Pilot Freight Services
    PITT_OHIO PITT OHIO
    POCZTEX Pocztex
    POLAND_POST Poczta Polska
    POSTENALAND Posten Âland
    POSTNL PostNL
    POSTNL_EXPRESS PostNL Express
    POSTNL_EXTRA PostNL extra@home
    POSTNL_LETTER PostNL letter
    POSTNORD Postnord
    PRIMEMAIL PrimeMail
    PROFESSIONAL Professional
    QUANTIUM Quantium
    RABEN Raben
    REDDAWAY Reddaway
    REDUR Redur
    REDYSER Redyser
    RELAIS_COLIS Relais Colis
    RHENUS Rhenus
    RJP Red je pakketje
    ROYAL_MAIL Royal Mail
    SAGAWA Sagawa
    SAGAWA_EXPRESS Sagawa Express
    SAIA Saia
    SAMEDAY Sameday
    SANDD Sandd
    SCHENKER_JOYAU Schenker-Joyau
    SDA SDA
    SDV SDV
    SELEKTVRACHT Selektvracht
    SELLIER Sellier
    SERNAM Sernam
    SEUR Seur
    SFC_SERVICE SFC Service
    SF_EXPRESS SF Express
    SGT SGT
    SINGAPORE_POST Singapore Post
    SLOVENIA_POST Post of Slovenia
    SMARTMAIL Smartmail
    SO_COLISSIMO SoColissimo
    SPEDITION_GUETTLER Spedition Guettler
    SPEEDY Speedy
    SPRING Spring Global Mail
    STREAMLITE Streamlite
    STRECK Streck
    SWEDEN_POST Sweden Post
    SWISS_POST Swiss Post
    TARGET Target
    TAT TAT
    TECNO_TRANS Tecnotrans
    TIPSA Tipsa
    TNT TNT
    TOLL_GLOBAL_EXPRESS Toll Global Express
    TOMBA Tomba
    TOURLINE_EXPRESS Tourline Express
    TPG TPG Logistics
    TRANS_FM Trans FM
    TRANSMISSION TransMission
    TRANS_O_FLEX Trans-o-Flex
    TRUNKRS Trunkrs
    TSN Transportservice Nederland
    UBI UBI Smart Parcel
    UK_MAIL UKMail
    UPS UPS
    UPS_FREIGHT UPS Freight
    UPS_IPARCEL UPS i-parcel
    UPS_MAIL_INNOVATIONS UPS Mail Innovations
    UPSMI UPSMI
    USPS USPS
    USPS_EPACKET USPS Commercial ePacket
    USPS_PRIORITY_MAIL_INTERNATIONAL USPS Priority Mail International
    VENIPAK Venipak
    VIETNAM_POST Vietnam Post
    VITRAN Vitran Express
    VOS_LOGISTICS Vos Logistics
    WANB_EXPRESS Wanb Express
    WINIT WIN.IT America
    WISHPOST WishPost
    WNDIRECT WNdirect
    WPX WPX Delivery Solutions
    XPO XPO Logistics
    YAMATO Yamato
    YAMATO_TRANSPORT Yamato Transport
    YANWEN Yanwen
    YDH YDH
    YODEL Yodel
    YRC YRC Freight
    YUN_EXPRESS Yun Express
    YUN_POST Yun Post
    YUN_TRACK Yun Track
    ZELERIS Zeleris
    ZHIPSTER Zhipster
    ZIEGLER Ziegler
    ZIM ZIM
    ZUFALL Zufall
    ZUST Zust