NAV Navbar

Introduction

Welcome to the Cubyn API! This API is organized around REST over HTTPS.

If you need help implementing the Cubyn API on your website, send us an email at onboarding@cubyn.com to get your API Application Key!

We also provide a Sandbox environment where you will be able to test your integration before going live. See Using Cubyn Sandbox

All our endpoints speak JSON fluently.

Authentication

Try this with your applicationKey

curl https://api.cubyn.com/v2 \
    -H 'X-Application: my-api-key'

RESPONSE

{
  "version": "0.0.3",
  "name": "cubyn.api",
  "description": "Please visit developers.cubyn.com for further information on this API.",
  "auth": {
    "application": {
      "name": "Mathieu Lemaire",
      "createdAt": "2015-08-19T10:18:13.000Z",
      "updatedAt": "2015-08-19T10:18:14.000Z"
    },
    "user": {
      "id": 706293859,
      "firstName": "Mathieu",
      "lastName": "Lemaire",
      "phone": "0664543537",
      "createdAt": "2015-08-19T10:18:13.000Z",
      "updatedAt": "2015-08-19T10:18:13.000Z",
      "email": "mathieu@cubyn.com"
    }
  }
}

All endpoints except GET /v2 require a proper authentication. Your API credentials will consist of an applicationKey. Authentication is done simply by adding an X-Application header containing your API Key.

Quick Start Guide

Cubyn enables e-merchants to manage their inventory, orders and returns from a single interface. The process is simple as below:

Step Description API METHOD
STEP 1 Send inventory POST /v2/storage-inbound/orders?filters[warehouseId]=24082363
STEP 2 Track inventory GET /v2/product-catalog/products/
STEP 3 Create parcels POST /v2/parcels
STEP 4 Track parcels GET /v2/parcels/:id

STEP 1: Send inventory

REQUEST (curl)

curl --request POST \
  --url 'https://api.cubyn.com/v2/storage-inbound/orders?filters%5BwarehouseId%5D=24082363&=' \
  --header 'content-type: application/json' \
  --header 'x-application: my-app-key' \
  --data ' {
    "packingUnits": 1,
    "items": [{
        "productName": "product33",
        "sku": "mySku_product33",
        "barcode": "EAN_product33",
        "quantity": 4
    }]
}'

RESPONSE

{
  "id": "e4f007ae-4412-4f90-bc17-a7aa2679b7a6",
  "pid": "290833",
  "declaredPackingUnits": 1,
  "declaredItems": 1,
  "status": "VALIDATED"
}

POST /v2/storage-inbound/orders?filters[warehouseId]=24082363

Field Type Details
packingUnits Integer Quantity of boxes or pallets containing your products for the stock shipment
 items Array Array of items in your inbound order
 items.$.productName* String Name of your product
items.$.sku* String  Unique reference of your product
items.$.barcode* String Physical identification of your product (EAN, IMEI, UPC...)
items.$.quantity Integer Quantity of objects per item

Golden rules for an inbound order creation :

This route returns the created inbound order.

Field Type Details
id String Id used for the API call for the inbound order
pid String Inbound order ID to write on your packing unit before sending it to the warehouse
declaredPackingUnits Number Number of packing units you declared in your inbound order
declaredItems Number Number of items you declared in your inbound order
status Array Status of your inbound order

STEP 2: Track inventory

REQUEST (curl)

curl --request GET \
  --url https://api.cubyn.com/v2/product-catalog/products/ \
  --header 'x-application: my-app-key'

RESPONSE

