Introduction
Welcome to the Cubyn API! This API is organized around REST over HTTPS.
To implement the Cubyn API on your website, please refer to Connecting the Cubyn API to get your API application Key.
If you need a Sandbox environment to test the connection, please contact us at integrations@cubyn.com and refer to 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": "My API application",
"createdAt": "2015-08-19T10:18:13.000Z",
"updatedAt": "2015-08-19T10:18:14.000Z"
},
"user": {
"id": 706293859,
"firstName": "Jane",
"lastName": "Doe",
"phone": "0606060606",
"createdAt": "2015-08-19T10:18:13.000Z",
"updatedAt": "2015-08-19T10:18:13.000Z",
"email": "jane.doe@acme.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 1: you declare your WIO (products, product quantities and shipment details)
STEP 2: you can track your inventory in real-time once your products are stored in our warehouse
STEP 3: you create parcels that we fulfill (picking, packing and delivery to final recipient)
STEP 4: you are notified in real-time on your orders statuses
Step | Description | API METHOD |
---|---|---|
STEP 1 | Send inventory | POST /v2/storage-inbound/orders?filters[warehouseId]=:warehouseId |
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
1. Declare products & products quantities for your WIO
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 ' {
"items": [{
"productName": "product33",
"sku": "mySku_product33",
"barcode": "EAN_product33",
"quantity": 4
}]
}'
RESPONSE
{
"id": "e4f007ae-4412-4f90-bc17-a7aa2679b7a6",
"pid": "290833",
"declaredItems": 4,
"status": "CREATED"
}
POST /v2/storage-inbound/orders?filters[warehouseId]=:warehouseId
warehouseId | Corresponding warehouse |
---|---|
3628042 | France |
193543585 | Spain |
Field | Type | Details |
---|---|---|
items | Array | Array of items in the inbound order |
items.$.productName* | String | Name of the product |
items.$.sku* | String | Unique reference of the product |
items.$.barcode* | String | Physical identification of the product (EAN, IMEI, UPC...) |
items.$.quantity* | Integer | Quantity of objects per item |
items.$.lotNumber | String | Lot identification, set to WIO ${WIO id} by default |
items.$.lotDate | Date | Lot date, set to null by default. If set to null, the lot date will take the value of the WIO reception date once received at the warehouse |
items.$.customPickingStrategyForProduct | Boolean | If you want to activate lot tracking, including custom picking strategy (FIFO, LIFO) for a new SKU, false by default |
Golden rules for an inbound order creation :
Fields
SKU
,productName
,barcode
andquantity
are mandatory.Within an inbound order, one
barcode
cannot be used for different SKUs.One SKU can have several barcodes (example: different IMEI for a same mobile SKU).
Fields
lotNumber
,lotDate
andcustomPickingStrategyForProduct
are only needed for merchants using lot management features.
This route returns informations about the created inbound order. Here are the most important :
Field | Type | Details |
---|---|---|
id | String | Id used for other API calls needing this inbound order |
declaredItems | Number | Number of items declared in the inbound order |
status | String | Status of the inbound order |
2. Declare shipment details for your WIO
Our Delivery Document is a scannable document that you need to attach on every box or pallet you send within your WIO. It enables our receiving team to easily identify your goods. It is highly recommended that you use this if you never used carrier tracking number before.
REQUEST (curl) - DELIVERY DOCUMENT TRACKING (1 tracking = N boxes/packing units)
curl --request POST \
--url 'https://api.cubyn.com/v2/storage-inbound/orders/batch-deliveries' \
--header 'content-type: application/json;charset=UTF-8' \
--header 'x-application: my-app-key' \
--data '{
"orderId": "e4f007ae-4412-4f90-bc17-a7aa2679b7a6",
"deliveries": [
{
"carrierName": "Other carrier",
"declaredPackingUnits": 2,
"estimatedReceptionDate": "2021-12-31T23:00:00Z"
}
]
}'
RESPONSE - DELIVERY DOCUMENT TRACKING (1 tracking = N boxes/packing units)
[
{
"warehouseId": 193543585,
"orderId": "1907ba12-e2b2-4eaa-8587-83fac21b421b",
"carrierName": "Other carrier",
"estimatedReceptionDate": "2021-12-31T23:00:00.000Z",
"declaredPackingUnits": 2,
"carrierTrackingId": "23eaeabb-7245-4b8c-8d89-2290368e47ab",
"id": "ea7dd22a-1201-4dba-b360-a3d891e65cc7",
"reference": "23eaeabb-7245-4b8c-8d89-2290368e47ab",
"status": "CREATED",
"createdAt": "2021-08-02T11:55:47.000Z",
"updatedAt": "2021-08-02T11:55:47.000Z",
"receivedAt": null,
"receivedPackingUnits": 0,
"storedItems": 0
}
]
REQUEST (curl) - CARRIER TRACKING (1 tracking = 1 box/packing unit)
curl --request POST \
--url 'https://api.cubyn.com/v2/storage-inbound/orders/batch-deliveries' \
--header 'content-type: application/json;charset=UTF-8' \
--header 'x-application: my-app-key' \
--data '{
"orderId": "e4f007ae-4412-4f90-bc17-a7aa2679b7a6",
"deliveries": [
{
"carrierName": "UPS",
"carrierTrackingId": "1Z3736373638393837",
"declaredPackingUnits": 1,
"estimatedReceptionDate": "2021-12-31T23:00:00Z"
},
{
"carrierName": "UPS",
"carrierTrackingId": "1Z3736373638393838",
"declaredPackingUnits": 1,
"estimatedReceptionDate": "2021-12-31T23:00:00Z"
}
]
}'
RESPONSE - CARRIER TRACKING (1 tracking = 1 box/packing unit)
[
{
"warehouseId": 193543585,
"orderId": "e4f007ae-4412-4f90-bc17-a7aa2679b7a6",
"carrierTrackingId": "1Z3736373638393837",
"carrierName": "UPS",
"estimatedReceptionDate": "2021-12-31T23:00:00.000Z",
"declaredPackingUnits": 1,
"id": "a73e2afc-5403-4312-af6b-423a71d42964",
"reference": "1Z3736373638393837",
"status": "CREATED",
"createdAt": "2021-08-02T11:52:08.000Z",
"updatedAt": "2021-08-02T11:52:08.000Z",
"receivedAt": null,
"receivedPackingUnits": 0,
"storedItems": 0
},
{
"warehouseId": 193543585,
"orderId": "e4f007ae-4412-4f90-bc17-a7aa2679b7a6",
"carrierTrackingId": "1Z3736373638393838",
"carrierName": "UPS",
"estimatedReceptionDate": "2021-12-31T23:00:00.000Z",
"declaredPackingUnits": 1,
"id": "4b4da10c-a0ff-47f9-8af3-a8b5a9627515",
"reference": "1Z3736373638393838",
"status": "CREATED",
"createdAt": "2021-08-02T11:52:08.000Z",
"updatedAt": "2021-08-02T11:52:08.000Z",
"receivedAt": null,
"receivedPackingUnits": 0,
"storedItems": 0
}
]
POST /v2/storage-inbound/orders/batch-deliveries
Field | Type | Details |
---|---|---|
orderId* | String | ID of the inbound order to declare shipment details for |
deliveries* | Array | Array of shipments (to declare details for each) |
deliveries.$.carrierName* | String | Supported carrier name: 'Other carrier' for Cubyn Delivery Document |
deliveries.$.carrierTrackingId* | String | Carrier tracking ID of the delivery |
deliveries.$.declaredPackingUnits* | Number | Number of boxes in your shipment |
deliveries.$.estimatedReceptionDate | Date | Estimated reception date of the delivery at the warehouse |
POST /v2/storage-inbound/orders/batch-deliveries
Field | Type | Details |
---|---|---|
orderId* | String | ID of the inbound order to declare shipment details for |
deliveries* | Array | Array of shipments (to declare details for each) |
deliveries.$.carrierName* | String | Supported carriers: 'UPS' / 'DHL' |
deliveries.$.carrierTrackingId* | String | Carrier tracking ID of the delivery provided by UPS / DHL |
deliveries.$.declaredPackingUnits* | Number | Should equal 1 in this mode (1 box = 1 tracking) |
deliveries.$.estimatedReceptionDate | Date | Estimated reception date of the delivery at the warehouse |
Deliveries allow warehouse operators to know which incoming order is associated with each package received. For this reason, carrier tracking IDs must be indicated for each delivery.
This route returns the list of created deliveries and their informations. Here are the most important :
Field | Type | Details |
---|---|---|
$.id | String | Id of the delivery |
$.status | String | Status of the delivery |
$.orderId | String | Id of the inbound order associated to the delivery |
$.carrierTrackingId | String | Carrier tracking ID of the delivery |
$.carrierName | String | Name of the delivery carrier |
$.estimatedReceptionDate | Date | Estimated reception date of the delivery at the warehouse |
$.declaredPackingUnits | Number | Number of packing units declared in the delivery |
3. Download delivery document
To be able to send your inventory to Cubyn's warehouse you need to download your delivery document.
Downloading your delivery document comes in two step:
REQUEST (curl) - Get your order's deliveries
curl --request GET \
--url 'https://api.cubyn.com/v2/storage-inbound/deliveries?filters[orderId]=3d8fe1a4-41ba-4649-9981-6cf01f26a09b' \
--header 'x-application: my-app-key'
RESPONSE (curl) - Get your order's deliveries
[
{
"id": "fd16cbc2-8392-49e6-8253-5cfcc026ed93",
"orderId": "3d8fe1a4-41ba-4649-9981-6cf01f26a09b",
"status": "CREATED",
"reference": "77b3d5d1-450e-4b03-b829-34b9de2849da",
"warehouseId": 3628042,
"createdAt": "2023-06-16T12:35:15.000Z",
"updatedAt": "2023-06-16T12:35:15.770Z",
"receivedAt": null,
"carrierName": "Other carrier",
"carrierTrackingId": "77b3d5d1-450e-4b03-b829-34b9de2849da",
"fileKey": null,
"estimatedReceptionDate": "2023-06-29T22:00:00.000Z",
"receivedPackingUnits": 0,
"completedPackingUnits": 0,
"receivedItems": 0,
"storedItems": 0,
"declaredPackingUnits": 1,
"deliveryMode": "STANDARD",
"totalWeight": null,
"boxHeight": null,
"boxLength": null,
"boxWidth": null,
"weight": null
}
]
GET /v2/storage-inbound/deliveries
Field | Type | Details |
---|---|---|
filters.orderId* | String | Your inbound order id. |
The previous endpoint allowed you to fetch your deliveries's ids. You can now use it to fetch your documents. This will give you an url to download the PDF file generated.
REQUEST (curl) - Get your deliveries's documents
curl --request POST \
--url 'https://api.cubyn.com/v2/storage-inbound/deliveries/fd16cbc2-8392-49e6-8253-5cfcc026ed93/document' \
--header 'x-application: my-app-key'
RESPONSE (curl) - Get your deliveries's documents
{
"url": "https://s3-eu-west-1.amazonaws.com/cubyn.staging.vault/deliveries/fd16cbc2-8392-49e6-8253-5cfcc026ed93/liyjz9ul008bba91c4etu7p4.pdf?AWSAccessKeyId=AKIASLTUFOJUFNBXHL52&Expires=1686920137&Signature=7nB3ef9qHBunxjyoi82NTpb1g%2Bg%3D"
}
POST /v2/storage-inbound/deliveries/:deliveryId/document
Field | Type | Details |
---|---|---|
deliveryId* | String | Your delivery id. |
Response is an url to your delivery document's PDF.
4. Validate your order
At this point your order should still be displayed as DRAFT
in shipper app. The status returned by the first endpoint is CREATED
.
To be properly handled an order needs to be validated.
Once you have properly downloaded your delivery documents you can validate your order before sending it. To do so you can use the following endpoint.
REQUEST (curl) - Validation of your inbound order
curl --request POST \
--url 'https://api.cubyn.com/v2/storage-inbound/orders/3d8fe1a4-41ba-4649-9981-6cf01f26a09b' \
--header 'content-type: application/json;charset=UTF-8' \
--header 'x-application: my-app-key' \
--data '{
"status": "VALIDATED"
}'
RESPONSE - Validation of your inbound order
{
"updated": 1
}
POST /v2/storage-inbound/orders/:orderId
Field | Type | Details |
---|---|---|
status* | String | VALIDATED to put the order as none-draft. CREATED to keep it as draft. |
STEP 2: Track inventory
Track inventory
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v2/inventory/products/ \
--header 'x-application: my-app-key'
RESPONSE
{
"products": [
{
"name": "Product 0",
"reference": "product_0",
"merchantId": 134362594,
"type": "STANDARD",
"isUnknown": false,
"isUnscannable": false,
"isCase": false,
"isCasePacked": false,
"scubId": "33e5266e-e38f-4aa0-8dd9-440b4ce89336",
"productId": "f58bef17-10d2-4a20-81d3-d7a75d5046c1",
"warehouseGroupKey": "TOTAL",
"availableQuantity": 0,
"damagedQuantity": 0,
"reservedQuantity": 0
}
]
}
This endpoint for single warehouse merchants:
GET /v2/inventory/products?productId=:productId
This endpoint will return 1 product
This endpoint for multi warehouse merchants:
for warehouseGroupKeys
leave FR, ES
for productId
, replace it with your product id
GET /v2/inventory/products?warehouseGroupKeys[]=FR&warehouseGroupKeys[]=ES&productId=:productId
This endpoint will return 1 product twice, with stocks aggregated by warehouse groups.
If you are multi warehouse merchant use these filters ?warehouseGroupKeys[]=FR&warehouseGroupKeys[]=ES
in each API call
This endpoint for single warehouse merchants:
GET /v2/inventory/products
This endpoint for multi warehouse merchants:
GET /v2/inventory/products?warehouseGroupKeys[]=FR&warehouseGroupKeys[]=ES
This endpoint gets a maximum of 1000 products. To get all your products you can use the limit and offset parameters, for instance if you have 2200 products:
Endpoint | Description |
---|---|
/v2/inventory/products |
returns 1st 1000 products |
/v2/inventory/products?limit=1000&offset=1000 |
returns next 1000 products |
/v2/inventory/products?limit=200&offset=2000 |
returns next 200 products |
Using filters you can filter out the products you are looking for:
Endpoint | Description |
---|---|
/v2/inventory/products?query=iphone |
returns array of item(s) that has iphone value in sku or name fields |
/v2/inventory/products?types[]=STANDARD |
returns only standard products you can fetch products with the following types: STANDARD, BUNDLE, VIRTUAL, DAMAGED |
/v2/inventory/products?isCase=true |
returns array of item(s) that are cases |
/v2/inventory/products?isCasePacked=true |
returns array of item(s) that are case packed items |
/v2/inventory/products?isUnknown=true |
returns array of item(s) that are unknown |
/v2/inventory/products?isUnscannable=true |
returns array of item(s) that are unscannable |
Track barcodes
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v2/inventory/product-sku/myproductId1 \
--header 'x-application: my-app-key'
RESPONSE
[
{
"skuIds": [],
"barcodeSet": [
"L8A2PZJ91K7J9D0062EIMFMZ"
],
"quantity": 794
},
{
"skuIds": [],
"barcodeSet": [
"L8A2PZJ91K7J9D0062EIMFMZ4"
],
"quantity": 0
}
]
To fetch the barcodes and their quantities for a given product use the following
GET /v2/inventory/product-sku/{productId}
This endpoint will return an array of objects containing the barcode set and its quantity.
For classic cases, barcodeSet
always contains only 1 element.
Field skuIds will only be filled if your inventory is handled by our automated warehouse.
Track lots
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v2/inventory/lots?productId=58f0ef85-7006-4488-adca-dbbfa3d79fea&withQuantity=true&aggregatedBy=lotNumberLotDateProductId&limit=20&offset=0&sort[lotDate]=asc \
--header 'x-application: my-app-key'
RESPONSE
{
"lots":[
{
"merchantId":369502585,
"productId":"58f0ef85-7006-4488-adca-dbbfa3d79fea",
"lotId": "WIO_123_2022-09-23_58f0ef85-7006-4488-adca-dbbfa3d79fea",
"lotDate":"2022-09-23T00:00:00.000Z",
"lotNumber":"WIO 123",
"status":null,
"availableQuantity":6,
"damagedQuantity":1,
"aggregatedBy": "lotNumberLotDateProductId"
}
]
}
Use this endpoint to get a list of lots
GET /v2/inventory/lots
This endpoint gets a maximum of 1000 lots. To get all your lots you can use the limit and offset parameters, for instance if you have 2200 lots:
Endpoint | Description |
---|---|
/v2/inventory/lots?limit=1000 |
returns 1st 1000 lots |
/v2/inventory/lots?limit=1000&offset=1000 |
returns next 1000 lots |
/v2/inventory/lots?limit=1000&offset=2000 |
returns next 200 lots |
Using filters you can filter out the lots you are looking for:
Endpoint | Description |
---|---|
/v2/inventory/lots?productId=58f0ef85-7006-4488-adca-dbbfa3d79fea |
returns array of lots that belongs to a given product. |
/v2/inventory/lots?withQuantity=true |
returns only lots with either available or damaged quantity greater than 0. |
/v2/inventory/lots?query=WIO 123 |
returns lots with matching lot numbers. |
/v2/inventory/lots?aggregatedBy=lotNumberLotDateProductId |
returns lots aggregations by lotNumber, lotDate and productId. By default none-aggregated lots are returned. |
Using sorting you can sort your lots by ascending or descending order.
Endpoint | Description |
---|---|
/v2/inventory/lots?sort[lotDate]=asc |
returns array of lots sorted by lot date ascending. |
/v2/inventory/lots?sort[lotDate]=desc |
returns array of lots sorted by lot date descending. |
Webhooks
You can use webhooks to subscribe to events related to your stock.
By providing us with a webhook, you will be notified everytime one of your product's quantities changes.
When creating an “API Cubyn
” application, you can provide a URL to subscribe to webhooks. Cubyn will post stock updates related to your product to this URL.
Note that if you create multiple “API Cubyn
” applications, each with a different webhook URL, Cubyn will post all stock updates to every application with stock:updated
events enabled.
Enabling webhooks
To activate webhooks for your account, configue on shipper.cubyn.com applications:
- URL of the Webhook
- Events you want to subscribe to (see below)
Stock webhook event types
Only one type of event related to stock exists currently. Others are linked to parcels.
Event | Description |
---|---|
stock:updated |
Stock have change for one of your product. |
Wehbook request
A JSON payload
POST
ed to your webhook
{
"sku": "product_2",
"ownerId": 369502585,
"reserved": 1,
"available": 81,
"warehouse": "TOTAL",
"applicationId": 488978068
}
Our systems will issue POST requests to your Webhook URL with these fields in the request body:
sku
: The sku of your updated product.ownerId
: Your Cubyn's merchant ID.reserved
: Reserved quantity, stock is still in our warehouse but not available for sale anymore.available
: Stock is still available and already in our warehouse.warehouse
:TOTAL
|FR
. Quantity should be the same for both as Cubyn only have a warehouse in France at the moment. When a new warehouse is open, example in spain withES
, you will be able to know your total aggregated stock, or your stock per country. You will receive one event per country. It means that for one product updated in France, you will receive two events, one forTOTAL
and one forFR
.application
: The identifier of your application. Useful if you have multiple applications pointing to the same webhook URL.
Track inventory (legacy)
curl --request GET \
--url https://api.cubyn.com/v2/product-catalog/products/ \
--header 'x-application: my-app-key'
RESPONSE
[
{
"id": "e7fe10a9-0fcf-4810-8def-b6b53849616b",
"ownerId": 161181051,
"sku": "bundle phone 1",
"sanitizedSku": "BUNDLE PHONE 1",
"name": "Bundle test phone",
"isVirtual": false,
"isBundle": true,
"isUnknown": false,
"createdAt": "2020-05-15T16:49:17.000Z",
"updatedAt": "2020-05-15T16:49:17.000Z",
"scubsIds": [
"7ceade20-7638-4713-924c-c94eab12c4fb",
"9216cdaa-3d1f-4a9c-ab04-2e3ef487fd3a"
],
"stock": {
"hadStockInbounded": false,
"quantityAvailable": 4,
"quantityOutbounded": 0,
"quantityInbounding": 0,
"quantityOutbounding": 0,
"quantityDamaged": 5
},
"requiresItemIdentifiers": null,
"externalReferences": [
{
"value": "BUNDLE PHONE 1",
"rawValue": "bundle phone 1"
}
]
}
]
GET /v2/product-catalog/products/{product_id}
This endpoint will return 1 product
GET /v2/product-catalog/products
This endpoint gets a maximum of 1000 products. To get all your products you can use the offset parameter, for instance if you have 2300 products:
Endpoint | Description |
---|---|
/v2/product-catalog/products |
returns first 1000 products. |
/v2/product-catalog/products?offset=1000 |
returns next 1000 products. |
/v2/product-catalog/products?offset=2000 |
returns next 300 products since we fetched all of our products. |
Using filters you can filter out the products you are looking for, few examples:
Endpoint | Description |
---|---|
/v2/product-catalog/products?filters[sku]=an_item |
returns array of item(s) that has an_item value in sku field |
/v2/product-catalog/products?filters[isBundle]=1 |
returns array of item(s) that are a bundle boolean values true/false values are represented as 1/0 |
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 \
}, \
{ \
"reference":"product_name_2", \
"count":2 \
} \
], \
"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"
}
- You can create parcels by providing recipient information and list of products (SKU x quantity)
- You can cancel a parcel while its status is still
CREATED
- Parcels cannot be updated, if you need to make a change, cancel the first parcel then create a new one
- Every parcel is validated according to available stock in warehouse and address standards
- Once a parcel is validated, its status is changed to
PICKED
(you cannot edit or cancel a parcel in this status)
POST /v2/parcels
If you need a batch endpoint for creating parcels, please contact help@cubyn.com.
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 , standard+ , express , 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": 297706966,
"batchId": "cafedd5e-e824-46c3-b6cc-3e077aa00846",
"type": "SHIPMENT",
"trackingId": "CUB297706966",
"status": "PICKED",
"aside": false,
"address": {
"line1": "31 rue du Pere Corentin",
"line2": "",
"zip": "75014",
"city": "Paris",
"state": "",
"country": "FR",
"additionalInformation": ""
},
"firstName": "Robin",
"lastName": "Dubois",
"organizationName": "cubyndemo2",
"deliveryMode": "express",
"deliverySigned": false,
"objectCount": 1,
"isAdvalorem": false,
"orderRef": "91251234",
"createdAt": "2019-12-11T18:11:29.000Z",
"updatedAt": "2019-12-11T18:11:29.000Z",
"validationStatus": "INFO",
"cancellationStatus": "NONE",
"shipperId": 427380376,
"selfReturnActivated": true,
"deliverySaturday": false,
"isAnonymized": true,
"isStorage": true,
"isRemoval": false
}
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.
When creating an “API Cubyn
” application, you can provide a URL to subscribe to webhooks. Cubyn will post tracking information that relate to parcels created via this application to the provided URL.
Note that if you create multiple “API Cubyn
” applications, each with a different webhook URL, the tracking information provided to each of the URLs will only relate to parcels created via the application associated with such URL. If you provide the same URL for all “API Cubyn
” applications, tracking information relating to parcels created with any of such applications will be provided to such URL - the API key in the payload will help determine to which application a parcel relates.
Enabling webhooks
To activate webhooks for your account, configue on shipper.cubyn.com applications:
- URL of the Webhook
- Events you want to subscribe to (see below)
Webhook event types
A webhook call will be triggered in each of those events:
Event | Description |
---|---|
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:
- providing us with an HTTPs webhook URL
- comparing your API key: every request will contain your api key within its body. Use it to make sure of caller's identity.
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
POST
ed to your webhook
{
"event": "parcel:shipped",
"key": "my-app-key",
"parcel": {
"address": {
"city": "Untesh",
"zip": "14150",
"country": "FR",
"additionalInformation": "",
"line2": "",
"line1": "10 Rue de Varnishold",
"state": ""
},
"aside": false,
"barcode": "2471690149",
"batchId": "f95a22b9-2e72-414a-8478-f12677410d6",
"cancellationStatus": "NONE",
"carrier": "carrier-colisprive",
"carrierTrackingId": "W5000140213462150",
"createdAt": "2022-02-09T18:39:05.000Z",
"collectId": 897355555,
"customsCategory": "COMMERCIAL",
"customsDescription": "produit cosmétique",
"customsHsCode": "33049900",
"customsOriginCountry": "FR",
"deliveryMode": "standard",
"deliverySaturday": false,
"deliverySigned": false,
"email": "val.sorna@gmail.com",
"firstName": "Vaelin",
"id": 817427867,
"insurance": 93.06,
"isAdvalorem": false,
"isAnonymized": false,
"isRemoval": false,
"isStorage": true,
"items": [
{
"count": 3,
"reference": "2346386383673"
},
{
"count": 1,
"reference": "iphone-XR"
}
],
"label": "Le 6th order",
"lastName": "Sorna",
"objectCount": 1,
"orderRef": "347-4957372-9234150",
"originalValue": "92",
"organizationName": "WOLFRNR & CO",
"phone": "0623333450",
"pickedAt": "2022-02-10T05:28:52.000Z",
"qrCode": "it.2.e814c8f0-3c16-4403-9faf-42765qwedfwefv86.bag",
"relayPickupRef": "TR456754",
"selfReturnActivated": false,
"shipperId": 834587545,
"status": "SHIPPED",
"trackingId": "CUB817427867",
"type": "SHIPMENT",
"updatedAt": "2022-02-10T08:36:01.244Z",
"validationStatus": "INFO",
"value": "92",
"viaApplicationId": 198914599,
"volumetricWeight": 1.8538,
"warehouseId": 3628042,
"weight": 2.82,
}
}
Our systems will issue POST requests to your Webhook URL with these 3 fields in the request body:
parcel
: take special attention to theparcel.status
key
: your API key, provided here as an authentication mechanismevent
: the original event which triggered the webhook
Testing your webhooks
Simply use these simple curl commands to try your webhooks -›
Try your webhook with the two following parcel events
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"} \
}'
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"} \
}'
STEP 5: Create claims
REQUEST (curl)
curl https://api.cubyn.com/v2/claims \
-H 'X-Application: my-app-key' \
-H 'Content-Type: application/json' \
--data '{ \
"type":"PARCEL_NEVER_RECEIVED", \
"entityType":"PARCEL", \
"entityId":"123123", \
"source":"RECIPIENT", \
"resolutionTypeSelected": "RESHIP", \
"attachments": [ \
{ \
"type": "ITEM_LABEL", \
"fileKey": "https://attachment.domain/path/to", \
}, \
{ \
"type": "ITEM_DAMAGED", \
"fileKey": "https://attachment.domain/path/to", \
} \
], \
"concerns": [ \
{ \
"entityId":"product_id_1", \
"entityType": "PRODUCT", \
"type": "MERCHANDISE", \
"quantity": "1" \
}, \
{ \
"entityId":"product_id_2", \
"entityType": "PRODUCT", \
"type": "MERCHANDISE", \
"quantity": "2" \
} \
], \
"requester":{ \
"firstName": "Sophie", \
"lastName": "Martin", \
"email":"test@cubyn.com", \
"organizationName":"CUBYN", \
"language":"FR", \
"bankInfo": { \
"firstName": "Sophie", \
"lastName": "Martin", \
"iban":"GB33BUKB20201555555555", \
"bic":"GEBABEBB", \
"country":"FR", \
}, \
} \
}'
RESPONSE (Created claim ID)
"9410f580-3737-49f4-bfca-a23d661420cf"
- You can create claim for parcel / sku(product)
- Required attachments per claim type:
- - Order is late
- - - No attachments required
- - Parcel never received / Parcel missing product
- - - Commercial invoice
- - Damaged parcel
- - - Commercial invoice
- - - Photo of damaged item
- - - Photo of shipping label
POST /v2/claims
Field | Type | Details |
---|---|---|
type * |
Enum<string> |
Type of the claim. For more details : Claim types |
source * |
Enum<string> |
Source is the initiator of the request. For more details : Sources |
entityType * |
Enum<string> |
Type of the entity. For more details : Entity types |
entityId * |
string |
Entity ID (Should be id of entity type (id of parcel / id of sku)) |
resolutionTypeSelected * |
Enum<string> |
Resolution type selected by recipient. For more details : Resolution types |
attachments |
[<ClaimFile>] |
Array of attachments that are uploaded by posting files (Please see Claim file) |
concerns |
[<Concern>] |
Array of items (SKUs/products) that has issues contained in this parcel (For more details : Concerns) |
requester |
<Requester> |
Only for CONSUMER claims - details of consumer, that is creating a claim (For more details : Requesters) |
STEP 6: Track claims
REQUEST (curl)
curl https://api.cubyn.com/v1/claims \
-H 'X-Application: my-app-key'
RESPONSE
[ { "id": "d6186a3c-b037-4650-9f1e-56f2ad410d10", "type": "PARCEL_RECEIVED_DAMAGED", "attachments": [{ "id": "33bbafcc-7e55-4d8f-a90f-a5275201f6d4", "incidentId": "fd9c6662-541c-49e1-9a37-21151a13f891", "type": "COMMERCIAL_INVOICE", "fileKey": "/kvs1gu32000ifdexample.pdf", "url": "https://aws/path/to/file", "createdAt": "2021-11-09T11:57:33.000Z", "updatedAt": "2021-11-09T11:57:33.000Z", }], "concerns": [{ "id": "MERCHANDISE|0347b8d0-8d4a-5c0a-8eaf-0bca15c94bc6", "incidentId": "959516f1-c907-486d-2e18-d7aa3355983a", "entityId": "0347b8d0-8d4a-4c0a-8eaf-0bca15c94bc1", "entityType": "ITEM", "type": "MERCHANDISE", "quantity": 1 "createdAt": "2021-07-02T10:13:52.000Z", "updatedAt": "2021-07-02T10:13:52.000Z", }], "status": "REJECTED", "refundStatus": "REJECTED", "source": "RECIPIENT", "ownerId": 339, "entityId": "889768785", "entityType": "PARCEL", "resolutionTypeApplied": "REFUND", "refundId": 1, "shippingFeesAmount": 50, "merchandiseValue": 20, "rejectedReason": [{ "key": "PARCEL_DELIVERED_ON_TIME" }], "relatedShipperId": 608838005, "reshipParcelId": null, "decidedToRefundAt": "2021-11-24T11:37:31.000Z", "requester": { "id": 339, "firstName": "Sophie", "lastName": "Martin", "organizationName": "CUBYN", "email": "test@cubyn.com", "language": "FR", "createdAt": "2021-11-24T11:37:31.000Z", "updatedAt": "2021-11-24T11:37:31.000Z", }, "createdAt": "2021-11-24T11:37:31.000Z", "updatedAt": "2021-11-24T11:37:36.000Z", } ]
- You can get list of your claims
- Some of the fields can only be requested if you have specific rights
GET /v2/claims
Field | Type | Details |
---|---|---|
id |
string |
id of claim |
type |
Enum<string> |
Type of the claim. For more details : claim types |
attachments |
[<ClaimFileRetrieve>] |
Array of attachments (see Attachments) |
concerns |
[<Concern>] |
Array of items (SKUs/products) that has issues contained in this parcel (see Concerns) |
status |
Enum<string> |
Status of the claim (Statuses) |
refundStatus |
Enum<string> |
Refund status of the claim (Refund statuses) Applicable when resolution type is REFUND |
ownerId |
string |
Owner id (requester id for recipient and shipper id for shipper) id should refer to provided source Sources |
source |
Enum<string> |
Source is the initiator of the request. For more details : Sources |
entityId |
string |
Entity ID (Should be id of entity type (id of parcel / id of sku)) |
entityType |
Enum<string> |
Type of the entity. For more details : Entity types |
resolutionTypeApplied |
Enum<string> |
Resolution type applied by CUBYN. For more details : Resolution types |
decidedToRefundAt |
date |
Date when CUBYN has made a decision to REFUND |
refundId |
number |
Refund ID that is set to claim when it is going to be billed |
shippingFeesAmount |
number |
Amount in % of shipping fee |
merchandiseValue |
number |
Amount to be refunded in € |
rejectedReason |
[<{ "key": Enum<string> }>] |
Reason why claim was rejected |
relatedShipperId |
string |
Shipper id for RECIPIENT claim |
reshipParcelId |
string |
Parcel ID that is created for RESHIP claim (new re-ship parcel Id) |
requester |
<Requester> |
Requester details (see Requester) |
updatedAt |
date |
"2020-01-01T00:00:00.000Z" |
createdAt |
date |
"2020-01-01T00:00:00.000Z" |
STEP 7: Update claim
REQUEST (curl)
curl --location --request POST 'https://api.playship.co/v1/claims-add-attachment' \
-H 'X-Application: my-app-key' \
-H 'Content-Type: application/json' \
--data-raw '{
"incidentId": "eb68281c-d82a-4c1e-bb7b-660b0ae630c6",
"attachments": [
{ "fileKey": "/lbdqus1y000a0064a89ehzlx.pdf", "type": "IDENTIFICATION_DOCUMENT" }
]
}'
RESPONSE
{
"incident": {
"attachments": [
{
"id": "0b2cd101-fae1-4dc5-9e52-29f1b96a16aa",
"incidentId": "eb68281c-d82a-4c1e-bb7b-660b0ae630c6",
"type": "IDENTIFICATION_DOCUMENT",
"fileKey": "/lbdqsjw4000a0064a8b84x89.png",
"createdAt": "2022-12-07T14:25:18.000Z",
"updatedAt": "2022-12-07T14:25:18.000Z"
},
{
"id": "1b70aadd-d152-4dd0-a1cf-e45479281fc6",
"incidentId": "eb68281c-d82a-4c1e-bb7b-660b0ae630c6",
"type": "COMMERCIAL_INVOICE",
"fileKey": "/lbdqus1y000a0064a89ehzlx.pdf",
"createdAt": "2022-12-07T14:32:37.000Z",
"updatedAt": "2022-12-07T14:32:37.000Z"
},
{
"fileKey": "/lbdqus1y000a0064a89ehzlx.pdf",
"type": "IDENTIFICATION_DOCUMENT",
"incidentId": "eb68281c-d82a-4c1e-bb7b-660b0ae630c6"
}
],
"attachmentValidations": [],
"concerns": [],
"id": "eb68281c-d82a-4c1e-bb7b-660b0ae630c6",
"createdAt": "2022-12-07T14:25:18.000Z",
"status": "CREATED",
"refundStatus": "CREATED",
"incidentValidationTypes": [],
"refundValidationTypes": [],
"source": "SHIPPER",
"ownerId": 315576186,
"origin": "ZENDESK",
"originId": null,
"entityId": "120165677",
"entityType": "PARCEL",
"reshipParcelId": null,
"relatedShipperId": 315576186,
"type": "PARCEL_NEVER_RECEIVED",
"resolutionTypeSelected": "REFUND",
"resolutionTypeApplied": null,
"refundId": null,
"isManuallyUpdated": true,
"shippingFeesAmount": null,
"merchandiseValue": null,
"taxValue": null,
"rejectedReason": null,
"decidedToRefundAt": null,
"refundSentToHeadOfFinanceAt": null,
"refundSentXMLEndToEndId": null,
"updatedAt": "2023-01-03T14:37:30.000Z",
"isArchived": false,
"requester": null,
"returns": null,
"modificationEvents": {
"ATTACHMENT_UPDATED": {
"meta": {
"attachments": [
{
"fileKey": "/lbdqus1y000a0064a89ehzlx.pdf",
"type": "IDENTIFICATION_DOCUMENT"
}
]
}
},
"STATUS_UPDATED": {
"meta": {
"status": "CREATED"
}
},
"REFUND_STATUS_UPDATED": {
"meta": {
"refundStatus": "CREATED"
}
}
}
}
}
ERROR RESPONSE
{
"message": "Token validity is expired",
"stack": "Error: Token validity is expired\n at handler (/app/src/lambdas/can-access:v1/index.js:108:15)\n at runMicrotasks (<anonymous>)\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n at decoratedHandler (/app/node_modules/@devcubyn/carotte-runtime/dist/load-functions/index.js:33:20)",
"status": 401,
"type": "UnauthorizedError"
}
- You should first upload your attachments with POST /v2/attachments and gey fileKeys
- You can add multiple attachments for one incident
- You should specify type of the attachment Claim attachment type
- As a response we see the whole claim payload
POST /v2/attachments
Field | Type | Details |
---|---|---|
incidentId |
string |
id of claim |
attachments |
[<ClaimFile>] |
Array of attachments (see Attachments) |
STEP 8: Generate return label
1. Generate the return parcel
In order to generate a return label to a given - already delivered - parcel using the Cubyn API
, first a return parcel
needs to be generated using the endpoint found below.
REQUEST (curl)
curl https://api.cubyn.com/v2/parcels/904123053/recipient-returns \
-H 'X-Application: my-app-key'
RESPONSE
{
"id": 906312312,
"batchId": "86820c7e-c6e5-482b-92cc-3cfe58a8d6e7",
"type": "RECIPIENT_RETURN",
"trackingId": "CUB906312312",
"carrierTrackingId": "8R43605332126",
"status": "CREATED",
"aside": false,
"address": {
"line1": "13 rue La Rue Qui Roule",
"line2": "",
"zip": "88880",
"city": "L'isle de rôti",
"state": "",
"country": "FR",
"additionalInformation": ""
},
"firstName": "Raggie",
"lastName": "Redmont",
"email": "RaRe@islederoti.com",
"carrier": "colissimo",
"deliveryMode": "standard",
"deliverySigned": false,
"objectCount": 1,
"insurance": 0,
"isAdvalorem": false,
"orderRef": "00000019",
"createdAt": "2022-01-13T16:46:19.000Z",
"updatedAt": "2022-01-13T16:46:20.797Z",
"validationStatus": "INFO",
"cancellationStatus": "NONE",
"viaApplicationId": 483489204,
"shipperId": 784567987,
"pickedAt": "2022-01-13T16:46:19.000Z",
"selfReturnActivated": false,
"customsHsCode": "123456",
"warehouseId": 3628042,
"deliverySaturday": false,
"isAnonymized": false,
"isStorage": true,
"isRemoval": false
}
POST /v2/parcels/:id/recipient-returns
This endpoint creates a return parcel
- using the id
of an existing delivered parcel belonging to the shipper - and as a response it returns said return parcel
object.
From this response, the id
of the newly created return parcel
has to be retained to generate the return label via the actions detailed in the upcoming sub-step.
Field | Details |
---|---|
id |
The id of the parcel belonging to the shipper which we want to transform into a return parcel |
2. Generate the return label
REQUEST (curl)
curl https://api.playship.co/v2/attachments/?includes[]=attachment.file&filters[parcelId]=881112350&filters[type]=LABEL \
-H 'X-Application: my-app-key'
RESPONSE
[
{
"id": 461256384,
"type": "LABEL",
"status": "SUCCESS",
"name": "label-461396384",
"format": "PDF",
"pageCount": 1,
"file": {
"key": "/kyd7elpu000sfd339ecqxl4n.pdf",
"url": "https://s3-eu-west-1.amazonaws.com/cubyn.staging.default/kyd7elpu0230sfd339ecqxl4n.pdf?AWSAccessKeyId=AKIASLTUFOJUFNBXHL52&Expires=1642134252&Signature=MG2fxph1dl9Ug5cxEji%3T0Gdg%2Bcs%3D"
},
"s3Url": "https://s3-eu-west-1.amazonaws.com/cubyn.staging.default/kyd7elpu0230sfd339ecqxl4n.pdf?AWSAccessKeyId=AKIASLTUFOJUFNBXHL52&Expires=1642134252&Signature=MG2fxph1dl9Ug5cxEji%3T0Gdg%2Bcs%3D",
"fileSize": 120000,
"parcelId": 906312312,
"fileKey": "/kyd7elpu000sfd339ecqxl4n.pdf",
"createdAt": "2022-01-13T16:46:20.000Z",
"updatedAt": "2022-01-13T16:46:21.000Z"
}
]
GET /v2/attachments/?includes[]=attachment.file&filters[parcelId]=:id&filters[type]=LABEL
The endpoint above - using the id
of the return parcel
generated in the previous sub-step - returns a full LABEL
object that belongs to the given parcel.
This object (see example on the right) includes the URL
through which the label can be downloaded in a .pdf
form. (The URL
is to be found exactly under the response.file.url
key)
Field | Value | Details |
---|---|---|
includes[] |
attachment.file |
We want to include the attachment files belonging to the return parcel |
filters[parcelId] |
id |
Filtering by the id of the return parcel to which we want to get the return label |
filters[type] |
LABEL |
Filtering only the LABEL type objects |
Lot Management API
Here the collection on v3 api objects and endpoints dedicated to lot management
Lot properties
Field | Type | Details |
---|---|---|
id |
string |
the id attached to one product, aggregation of date ref and productId |
productId |
string |
the product related to the lot |
date |
date |
lot validity date |
reference |
string |
represent the lot reference like 'WIO 12345' |
isBlocked |
boolean |
status of the lot, could be active when isBlocked equal false or blocked if isBlocked equal to true |
quantities |
object |
detailled quantities for this lot, full details describe below |
Quantities
Field | Type | Details |
---|---|---|
available |
number |
all objects available on this lot (if not blocked) |
damaged |
number |
all objects damaged |
total |
number |
every objects in available and damaged |
Warning
As the id is an aggregation of reference, date and productId, it will be modified when its date
or reference
is patched.
Retreive all lots
It will search and return among all your lots register at Cubyn. By default it will return the 1000 latest updated lots. You have filters in order to search more precisely into your lots.
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v3/inventory/lots?filters[productId]=0318d74f-d0ab-4c10-975f-c4dcf14b2261&limit=20 \
--header 'X-Application: my-app-key'
RESPONSE
[
{
"id": "123456789_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"productId": "0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2024-01-01T00:00:00.000Z",
"reference": "WIO 123456789",
"isBlocked": true,
"quantity": {
"available": 2,
"damaged": 0,
"total": 2
}
}, {
"id": "9996666_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"productId": "0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2024-01-01T00:00:00.000Z",
"reference": "WIO 9996666",
"isBlocked": false,
"quantity": {
"available": 2,
"damaged": 1,
"total": 3
}
}
]
GET /v3/inventory/lots/
Filters params
All filters are optional and here to have a more precise results.
Field | Type | Details |
---|---|---|
lotIds |
array<string> |
list of lotIds searched, minimun one value if used and maximum 1000 like the limit |
productId |
string |
Will return all lots for one product |
date |
string |
get all lot sharing the same date |
reference |
string |
get all lot sharing the same reference |
withQuantity |
boolean |
return only lots with available quantity |
Limit and offset
By default the limit is 500 (and also the maximum allowed) lots, if you have more you can play with the offset in order to get the next one
Field | Type | Details |
---|---|---|
limit |
number |
limit is by default 1000 |
offset |
number |
offset by default 0, the first n-indexes to skip to retrieve the n+1 lots |
like in these exemples
Endpoint | Description |
---|---|
v3/inventory/lots?limit=20 |
return only the 20 first lots |
v3/inventory/lots?limit=100&offset=100 |
returns next 100 lots |
Sorting
Using sorting you can sort your lots by ascending or descending order.
Endpoint | Description |
---|---|
/v2/inventory/lots?sort[lotDate]=asc |
returns array of lots sorted by lot date ascending. |
/v2/inventory/lots?sort[lotDate]=desc |
returns array of lots sorted by lot date descending. |
it will return an array of lots or empty if no lots matching the filters
on the header, x-total-count
as the total number of lots matching to the filters
Retreive one lot
Retreive the lot with a specific id or throw 404 not found
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v3/inventory/lots/123456789_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261 \
--header 'X-Application: my-app-key'
RESPONSE
{
"id": "123456789_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"productId": "0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2024-01-01T00:00:00.000Z",
"reference": "WIO 123456789",
"isBlocked": true,
"quantity": {
"available": 2,
"damaged": 0,
"blocked": 0
}
}
GET /v3/inventory/lots/:id
it will return one lot
status | Description |
---|---|
404 |
lot for this id is not found |
Update Lot
Modify some lot properties and return the updated lot.
curl --request PATCH \
--url https://api.cubyn.com/v3/inventory/lots/123456789_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b226 \
--header 'X-Application: my-app-key'
--header 'content-type: application/json' \
--data '{
"date": "2024-03-01T00:00:00.000Z",
"reference" "WIO 100000",
"blocked": false
}'
RESPONSE
{
"id": "100000_2024-03-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"productId": "0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2024-03-01T00:00:00.000Z",
"reference": "WIO 100000",
"isBlocked": false,
}
PATCH /v3/inventory/lots/:id
At least one property must be in the payload to b a valid request
Field | Type | Details |
---|---|---|
date |
date |
the new validity date |
reference |
string |
the new reference for this lot |
blocked |
boolean |
the new status of this lot, active or blocked |
it will return the lot udpated
status | Description |
---|---|
404 |
lot for this id is not found |
Warning
It will modify the lot id if you patch the date
and/or reference
, save the response as new lot value.
Also please note, the patching lot could merge it with an exiting lots, it will automatically take the status of the destination lot.
for exemple, if you've got these lots
:
[
{
"id": "REF-1-DATE-1_PRODUCT-1",
"reference": "REF_1",
"productId": "PRODUCT_1",
"date": "DATE_1",
"isBlocked": false,
"quantities": {
"available": 20,
"damaged": 0,
"total": 20,
}
},
{
"id": "REF-1-DATE-2_PRODUCT-1",
"reference": "REF_1",
"productId": "PRODUCT_1",
"date": "DATE_2",
"isBlocked": true,
"quantities": {
"available": 5,
"damaged": 1,
"total": 6,
}
},
]
and you send this
curl --request PATCH \
--url https://api.cubyn.com/v3/inventory/lots/REF-1-DATE-1_PRODUCT-1 \
--header 'X-Application: my-app-key'
--header 'content-type: application/json' \
--data '{
"date": "DATE_2",
}'
it will merge lot like this
[
{
"id": "REF-1-DATE-2_PRODUCT-1",
"reference": "REF_1",
"productId": "PRODUCT_1",
"date": "DATE_2",
"isBlocked": true,
"quantity": 30,
"quantities": {
"available": 25,
"damaged": 1,
"total": 26,
}
},
]
Manage Lot Status
This endpoints only patch the status. It will not changed the lot id.
curl --request PATCH \
--url https://api.cubyn.com/v3/inventory/lots/123456789_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b226/status \
--header 'X-Application: my-app-key'
--header 'content-type: application/json' \
--data '{
"blocked": false
}'
RESPONSE
{
"id": "123456789_2024-01-01T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b226",
"productId": "0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2024-01-01T00:00:00.000Z",
"reference": "WIO 123456789",
"isBlocked": true,
}
PATCH /v3/inventory/lots/:id/status
Field | Type | Details |
---|---|---|
blocked |
boolean |
the new status of this lot, active or blocked |
it will return the lot udpated
status | Description |
---|---|
404 |
lot for this id is not found |
Parcel API
Parcel properties and objects
Statuses
New parcel statuses
Name | Details |
---|---|
CREATED |
when the parcel is created on cubyn side |
CANCELED |
The parcel has been canceled |
VALIDATION_FAILED |
The parcel has not been validated |
PROCESSING |
preparation is in progress |
SHIPPED |
the parcel has sent to carrier |
IN_TRANSIT |
parcel is in transit on carrier side |
DELIVERED |
Delivered to the customer |
RETURNING |
Parcel has been returned and in transit to the warehouse |
RETURNED |
Parcel has been delivered to the warehouse |
CARRIER_EXCEPTION |
parcel could not be delivered due to carrier exception |
Address
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.) |
Lot
Field | Type | Details |
---|---|---|
id* |
string |
lot id |
reference* |
string |
lot reference |
date* |
string |
lot validaty date |
quantity |
number |
number of object sent with this lot |
Content
Field | Type | Details |
---|---|---|
id* |
string |
product id |
reference* |
string |
product reference |
name* |
string |
product name |
lots |
array |
array of object sent split by lot |
quantity* |
number |
how many products has been sent |
Parcel
Field | Type | Details |
---|---|---|
id* |
number |
the unique id attached ton one parcel |
trackingId |
string |
the carrier tracking id if assigned to a carrier |
status* |
Enum<string> |
enum, will one of the status describe above |
type* |
string |
Type of the parcel, could be SHIPMENT, RECIPIENT_RETURN, DUPLICATE or CUBYN_RETURN |
address* |
object |
describe in address |
firstName* |
string |
First name of recipient |
lastName* |
string |
Last name of recipient |
phone* |
string |
Phone of recipient |
email* |
string |
Email of recipient |
organizationName |
string |
Organization name if lastName and firstName are not defined |
deliveryMode* |
Enum<string> |
Shipping mode allowed: standard , standard+ , express , express+ or relay |
deliverySigned* |
boolean |
Should shipment be handed against signature |
relayPickupRef |
string |
Pickup point identifier (only if deliveryMode is relay ) (see handling relay) |
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) |
createdAt* |
string |
parcel creation date in cubyn system |
updatedAt* |
string |
last update on the parcel |
validatedAt |
string |
when the parcel has been validated and ready to be fulfilled |
shippedAt |
string |
parcel was handed over to the transporter |
deliveredAt |
string |
Parcel was delivered to the recipient |
ordered* |
object |
parcel object asked details |
ordered.quantity* |
number |
parcel total object quantity asked |
ordered.content* |
array |
list of required object per product |
shipped |
object |
parcel objects shipped |
shipped.quantity |
number |
parcel total object quantity shipped |
shipped.content |
array |
list of object shipped per product, describe content |
Retreive all parcels
If will search and return among all your parcels registered at Cubyn. By default it will return the 500 latest created parcels. You have filters in order to search more precisely into your parcels.
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v3/parcels \
--header 'X-Application: my-app-key'
RESPONSE
[
{
"id": 370449951,
"trackingId": "CUB370449951",
"carrierTrackingId": "6C18627519287",
"status": "CARRIER_DELIVERED", // maybe cancellation should be a status too and we can simplify the status list too
"address": {
"line1": "728 Chemin des Planes",
"line2": "",
"zip": "30700",
"city": "Saint-Siffret",
"state": "",
"country": "FR",
"additionalInformation": ""
},
"firstName": "Audrey",
"lastName": "Melano",
"phone": "06 30 06 48 41",
"email": "shipping_17508417_38991824@eu.perso-email.com",
"value": 330.75,
"carrier": "colissimo",
"deliveryMode": "standard+",
"deliverySigned": true,
"insurance": 12.54,
"isAdvalorem": false,
"orderRef": "38991824",
"createdAt": "2024-03-19T11:28:05.000Z",
"updatedAt": "2024-03-22T12:11:43.342Z",
"cancelled": false,
"ordered": {
"quantity": number;
"content": {
"reference": string;
"quantity": number;
"name"?: string;
"value"?: number
}[]
},
"shipped": {
"quantity": number;
"content": {
"id": string;
"reference": string;
"name": string;
"lots": {
"id": string; // not UUID, but aggregated lotId (lotNumber+lotDate+productId)
"reference": string;
"date": Date;
"quantity": number; // quantity picked only for the lot
}[], // could be undefined if no lots (QUESTION about when we mix)
"quantity": number; // total quantity (QUESTION: naming totalQuantity )
}[];
}
"weight": 0.38,
"volumetricWeight": 0.7568,
"shippedAt": "2024-03-19T19:18:06.000Z",
"deliveredAt": "2024-03-22T11:31:00.000Z",
"originalValue": 330.75,
"validatedAt": "2024-03-19T11:28:09.000Z", // to be renamed in validatedAt
},
]
GET /v3/parcels/
Filters params
All filters are optional and here to have a more precise results.
Field | Type | Details |
---|---|---|
parcelIds |
array<number> |
only parcels with the id requested |
status |
string |
only return parcels with status matching required one, list of status like the one descrive above |
orderRef |
string |
filter by orderRef on parcels |
type |
string |
filter by parcel type with one of the parcel type describe above |
Limit and offset
By default the limit is 500 (and also the maximum allowed) lots, if you have more you can play with the offset in order to get the next one
Field | Type | Details |
---|---|---|
limit |
number |
limit is by default 500, if you |
offset |
number |
offset by default 0, the first n-indexes to skip to retrieve the n+1 lots |
like in these exemples
Endpoint | Description |
---|---|
v3/parcels?limit=20 |
return only the 20 first parcels |
v3/parcels?limit=100&offset=100 |
returns next 100 parcels |
it will return an array of parcels or empty if no parcels matching the filters
Retrieve one parcel
curl --request GET \
--url https://api.cubyn.com/v3/parcels/370449951 \
--header 'X-Application: my-app-key'
RESPONSE
{
"id": 370449951,
"trackingId": "CUB370449951",
"carrierTrackingId": "6C18627519287",
"status": "CARRIER_DELIVERED", // maybe cancellation should be a status too and we can simplify the status list too
"address": {
"line1": "728 Chemin des Planes",
"line2": "",
"zip": "30700",
"city": "Saint-Siffret",
"state": "",
"country": "FR",
"additionalInformation": ""
},
"firstName": "Audrey",
"lastName": "Melano",
"phone": "06 30 06 48 41",
"email": "shipping_17508417_38991824@eu.perso-email.com",
"value": 330.75,
"carrier": "colissimo",
"deliveryMode": "standard+",
"deliverySigned": true,
"insurance": 12.54,
"isAdvalorem": false,
"orderRef": "38991824",
"createdAt": "2024-03-19T11:28:05.000Z",
"updatedAt": "2024-03-22T12:11:43.342Z",
"cancelled": false,
"ordered": {
"quantity": number;
"content": {
"reference": string;
"quantity": number;
"name"?: string;
"value"?: number
}[]
},
"shipped": {
"quantity": number;
"content": {
"id": string;
"reference": string;
"name": string;
"lots": {
"id": string; // not UUID, but aggregated lotId (lotNumber+lotDate+productId)
"reference": string;
"date": Date;
"quantity": number; // quantity picked only for the lot
}[], // could be undefined if no lots (QUESTION about when we mix)
"quantity": number; // total quantity (QUESTION: naming totalQuantity )
}[];
}
"weight": 0.38,
"volumetricWeight": 0.7568,
"shippedAt": "2024-03-19T19:18:06.000Z",
"deliveredAt": "2024-03-22T11:31:00.000Z",
"originalValue": 330.75,
"validatedAt": "2024-03-19T11:28:09.000Z", // to be renamed in validatedAt
}
GET /v3/parcels/:id
it will return a parcel
status | Description |
---|---|
404 |
lot for this id is not found |
Product API
Product properties and objects
Product
Field | Type | Details |
---|---|---|
id* |
string |
the product id attached ton one parcel |
reference* |
string |
unique reference for a product |
name* |
string |
product name |
type* |
string |
product type such as STANDARD, RECIPIENT_RETURN, BUNDLE, VIRTUAL, BLOCKED_LOT, DAMAGED |
archived* |
boolean |
if product is archived |
archivedAt |
date |
if archived is the date when its happened |
updatedAt* |
date |
last update on the product |
quantities* |
object |
describe in below |
lots* |
array |
describe in lot |
Quantities
Field | Type | Details |
---|---|---|
available |
number |
all objects available on this product to be sold |
damaged |
number |
all objects damaged |
reserved |
number |
all objects reserved on parcels (not available) |
blocked |
number |
all objects blocked on blocked lot |
total* |
number |
sum of every quantity |
Retreive all products
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v3/inventory/products \
--header 'X-Application: my-app-key'
RESPONSE
[
{
"id": "feeefa44-9e51-4fa7-b8b5-b29e450f488d",
"reference": "productReferenceA",
"name": "New Product",
"type": "STANDARD",
"ownerId": 7010000001,
"archived": false,
"updatedAt": "2022-09-12T00:00:00.000Z",
"quantity": {
"available": 2,
"damaged": 0,
"blocked": 0,
"reserved": 0,
"total": 2,
},
"lots": [
{
"id": "9996666_2022-09-12T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2022-09-12T00:00:00.000Z",
"reference": "WIO 9996666",
"isBlocked": false,
"quantity": {
"available": 2,
"damaged": 0,
"total": 2,
}
}
]
}
]
GET /v3/inventory/products
Filters params
All filters are optional and here to have a more precise results.
Field | Type | Details |
---|---|---|
productIds |
array<string> |
only products with the id requested |
onlyWithAvailableQuantity |
boolean |
only return product with available quantity |
type |
string |
one of product type describe above |
reference |
string |
a product sku |
isArchived |
boolean |
only products archived or not regarding the value, value possible true or false |
isCase |
boolean |
only products is a case or not regarding the value sent |
isCasePacked |
boolean |
only products is a casePacked or not regarding the value sent |
isUnknown |
boolean |
only products is unknown or not regarding the value sent |
Limit and offset
By default the limit is 1000 (and also the maximum allowed) lots, if you have more you can play with the offset in order to get the next one
Field | Type | Details |
---|---|---|
limit |
number |
limit is by default 1000, if you |
offset |
number |
offset by default 0, the first n-indexes to skip to retrieve the n+1 lots |
like in these exemples
Endpoint | Description |
---|---|
v3/inventory/products?limit=20 |
return only the 20 first products |
v3/inventory/products?limit=100&offset=100 |
returns next 100 products |
it will return an array of product
on the header, x-total-count
as the total number of products eligible to the filters (can be more than the limit)
Retreive one product
curl --request GET \
--url https://api.cubyn.com/v3/inventory/products/370449951 \
--header 'X-Application: my-app-key'
RESPONSE
{
"id": "feeefa44-9e51-4fa7-b8b5-b29e450f488d",
"reference": "productReferenceA",
"name": "New Product",
"quantity": {
"available": 2,
"damaged": 0,
"blocked": 0,
"reserved": 0,
},
"lots": [
{
"id": "9996666_2022-09-12T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2022-09-12T00:00:00.000Z",
"reference": "WIO 9996666",
"isBlocked": false,
"quantity": {
"available": 2,
"damaged": 0,
"blocked": 0,
}
}
]
}
GET /v3/inventory/products/:id
it will return a product
status | Description |
---|---|
404 |
lot for this id is not found |
Webhooks
You can use webhooks to subscribe to events related to your product stock updates.
By providing us with a webhook, you will be notified everytime one of your product's quantities changes.
When creating an “API Cubyn
” application, you can provide a URL to subscribe to webhooks. Cubyn will post product stock updates related to your product to this URL.
Note that if you create multiple “API Cubyn
” applications, each with a different webhook URL, Cubyn will post all stock updates to every application with product.stock.updated
events enabled.
Enabling webhooks
To activate webhooks for your account, configure on shipper.cubyn.com applications:
- URL of the Webhook
- Events you want to subscribe to (see below)
Stock webhook event types
Only one type of event related to stock exists currently. Others are linked to parcels.
Event | Description |
---|---|
product.stock.updated |
Stock have change for one of your product. |
Wehbook request
A JSON payload
POST
ed to your webhook
{
"id": "feeefa44-9e51-4fa7-b8b5-b29e450f488d",
"reference": "productReferenceA",
"name": "New Product",
"type": "STANDARD",
"ownerId": 7010000001,
"archived": false,
"updatedAt": "2022-09-12T00:00:00.000Z",
"quantity": {
"available": 2,
"damaged": 0,
"blocked": 0,
"reserved": 0,
"total": 2,
},
"lots": [
{
"id": "9996666_2022-09-12T00:00:00.000Z_0318d74f-d0ab-4c10-975f-c4dcf14b2261",
"date": "2022-09-12T00:00:00.000Z",
"reference": "WIO 9996666",
"isBlocked": false,
"quantity": {
"available": 2,
"damaged": 0,
"total": 2,
}
}
]
}
Our systems will issue POST requests to your Webhook URL with product in the request body.
Inbound API
Inbound properties and objects
Inbound order statuses
Name | Details |
---|---|
CREATED |
When order is created on Cubyn side |
VALIDATED |
When order is validated on Cubyn side |
RECEIVING |
When order is receiving on Cubyn side |
COMPLETED |
When order is received on Cubyn side |
Lot information
Field | Type | Details |
---|---|---|
date* |
date |
Lot validity date |
reference* |
string |
Represent the lot reference like 'WIO 12345' |
Inbound order line quantities
Field | Type | Details |
---|---|---|
declared* |
number |
Declared items quantity |
labeled* |
number |
Labeled items quantity |
stored* |
number |
Stored items quantity |
Inbound order line
Field | Type | Details |
---|---|---|
id* |
string |
Inbound order line id |
orderId* |
string |
Inbound order id |
name* |
string |
Product name |
barcode* |
string |
Product barcode |
sku* |
string |
Product SKU |
quantities* |
object |
Inbound order line quantities |
createdAt* |
date |
Inbound order line creation date in Cubyn system |
updatedAt* |
date |
Last update on the inbound order line |
lotInformation |
object |
Lot information |
Inbound order
Field | Type | Details |
---|---|---|
id* |
string |
Inbound order id |
status* |
Enum<string> |
Inbound order status |
lines* |
array |
Inbound order lines |
isDeleted* |
boolean |
Is inbound order deleted? |
declaredPackingUnits* |
number |
Number of declared packing units |
receivedPackingUnits* |
number |
Number of received packing units |
completedPackingUnits* |
number |
Number of completed packing units |
declaredItems* |
number |
Number of declared items |
storedItems* |
number |
Number of stored items |
createdAt* |
date |
Inbound order creation date in Cubyn system |
updatedAt* |
date |
Last update on the inbound order |
receiptStartedAt* |
date |
Inbound order reception date in Cubyn system |
validatedAt* |
date |
Inbound order validation date in Cubyn system |
completedAt* |
date |
Inbound order completion date in Cubyn system |
deletedAt* |
date |
Inbound order deletion date in Cubyn system |
ownerId* |
number |
Owner id of the inbound order |
insurance* |
number |
Insurance value |
isSameDayInbound* |
boolean |
Is order supposed to be inbounded in the day |
Retrieve one inbound order
Retrieve inbound order with inbound order lines and lot information with a specific id or throw 404 not found.
REQUEST (curl)
curl --request GET \
--url https://api.cubyn.com/v3/storage-inbound/orders/b7b41188-ce8e-49bf-94be-b9a11e8c5846 \
--header 'X-Application: my-app-key'
RESPONSE
{
"id": "b7b41188-ce8e-49bf-94be-b9a11e8c5846",
"lines": [
{
"id": "0c245d32-4f18-4c93-89e6-db2786dbad66",
"orderId": "b7b41188-ce8e-49bf-94be-b9a11e8c5846",
"name": "Product 1",
"barcode": "barcode_1",
"sku": "SKU_1",
"quantities": {
"declared": 1,
"labeled": 0,
"stored": 0
},
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"lotInformation": {
"date": "2024-01-01T00:00:00.000Z",
"reference": "WIO 123456789"
}
}
],
"isDeleted": false,
"declaredPackingUnits": 1,
"receivedPackingUnits": 0,
"completedPackingUnits": 0,
"declaredItems": 1,
"storedItems": 0,
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"receiptStartedAt": null,
"validatedAt": null,
"completedAt": null,
"deletedAt": null,
"status": "CREATED",
"ownerId": 111111111,
"insurance": null,
"isSameDayInbound": false
}
GET /v3/storage-inbound/orders/:id
It will return one inbound order
status | Description |
---|---|
404 |
Inbound order for this id is not found |
Update lot information on inbound line
Modify some lot information on inbound order line and return line with the updated lot information.
curl --request PATCH \
--url https://api.cubyn.com/v1/storage-inbound/lines/7dd2599e-e208-4624-8e07-2778b899db99/lot \
--header 'X-Application: my-app-key' \
--header 'content-type: application/json' \
--data '{
"date": "2024-03-03T00:00:00.000Z",
"reference": "WIO 100000"
}'
RESPONSE
{
"id": "7dd2599e-e208-4624-8e07-2778b899db99",
"orderId": "b7b41188-ce8e-49bf-94be-b9a11e8c5846",
"name": "Product 1",
"barcode": "barcode_1",
"sku": "SKU_1",
"quantities": {
"declared": 1,
"labeled": 0,
"stored": 0
},
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"lotInformation": {
"date": "2024-03-03T00:00:00.000Z",
"reference": "WIO 100000"
}
}
PATCH /v1/storage-inbound/lines/:lineId/lot
At least one property must be in the payload to be valid request
Field | Type | Details |
---|---|---|
date |
date |
New validity date (in format YYYY-MM-DDTHH:mm:ss.sssZ ) |
reference |
string |
New reference |
It will return the inbound order line with the updated lot information
status | Description |
---|---|
400 |
Not allowed to modify inbound line lot information related to the return |
400 |
Not allowed to modify inbound line lot information related to the inbound order with the status |
404 |
Inbound order line is not found |
404 |
Inbound lot for line is not found |
Warning
Not allowed to modify lot information on line related to the:
- inbound order related to the return;
- inbound order in the status (RECEIVING|COMPLETED
).
API Reference
API Objects
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 |
Concerns
This is the concern model used in to specify an object contained in a Claim
.
Field | Type | Details |
---|---|---|
type* |
Enum<string> |
Type of concerned item Claim concern type |
entityId* |
string |
Id of issued sku or parcel based on what is provided to Entity type |
entityType* |
string |
Entity type Claim concern entity type |
quantity* |
number |
Number of concerned products |
incidentId |
string |
Related claim id (only displayed when retrieve data) |
Requester
This is the requester model used in to specify an object contained in a Claim
.
Field | Type | Details |
---|---|---|
firstName* |
string |
First Name of claim creator |
lastName* |
string |
Last Name of claim creator |
email* |
email |
Email of claim creator |
organizationName* |
number |
Organization name that this requester is belong |
language* |
string |
FR/ES |
bankInfo* |
<BankInfo> |
Bank information format |
Bank info
This is the bank info model used in to specify an object contained in a Requester
.
Field | Type | Details |
---|---|---|
firstName* |
string |
First Name of refund recipient |
lastName* |
string |
Last Name of refund recipient |
iban* |
string |
IBAN of refund recipient |
bic* |
string |
BIC of refund recipient |
country* |
string |
FR/ES |
Claim file
This is claim file attachment object, that is required to provide for a claim.
Field | Type | Details |
---|---|---|
type * |
Enum<string> |
Claim attachment type Claim attachment type |
fileKey * |
string |
Key that we get as a response when upload file with files API |
Claim file retrieve
This is claim file attachment object, this is what displayed when claim is retrieved
Field | Type | Details |
---|---|---|
id |
string |
File id |
incidentId |
string |
Related claim id (only displayed when retrieve data) |
type |
Enum<string> |
Claim attachment type Claim attachment type |
fileKey |
string |
Key that we get as a response when upload file with files API |
url |
string |
Url to the file |
createdAt |
date |
Date when file was uploaded |
updatedAt |
date |
Date when file was updated |
Enums
Claim type
These are the list of claims types that can be selected in ENUM.
VALUE | Details |
---|---|
PARCEL_LATE_DELIVERY |
Means that delivery is late for this parcel |
PARCEL_MISSING_PRODUCT |
The parcel is incomplete, something is missing |
PARCEL_NEVER_RECEIVED |
Means that this parcel has been delivered but not received |
PARCEL_NEVER_RECEIVED_LOST_IN_TRANSIT |
This parcel has not been delivered |
PARCEL_NEVER_RECEIVED_MARKED_AS_LOST_CARRIER |
The carrier marked the order as lost in transit |
PARCEL_NOT_AVAILABLE_FOR_PICKUP |
The order is marked as available for pick up but availability is contested by recipient |
PARCEL_RECEIVED_DAMAGED |
The order is delivered with damages due to transportation |
PARCEL_WRONG_PRODUCT |
Wrong order or products received |
Source
These are the list of sources that can be selected in ENUM.
VALUE | Details |
---|---|
RECIPIENT |
Consumer (Claims created via care.cubyn.com) |
SHIPPER |
Shipper (Claims created via shipper.cubyn.com) |
Entity type
These are the list of entity types that can be selected in ENUM.
VALUE | Details |
---|---|
PARCEL |
Parcel |
PRODUCT |
SKU (Product) |
Resolution type
These are the list of resolution types that can be selected in ENUM.
VALUE | Details |
---|---|
RESHIP |
Reship (when the desired resolution is to re-ship the entity(s)) |
REFUND |
Refund (when the desired resolution is to refund amount that is payed) |
Claim status
These are the list of claim statuses that can be selected in ENUM.
VALUE | Details |
---|---|
CREATED |
Claim is created but not yet handled by Cubyn agent |
REJECTED |
Claim is rejected by Cubyn |
RESOLVED |
Claim is resolved by Cubyn and sent to be refunded |
STARTED |
Claim is resolved by Cubyn and sent to bank to be refunded (The bank details validation is not passed yet) |
Claim attachment type
These are the list of claim's attachment types.
VALUE | Details |
---|---|
AFFIDAVIT |
Affidavit |
BUYING_INVOICE |
Purchase invoice of the SKU |
CARRIER_TRACKING_PAGE |
Carrier tracking page for the order |
CERTIFICATE_NOT_PICKED_UP |
Certificate of non delivery / not picking up |
COMMERCIAL_INVOICE |
Commercial invoice for the order |
COMPLAINT |
Affidavit OR police report |
GENERAL |
Other attachment |
IDENTIFICATION_DOCUMENT |
Identification document |
ITEM_DAMAGED |
Proof photo of damaged item (parcel/sku) |
ITEM_LABEL |
Pictures of parcel and shipment label |
ITEM_WRONG |
Picture of parcel and wrong products |
POLICE_REPORT |
Police report |
PROOF_OF_DELIVERY |
Proof of delivery |
Claim concern type
These are the list of claim concern types
VALUE | Details |
---|---|
MERCHANDISE |
Merchandise |
Claim concern entity type
These are the list of claim concern types
VALUE | Details |
---|---|
ITEM |
Item is the concerned entity |
PRODUCT |
SKU is the concerned entity |
API Endpoints
Find here all API endpoints available.
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 |
PUT | /v2/parcels/:id/cancel |
Cancel (and delete) 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 |
{"packingUnits": 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/inventory/products |
– | List all your products |
GET | /v2/inventory/products?productId=:productId |
– | Get one product by ID |
GET | /v2/inventory/product-sku/:productId |
- | List a product barcodes |
GET | /v2/inventory/lots?productId=:productId |
- | List a product lots |
PUT | /v2/product-catalog/products/:productId |
{"sku":"newSku", "name":"newName"} | Update a product |
Claims
Method | Path | Description |
---|---|---|
POST | /v1/claims |
Create new claim |
GET | /v1/claims |
Get list of claims |
GET | /v1/claims/:id |
Get one of claims |
Files
Method | Path | Body | Description |
---|---|---|---|
POST | /v1/files |
– | Post files |
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 |
CARRIER_RETURN_RECEIVED |
Cubyn | (final status) Parcel not delivered to recipient / returned to Cubyn warehouse |
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
Files upload
Used to upload files for claim creation
REQUEST (curl)
curl https://api.cubyn.com/v2/attachments \
-H 'X-Application: my-app-key' \
-F name=my-file.pdf
RESPONSE
{
"key": "/kwff65um003ufd339e9czkq0.pdf",
"url": "https://s3/path/to/file",
"meta": {
"contenttype": "application/pdf",
"originalname": "sample1.pdf"
}
}
Files upload for claims
Maximum allowed size: 5Mb.
Endpoint
POST /v1/files
Tracking page
Cubyn offers a unified tracking page that is common to every carrier we support. We highly recommend using it:
- the web page is accessible as soon as your parcel is picked by our messengers
- it unifies your customer experience across all our carriers
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 support many relay points now (all Mondial Relay zones)
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 integrations@cubyn.com.
Endpoint
https://apisandbox.cubyn.com/v2
Cubyn customer interface URL
https://shippersandbox.cubyn.com
Handling errors
When
PUT
ing orPOST
ing - 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. |