Working with API Resources

The fundamental concept in any REST API is the resource. A resource (such as products and orders) is an object with a type, associated data, relationships to other resources and a set of methods that operate on it. The VoyageOne API includes several API service endpoints which you call to work with resources. Each service is its own API, but you will work with each resource in roughly the same way.

To get you started working with VoyageOne API resources, you do not need to write any code. Instead, you can use an HTTP client such as the Linux program cURL. For example, the following cURL command executes a POST request to get a single product called "product-code-1":

{curl -X POST https://sandbox.voyageone.com/v1/restapi/supplier/product/get \
-H "Content-Type: application/json" \
-H "Client-Id: e174faa1b1cd00c817162002c25f579f " \
-H "Authorization: Bearer 301adf282ea832e8526877d74c938527" \
-d '{ "code": "product-code-1"}'

Every API resource described in the API Reference contains an example request and response that lets you try out the API. In addition to cURL, you can use API testing tools such as Postman. Postman provides a GUI for exploring an API's resources and executing its methods.

API Technical Details

All API requests follow REST rules in terms of resource naming conventions, use of methods as action descriptions and use of custom headers to convey additional information. Refer to the following guidelines to ensure the development of your application integration goes smoothly while conforming to the requirements of the VoyageOne API:

Working with Products

Products are the core resource in the VoyageOne Platform. All products are represented as a product variant. Product variants are made up of a parent product that includes basic product information and a set of child items (called variants) representing different variations of the parent product. A product variant will always contain one or more items even when the item will be listed individually. This format is intended to simplify the data contract necessary to communicate product data between all integrated systems.

Each item has its own SKU, price and inventory. For example, a shirt having three sizes and four colors has 12 variants, each with a unique SKU. In this example, each color would be a separate product variant identified by a unique product code and contain three items, making a total of four products available for listing on a marketplace.

In the product object model, there are product properties and item properties. Product properties are used to describe the information in common with all items/variants contained in the product variant such as the name and description of the product. Item properties are used to describe the properties of the specific item/variant such as the SKU, price and available quantity. Both the create and update product endpoints allow you to create and update all product and item properties in a single API request. While the product inventory, price and status endpoints allow you to update item properties without having to update the entire product providing for faster operations.

Note: Products having a single variant are treated as a standalone item that will be listed individually using the item's SKU. In this case, you can use either the item's SKU or any other unique value to define the product's code.

Important: Products cannot be deleted via the VoyageOne API. In order to delete a product, you will need to submit your request to support@voyageone.cn. Unlike products, items can be deleted from the catalog using the product update API endpoint. An item is automatically removed if the item is not included in the product update. Optionally, you can set the alive property to false or set the qty to 0 to prevent the item from being listed on a marketplace.

Working with Orders

During the order management process, you should perform multiple actions against orders. You should first request a list of orders with the status "Open" for importing into the vendor's system then for each order that is imported, you should send an order acknowledgement indicating a successful import. Next, you should send an order shipment per order indicating the order has been fulfilled.

Important: Once an order has been shipped, the shipping details cannot be updated.

If any item in the order cannot be fulfilled, you should send an order cancellation. Finally, you can check for the status of orders that are "Completed" to indicate the order has been successfully delivered.

Making an API Request

VoyageOne creates for each vendor a unique set of sandbox and production API credentials called the Client ID and Token. You pass these API credentials in the Client-Id header and Authorization header of each API request. Please contact support@voyageone.cn if you have not already acquired your API credentials.

Important: You should never use or disclose your API credentials in public.

Compared to token-based API authentication schemes like OAUTH and JWT, the VoyageOne API does not require the use of access tokens, web tokens or refresh tokens. Therefore, no additional logic is required by the application integration to request, track or otherwise manage any token type other than the Client ID and Token.

Once you have a valid set of API credentials, you can use the following steps to construct and make an API request:

  1. Add the base URL to the beginning of the desired API endpoint as shown in the following example:
  2. https://sandbox.voyageone.com/v1/restapi/supplier/product/info
  3. Add the POST method as shown in the following example:
  4. POST https://sandbox.voyageone.com/v1/restapi/supplier/product/list
  5. Add a Content-Type header to set the media type as JSON and to set the charset parameter as UTF-8 as shown in the following example:
  6. Content-Type: application/json; charset=UTF-8
  7. Add the Client-Id header with the appropriate Client ID as shown in the following example:
  8. Client-Id: e174faa1b1cd00c817162002c25f579f
  9. Add the Authorization header with the appropriate Token and define the token type as "Bearer".
  10. Note: The Token must be sent as a bearer token which conceals the token in the API request header instead of being sent in the query string or as a cookie.

    Sending a bearer token is simple as specifying the Authorization type as Bearer as shown in the following example.

    Authorization: Bearer 301adf282ea832e8526877d74c938527
  11. Add the required filtering and pagination parameters to the API request body as shown in the following example:
  12. 
    {
      "pageNo": 1,
      "pageSize": 100,
      "createdTime": [1514764800000, 1546214400000]
    }
    
  13. Finally, make the API request. The following example uses the cURL command line tool to get a list of all products using the specified Client ID and Token by calling the production get product API endpoint /restapi/supplier/product/list:
  14. 
    curl -X POST https://sandbox.voyageone.com/v1/restapi/supplier/product/list \
    -H "Content-Type: application/json" \
    -H "Client-Id: e174faa1b1cd00c817162002c25f579f"
    -H "Authorization: Bearer 301adf282ea832e8526877d74c938527" \
    -d '{"pageNo": 1, "pageSize": 100, "createdTime": [null,null]}'
    

Receiving an API Response

API responses will always be returned in JSON. Therefore, you do not need to specify the Accept header in API requests. Currently, error responses are only represented in the API response body and not as a standard HTTP status code as with traditionally REST APIs.

All API responses will return a top-level response object that always includes a code and data property. The status of the request is indicated by the value of the code property while the data property includes the requested data.

A successful API request will be indicated by a status code of 0. If the API request is successful, but there is no data collection to return, the data value will be empty as shown below:

{
  "code": "0",
  "data": []
}
An unsuccessful API request will return an error code as the code along with an additional message property describing the error as shown below:

{
  "code": "E1010074",
  "data": null,
  "message": "The data[items[0].qty] cannot be less than 0."
}
In addition to the successful and unsuccessful API requests as shown above, product API endpoints will also include product-level and item-level validation. Validation is indicated by two additional name/value pairs called "hasErrors" and "errors". If there are no errors, the "hasErrors" property will be set to false and the "errors" property will by empty as shown in the following example:

{
  "code": "0",
  "data":
  [
    {
      "sku": " example-product-sku ",
      "hasErrors": false,
      "errors": []
    }
  ]
}

Filtering

The VoyageOne API provides a single parameter for filtering products and orders by their creation time. This parameter is only available for use with the /restapi/supplier/product/list and /restapi/supplier/order/list API endpoints.

Note: The createdTime parameter can only be used with the /restapi/supplier/product/list API endpoint while the orderTime parameter is only for use with the /restapi/supplier/order/list API endpoint.

Parameter Description
createdTime Required. The specified time range for which the product's createdTime property equals or is within the specified range.

Note: When you first create a product, the VoyageOne API will automatically add the createdTime property using the current UTC timestamp in milliseconds.

To specify a time range, include the starting and ending UTC timestamps in milliseconds. For example, to specify January 1, 2018 through December 31, 2018, you would specify [1514764800000, 1546214400000] as the value. To get a list of all products, specify the value as [null, null].

orderTime Required. The specified time range for which the order's orderTime property equals or is within the specified range.

To specify a time range, include the starting and ending UTC timestamps in milliseconds. For example, to specify January 1, 2018 through December 31, 2018, you would specify [1514764800000, 1546214400000] as the value. To get a list of all orders, specify the value as [null, null].


Pagination

Though it is possible to make an API request to get a single product or order, in most cases, you will be getting hundreds or thousands of products and orders. In order to keep the API operating within acceptable performance limits and to help you avoid from inadvertently consuming more of your own network bandwidth than you might intend, the API will automatically paginate the data you request if the number of products or orders exceeds 100 or exceeds the numbers you set for the pageNo and pageSize parameters in the body of each API request. This means that information is returned in "pages" where you will have a defined number of pages that represent all your products or orders, which themselves will be distributed among the pages.

How to Call Successive Pages

The following optional two parameters are available for the /restapi/supplier/product/list and /restapi/supplier/order/list API endpoints. You may include them in your request in any order you wish.

Parameter Description
pageNo The specific page number in a paginated list of results. Including this parameter in your request will limit the response to a single page matching the page sequence order represented by the page number.
pageSize The number of items to include in the page of results. Including this parameter in your call will adjust the response to only include no more than the number of items that you specify on each page.

Note: The maximum number of items that can be included regardless of the amount you specify is 100.

You will need to construct an iterative loop statement that will continue making successive requests to the API for your data while incrementing the pageNo until you receive all items. You will know that you have received all items once the data element returns empty.

When making calls that return a large number of results, it will often be of benefit to page the result set. By requesting smaller subsets of data, you will get a response much faster than when requesting the entire, potentially large, data set.