[
   {
      "id":"5a110318-7170-43f0-bf74-6904d132944f",
      "ownerId":366912065,
      "sku":"iPhone_10_32G",
      "sanitizedSku":"IPHONE-10-32G",
      "name":"iPhone 10 32G",
      "isVirtual":false,
      "isBundle":false,
      "createdAt":"2019-11-13T17:05:47.000Z",
      "updatedAt":"2019-11-13T17:05:47.000Z",
      "scubsIds":[  ],
      "stock":{
         "hadStockInbounded":true,
         "quantityAvailable":33,
         "quantityOutbounded":0,
         "quantityInbounding":0,
         "quantityOutbounding":0,
         "ownerId":366912065,
         "scubId":"32b716d2-aea4-4ebc-b15d-64dd88e3f2c3"
      },
      "requiresItemIdentifiers":"NONE",
      "barcodes":[
         {
            "scubId":"32b716d2-aea4-4ebc-b15d-64dd88e3f2c3",
            "value":"08N987N9X8NAZ",
            "type":"USER_SKU",
            "createdAt":"2019-11-13T17:05:48.000Z",
            "rawValue":"08N987N9X8NAZ"
         }
      ],
      "externalReferences":[
         {
            "value":"IPHONE-10-32G",
            "rawValue":"iPhone_10_32G"
         }
      ]
   }
]

/v2/product-catalog/products/

STEP 3: Create parcels

REQUEST (curl)

curl https://api.cubyn.com/v2/parcels \
    -H 'X-Application: my-app-key' \
    -H 'Content-Type: application/json' \
    --data '{ \
      "firstName":"Sophie", \
      "lastName":"Martin", \
      "items":[ \
        { \
          "reference":"product_name", \
          "count":1 \
        } \
      ], \
      "orderRef": "my_order_reference", \
      "address":{ \
          "line1":"3 place de la Republique", \
          "zip":"69002", \
          "city":"Lyon", \
          "country":"France", \
          "additionalInformation":"code 9898" \
      }, \
      "objectCount":2 \
    }'

RESPONSE

{
  "id": 673847167,
  "status": "CREATED",
  "address": {
    "line1": "3 place de la Republique",
    "zip": "69002",
    "city": "Lyon",
    "country": "France",
    "additionalInformation": "code 9898"
  },
  "firstName": "Sophie",
  "lastName": "Martin",
  "deliveryMode": "standard",
  "deliverySigned": false,
  "isAdvalorem": 0,
  "applcationId": "92390180134",
  "shipperId": "2932983427982",
  "collectId": null,
  "barcode": null,
  "qrCode": null,
  "createdAt": "2015-08-18T16:26:08.000Z",
  "updatedAt": "2015-08-18T16:26:08.000Z"
}

POST /v2/parcels

Field Type Details
address * <Address> Defines the recipient address (see format)
items [<Item>] Array of items contained in this parcel (see format)
firstName string First name of recipient (max 35 characters)
lastName string Last name of recipient (max 35 characters)
organizationName string Organization name (max 35 characters) One of firstName, lastName and organizationName has to be defined
deliveryMode Enum<string> Shipping mode allowed: standard, express or relay
deliverySigned boolean Should shipment be handed against signature
relayPickupRef string Pickup point identifier (only if deliveryMode is relay) (see handling relay)
phone string Phone of recipient (phone format needed)
email string Email of recipient (email format needed)
isAdvalorem boolean Activation of ad valorem insurance of your parcel according to the value of your SKUs
orderRef string Unique reference of the parcel
value number Overall value of parcel (for international shipping only)
customsHsCode string Harmonized system code (for international shipping only)
customsCategory Enum<string> Nature of the order 'GIFT','DOCUMENTS','COMMERCIAL_SAMPLE','COMMERCIAL','RETURNED_GOODS','OTHER'
customsDescription string Description of contect (for international shipping only) (max 65 characters)
customsOriginCountry string Origin country (for international shipping only)

STEP 4: Track parcels

REQUEST (curl)

curl https://api.cubyn.com/v2/parcels/673847167 \
    -H 'X-Application: my-app-key'

RESPONSE

{
  "id": 673847167,
  "status": "CREATED",
  "address": {
    "line1": "3 place de la Republique",
    "zip": "69002",
    "city": "Lyon",
    "country": "France",
    "additionalInformation": "code 9898"
  },
  "firstName": "Sophie",
  "lastName": "Martin",
  "deliveryMode": "standard",
  "deliverySigned": false,
  "objectCount": 2,
  "isAdvalorem": 0,
  "applcationId": "92390180134",
  "shipperId": "2932983427982",
  "collectId": null,
  "barcode": null,
  "qrCode": null,
  "cancellationStatus": "NONE",
  "createdAt": "2015-08-18T16:26:08.000Z",
  "updatedAt": "2015-08-18T16:26:08.000Z"
}

GET /v2/parcels/:id

Use webhooks to subscribe to events related to parcels you created.

By providing us with a webhook, you will be notified everytime a parcel sees its status change. This allows you to take the appropriate action in the shortest delay, such as informing your customers that their product has been shipped.

Enabling webhooks

To activate webhooks for your account, configue on shipper.cubyn.com applications:

Webhook event types

A webhook call will be triggered in each of those events:

Event Description
parcel:deleted parcel not ready for picking; has been deleted
parcel:cancelled parcel parcel ready for picking; has been cancelled
parcel:picked parcel goes from being CREATED to being PICKED
parcel:shipped parcel is labelled and ready to be taken by carrier
parcel:carrier-status:changed parcel transits within the carrier network

Securing your webhook

A webhook creates a potential backdoor on your system, we thus recommend:

Backoff webhook attempts

If your server responds with a HTTP 500 status, our servers will attempt to replay the request up to 3 times: 1, 2, 4 minutes later.

Webhook request

A JSON payload POSTed to your webhook

{
    "event": "parcel:picked",
    "key": "my-app-key",
    "parcel": {
      "id": 673847167,
      "label": "iPhone 7",
      "status": "PICKED",
      "address": {
        "line1": "3 place de la Republique",
        "zip": "69002",
        "city": "Lyon",
        "country": "France",
        "additionalInformation": "code 9898"
      },
      "firstName": "Sophie",
      "lastName": "Martin",
      "deliveryMode": "standard",
      "objectCount": 2,
      "insurance": 250,
      "createdAt": "2015-08-18T16:26:08.000Z",
      "updatedAt": "2015-08-18T16:26:08.000Z"
    }
}

Our systems will issue POST requests to your Webhook URL with these 3 fields in the request body:

Testing your webhooks

Simply use these simple curl commands to try your webhooks -›


// parcel:deleted
curl https://<URL_WEBHOOK> -H 'Content-Type: application/json' \
--data '{ \
    "key":"<API_KEY>", \
    "event":"parcel:deleted", \
    "parcel":{"id":"<CUBYN_ID>","orderRef":"<ORDER_REFERENCE>","status":"CREATED"} \
}'

// parcel:picked
curl https://<URL_WEBHOOK> -H 'Content-Type: application/json' \
--data '{ \
    "key":"<API_KEY>", \
    "event":"parcel:picked", \
    "parcel":{"id":"<CUBYN_ID>","orderRef":"<ORDER_REFERENCE>","status":"PICKED"} \
}'

// parcel:carrier-status:changed
curl https://<URL_WEBHOOK> -H 'Content-Type: application/json' \
--data '{ \
    "key":"<API_KEY>", \
    "event":"parcel:carrier-status:changed", \
    "parcel":{"id":"<CUBYN_ID>","orderRef":"<ORDER_REFERENCE>","status":"CARRIER_DELIVERED"} \
}'

API Reference

Find here all API endpoints available.

Addresses

This is the address model used in Shipper and Parcel objects.

Field Type Details
line1 * string (max length: 35 chars.)
line2 string (max length: 35 chars.)
zip * string city's zip code
city * string city's name
state string required for US
country * string
additionalInformation string any detail (floor, code, ...) needed by the carrier to deliver / messenger to pick. (max length: 35 chars.)

Items

This is the item model used in to specify an object contained in a Parcel.

Field Type Details
count * string Number of items to pick
reference* string SKU of your product

Users

Method Path Description
GET /v2/users Get user currently connected
GET /v2/users/:id Read user details
PUT /v2/users/:id Edit a user

Parcels

Method Path Description
GET /v2/parcels List all your parcels
POST /v2/parcels Create a parcel
GET /v2/parcels/:id Read details of this parcel
PUT /v2/parcels/:id Edit a parcel
DELETE /v2/parcels/:id Delete a parcel non ready for picking
PUT /v2/parcels/:id/cancel Cancel a parcel ready for picking

Attachments

Method Path Body Description
GET /v2/attachments List all your attachments
GET /v2/attachments?filters[parcelId]=:id List all attachments of this parcel
POST /v2/attachments { "parcelId": ":id" } Upload a new attachment on this parcel
GET /v2/attachments/:id Read details of this attachment
DELETE /v2/attachments/:id Delete this attachment

Inbound orders

Method Path Body Description
GET /v2/storage-inbound/orders?filters[status]=:status List an inbound order with given status
GET /v2/storage-inbound/warehouses List all your warehouses
GET /v2/storage-inbound/orders/:orderId Read details of an inbound order with given id
POST /v2/storage-inbound/orders?filters[warehouseId]=:warehouseId {"declaredPackingUnits": 1, "items": [{"productName": "product33", "sku": "er1234" "barcode": "barcode74", "quantity": 1}]} Create an inbound order
DELETE /v2/storage-inbound/orders/:orderId?ownerId=:ownerId Delete an inbound order

Products

Method Path Body Description
GET /v2/product-catalog/products/ List all your products
PUT /v2/product-catalog/products/:productId {"sku":"newSku", "name":"newName"} Update a product

Glossary

Word Definition
sku Unique reference of your product
barcode Physical identification of your product (EAN, IMEI, UPC...)
packing unit Boxes or pallets containing your products in the inbound order
inbound order Group of declared products sent to Cubyn

Guides

Understanding Cubyn statuses

Parcels and their Attachments all have a status field.

Parcel statuses

Status Stakeholder Description
CREATED Shipper Parcel has been created and is still editable. The status remains CREATED in two scenarios: 1) The parcel is in error, for example missing stock, unknown external reference, error in address or 2) the parcel is well-validated and ready to be picked
PICKED Cubyn Parcel has been picked by an operator from Cubyn picking team. At this point of the process, the parcel can no longer be cancelled
SHIPPED Cubyn Parcel is now in carrier hands
CARRIER_IN_TRANSIT Carrier Parcel is on the way, transitting within carrier network
CARRIER_OUT_FOR_DELIVERY Carrier Carrier is ready to deliver the parcel
CARRIER_FAILED_ATTEMPT Carrier Carrier attempted to deliver the parcel but will try again
CARRIER_DELIVERED Carrier (final status) Parcel delivered successfully
CARRIER_EXCEPTION Carrier (final status) Parcel not delivered / returned to shipper

Parcel cancellation statuses

Status Description
NONE Default parcel cancellation status
IN_PROGRESS Parcel is in cancellation
SUCCEEDED Parcel has been cancelled
FAILED An error occured while cancelling the parcel

Attachment statuses

Status Description
IN_PROGRESS Attachment is being downloaded or processed by our servers
SUCCESS Attachment is ready to be printed
PRINTED Attachment has been printed and packed in your parcel

Parcel attachments

REQUEST (curl)

curl https://api.cubyn.com/v2/attachments \
    -H 'X-Application: my-app-key' \
    -F name=my-file.pdf \
    -F parcelId=983264786 \
    -F 'file=@/path/to/my-file.pdf'

RESPONSE

{
    "id":923743672,
    "type":"OTHER",
    "status":"SUCCESS",
    "name":"my-file.pdf",
    "file": {
        "url": "https://attachment.domain/path/to"
    },
    "pageCount":1,
    "fileSize":24218,
    "createdAt":"2016-08-23T15:27:54.000Z",
    "updatedAt":"2016-08-23T15:27:54.000Z"
}

Parcel attachments are a convenient way to have Cubyn print and pack documents in your parcels. e.g. Invoices, User guides, Ads, ...

Maximum allowed size: 2Mo. Only PDF files are supported.

You can also list and delete attachments as described in API Reference.

Endpoint

POST /v2/attachments

Tracking page

Cubyn offers a unified tracking page that is common to every carrier we support. We highly recommend using it:

To do so:

1. Build your Cubyn tracking number

CUB{{your parcel id}}

2. Build your Cubyn tracking page

http://track.cubyn.com/{{your tracking number}}

Handling Cubyn relay

Cubyn supports relay as a third delivery mode which requires a valid relayPickupRef to be set on the parcel. We recommend using our iframe to facilitate the Relay integration into your own systems.

If you do not want to integrate our iframe, please be aware that our relay offer is currently routed on Mondial Relay's network, so relayPickupRef needs to be a valid Mondial Relay pickup point ID. Check Mondial Relay Widget to have a map of pickup points.

Important note: we only support french pickup points.

https://app.cubyn.com/tools/relay-iframe/index.html?address=[...]&callback=[...]

Field Type Details
address * string Remember to URL encode this value Address must be formatted as follows: [line1] [line2] [zip] [city] [country]
callback * string Remember to URL encode this value That URL will be given query parameters telling which pickup point the user has selected.
Field Type Details
id string This is the one and only ID you need to set on parcel.relayPickupRef.
name string Name of the pickup point
image string
openinghours string Example: MON.0700.1830-TUE.0700.1830-WED.0700.1830...
street string
city string
zip string
country string

No page reload

shop.com/cart

<!-- This is your main checkout tunnel page. -->

<!-- You can include that iframe inside a popup for instance-->
<iframe src="https://app.cubyn.com/tools/relay-iframe/index.html?address=[...]&callback=http%3A%2F%2Fshop.com%2Fcallback">
</iframe>

<script type="text/javascript">
    window.setRelay = function(info) {
        console.log('Yeay — relay selected:', info);
    }
</script>

shop.com/callback

<!-- Once the relay is selected, the iframe will redirect to this page. -->

<script type="text/javascript">
    // call parent (out of iframe, but on same domain so that works)
    window.parent.setRelay(parseGetParams());

    function parseGetParams() {
        var vars = window.location.search.substring(1).split('&');
        var getPrms = {};
        for (var i = 0; i < vars.length; i++) {
            var pair = vars[i].split('=');
            getPrms[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
        }
        return getPrms;
    }
</script>

Our iframe relies on a http redirect to give you back results, thus (re)loading a new page. You can avoid this redirect by loading the map inside an iframe (in a popup for instance). Beware that cross domain scripting is not allowed. Here is a simple scenario to illustrate how to overcome this:

Using Cubyn Sandbox

Cubyn provides a Sandbox environment where you will be able to test your integration before going live. Ask us for a sandbox account here onboarding@cubyn.com.

Endpoint

https://apisandbox.cubyn.com/v2

Cubyn customer interface URL

https://shippersandbox.cubyn.com

Handling errors

When PUTing or POSTing - in case of a validation error, our API will describe each erroneous field. Here is an example:

 

REQUEST (curl)

curl https://api.cubyn.com/v2/users/124288383 \
    -X PUT \
    -H 'X-Application: my-app-key' \
    -H 'Content-Type: application/json' \
    --data '{"email":"wrongemail.com","password":"mypassword"}'

RESPONSE

{
    "errors": [
        {
            "field": "email",
            "message": "Validation isEmail failed"
        }
    ],
    "message": "Validation error: Validation isEmail failed",
    "type": "ValidationError"
}
Code Type Description
400 BadRequestError Often missing a required parameter
400 ValidationError Some field is badly formatted or has validation errors
404 ResourceNotFoundError The requested resource does not exist
403 ForbiddenError You cannot perform that action on this resource
413 TooBigFileError The file you uploaded is too big
50X ServerError Oops - that's for us.