Getting started

What is the purpose of this API?

Winddle API provides a way to access all the features of Winddle programatically.

Currently, more than 90% of the features available on Winddle.com are executed through this API, allowing your company to completely automate from the outside any kind of interactions with Winddle.

In other words, the purpose of this API is to fully expose Winddle's internals to allow full integration with your systems as well as provide a way to use the data available on Winddle and extend it as you see fit.

API usage scenarios

My company already has other softwares

Winddle has been designed from the ground-up to be flexible enough to interface with any kind of systems.

The first step in building an interface to Winddle is to select the interesting data from your source systems (the catalog of products, the list of orders and their main data, for instance the delivery date, the supplier's name, etc.)

Then, you can review the fields available in Winddle and map them as closely as possible. If nothing seems to match, you may create some Custom Fields in Winddle and use them to store that extra data from your source systems. It's better to use the default fields as much as possible as Winddle can then provide more meaning and context to them.

Once the mapping between your systems and Winddle has been worked out, you can develop a small set of tools to automatically get the data from your systems and send it to Winddle using this API. The two main options for this would be:

  • An ETL (extract/transform/load): most ETLs are able to communicate with Winddle using either XML or JSON REST interface. If you can also connect your systems to this ETL, then most of the hard work is done, it then becomes an issue of building the mappings and doing the fine tuning (how often to push/pull the data to/from Winddle, how to handle File upload/download, etc.). This solution works the best when your source systems already export their data to a simple database or other datawarehouse.
  • A custom program: in the most simple use-cases (for instance, when all you need is to push the Product/Projects from your ERP to Winddle), the best option may just be to build a small in-house program that will make a few calls to the API. Winddle API use REST, a very well supported format in most modern languages (Python/Ruby/C#/Java...).

Our technical team has experience designing and implementing interfaces between legacy systems and Winddle, feel free to contact us to discuss your options for an efficient integration of Winddle into your existing eco-system.

I would like to extend Winddle

Extending Winddle by creating tools hosted on your own servers and using the Winddle's data attached to your account is one of the possible usage of this API.

Please keep in mind that there are limits to the number of API calls / day (see usage limits) as well as server bandwidth and so, we discourage the following kind of extensions:

  • Real time monitoring tools based on frequent pulling of data from Winddle. We are currently working on a push system to which you'll be able to subscribe. In the meantime, please use reasonable frequencies.
  • Large data set analysis (ex: the details of every projects in the company). Winddle's provided a very flexible statistics system to perform many kind of analysis across your company's whole data.

Winddle offers no guarantee on the completion of requests that would violate the two guidelines above.

Our support website will gladly review your requirement and help you devise a set of optimized/tailored API calls, feel free to get in touch with them!

Where to obtain additional information?

Most of the concepts used by the API are described in more details on Winddle's support website, please have a look if you need a better understanding of the various resources used by this API.

If you have any technical issues when using this API, please feel free to get in touch directly with Winddle's support team!

We'll get back to you as soon as possible.

API Usage

Schema

API access is done over HTTPS, and accessed from https://www.winddle.com/api/v1 url.

All data is sent and received as either JSON or XML, depending on the header's Content-Type.

XML vs JSON format

This API documentation will mostly focus on the JSON syntax as it is less verbose.

The main difference between XML and JSON format is that all the underscored names (eg: deliver_at) becomes dash-separated (deliver-at) in XML.

Also, in XML, there should always be only one root node, the root node is described on each service page.

Blank fields are included as null instead of being omitted.

All timestamps are returned in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ, dates are also returned (and expected to be provided) in ISO 8601 format: YYYY-MM-DD

HTTP Verbs

Where possible, Winddle API strives to use consistent HTTP verbs for each action.
Verb Description
GET Used to retrieve resources or information
POST Used to create resources or perform custom actions involving creation of resources
PUT Used to partially or fully update a resource
PATCH Used to perform actions on a resource, usually performing a partial update
DELETE Used to delete resources

Authentication

Using OAuth2 Tokens (preferred)

Winddle's OAuth service is available at https://www.winddle.com/oauth.

The default OAuth2 scopes provided are full_read and full_write and allow full interaction with Winddle on the user's behalf. More fine grained scopes will be provided at a later time.

Registering your application with Winddle

Winddle currently doesn't allow to register new applications publicly. If you would like to integrate with Winddle, please get in touch with Winddle's support. We will require an application name, a list of callback urls, some contact information and a short description of the application's purpose. An OAuth Client ID and OAuth Client Secret will be provided shortly.

Implemented authorization flows

Winddle implements the Authorization Code flow, the Client credentials flow and the password flow

Any usage of the password flow will be monitored and access may be revoked at any time without prior notice. As such, we do not recommend that you use this for any integration with Winddle.

Sample code (ruby)

Please find below a sample of implementing the Authorization Code flow using Ruby's OAuth2 gem to retrieve the user's current projects.

require 'oauth2'

redirect_uri = 'http://yourwebsite.com/oauth2/callback'
client = OAuth2::Client.new 'fa4da16230726[...]1b55f',
                            '7e28b734d3b94[...]2068a',
                             site: "https://www.winddle.com"

#The Authorization Code will be sent to your redirect_uri
auth_url = client.auth_code.authorize_url redirect_uri: redirect_uri
p "Please visit this url: #{auth_url}"

#Transform the code into a token
token = client.auth_code.get_token '0a50[...]97efa',
                                   redirect_uri: redirect_uri

#Get the first page of the projects currently available for this user,
#same as opening the /projects page on Winddle,
#without any specific filters (JSON format)
token.get('/api/v1/projects').body

Using API Tokens (legacy)

This method isn't recommended as the responsability is on you to ensure that the tokens are never compromised and frequently rotated. Please use OAuth2 whenever possible.

Authentication to the Winddle API can still be made with an API token over HTTPS. You can generate multiple API tokens from your company settings.

Make sure to never share your API tokens or revoke them if you have any doubt it may have been compromised.

API tokens represents Winddle Users

The API token is tied to the person who created the token (or has been assigned to the token from the company settings). For instance, when creating a Project with a specific token, the owner will be internally set to the token's owner (and an actual different Project Manager can be set).

Including the Token in the Request Headers

The recommended way to include an identity in the request is to put the token in the request headers, using the Token authorization scheme defined in HTTP.

  curl -X GET -H "Authorization: Token token=bdc3cf2d7eb[....]df3ef1618f" \
    https://www.winddle.com/api/v1/products

Including the Token in the Request body (params)

Authenticating to the API could be done by including the key auth_api_token and the token as value as part of the params. For example:

curl -X POST -H "Content-Type: application/json" \
       -d '{"auth_api_token":"bdc3cf2d7eb[....]df3ef1618f", "name": "NewProduct"}' \
    https://www.winddle.com/api/v1/products

Or, using XML:

curl -X POST -H "Content-Type: application/xml" \
       -d '<?xml version="1.0" encoding="UTF-8"?>
           <product>
            <auth_api_token>bdc3cf2d7eb[....]df3ef1618f</auth_api_token>
            <name>NewProduct</name>
           </product>' \
    https://www.winddle.com/api/v1/products

Note that when using XML, the token must be included inside the root of the params.

Including the Token in the URL

When using the headers is inconvenient and there is no request body available (GET/DELETE), the last option is to put the token directly in the URL as an URL encoded parameter (auth_api_token).

curl -X GET https://www.winddle.com/api/v1/products?auth_api_token=bdc3cf2d7eb[....]df3ef1618f

Retrieving information about the logged in user

Once logged in, you can use the CurrentUser API endpoint to retrieve information about the logged in user.

API usage limits

By default, each registered company on Winddle is allowed 200 API calls / 24 hours.

Each page retrieving for paged API calls is accounted as a separate API call.

If you expect your usage to be higher than this limit, please get in touch with our sales.

Building requests

As a REST JSON/XML API, the way to access the various services is very straightforward.

Most of the resouces can be accessed with an url of the following form:

https://www.winddle.com/api/v1/<resource_name>/<resource_id>

The various parameters should be provided encoded as JSON/XML in the body of the request and the request headers should be set appropriatly. Some notes:

  • To use the JSON format for the requests/responses, the request header should contain a Content-Type set to application/json and a Accept set to at least application/json
  • To use the XML format for the requests/responses, the request header should contain a Content-Type set to application/xml and a Accept set to at least application/xml, text/xml
  • For most of the resources, the provided id may either be a winddle ID (unique integer) or a string that uniquely identify the resource. Please refer to the resource format to find out which field can be used as a replacement for the ID.

Errors

Whenever 'expected' errors occur while using the API, the following JSON response will be sent back:

{
  timestamp: see table below,
  error: {
    identifier: see table below (error identifier),
    message: summary message for the error
    details: additional details (usually, resource specific)
    full_messages: same as additional details all merged into one string, for convenience
  }
}

If the error happens after authentication, the response will also include the following information:

identity: {
  company: Token Company name,
  user: {
    email: Token owner email,
    full_name: Token owner first name / last name
  }
}

In case of unexpected error, the server will respond with a 500 error.

Below are the main HTTP error codes and identifier used as well as a summary description of the error.

HTTP Error code Error identifier Description
400 (bad request) invalid_value The value provided for one of the parameter isn't allowed
400 (bad request) invalid_operation The resource isn't in a state that allows this operation
401 (unauthorized) role_mismatch The token's owner roles (usually related to Checkpoint/Checklist) don't allow this operation to be performed
401 (unauthorized) unavailable_feature The token's company's subscription doesn't allow access to this feature
401 (unauthorized) authorizations The token's owner authorizations (usually 'company administrator') don't allow this operation to be performed
404 (not found) resource_matching The resource couldn't be found based on the provided id / alternative matching field
422 (unprocessable entity) resource_matching More than one resource could be matched with the provided identifier (the id should be used instead)
422 (unprocessable entity) invalid_record The provided values for the resource aren't valid and the resource modifications couldn't be saved. This usually means that the whole request had no impact, however, in some cases, trying to save may have had some side effects.

Resources

Products

The Product service allows to manage the products in your company. This is the service used by the Products page on Winddle.com.

The following services are available as nested services within a given Product:

Projects

Projects

The Project service allows to manage the projects in your company. This is the service used by the Projects page on Winddle.com.

Project lines

Project Lines are defined in the context of their Project, which is why the main service can be accessed at /api/v1/projects/project_id/line_items.

However, when editing a resource nested within a Project Line (checkpoints, price/quantity, comments, files, etc.), the main url will be /api/v1/line_items/line_item_id/service.

Here are the main nested services within a Project Line:

Checkpoints

Checkpoints of a given project line are modified through the LineItems/Checkpoints service, however, when dealing with Checkpoints on a larger scope (Company/User wide), there is also a Checkpoint service.

The main description of the checkpoint structure is on the LineItems/Checkpoints service page.

Just like project lines, Checkpoints also nest multiple dedicated services:

Contacts

  • Contact Companies main service allows to manage (create, update, delete...) company contacts (regardless of role) on Winddle.
  • Contact Users main service allows to manage (create, update, delete...) users contacts.

Other resources

The list below isn't comprehensive and will be regularly updated with more services we wish to open to our API users.

If there is something on Winddle you'd like to do from the API and you do not find the service page here or above, please get in touch with us!

  • Recent provides services related to pulling a list of recently modified Winddle objects (new files uploaded, checkpoints validated, new product/projects/project lines, etc.)
  • Search provides services related to searching Products, Projects, Users and Companies in Winddle.
  • Employees provides services to manage your company's employees.
  • Working Days provides services to manage the working days in your company.

Examples

Create a Product

In this example, we will create a new Product called "T-shirt", with a color "Blue"

Creating is a product is done by calling the /products API with a POST verb.

  curl -X POST -H 'Content-Type: application/json' \
    -d '{"auth_api_token":"ead96e[...]2eda2f8",
         "name":"T-Shirt", \
         "color":"blue"}' \
    http://www.winddle.com/api/v1/products

Here is the response from the server: (status code 200)

{
   "resource":{
      "type":"product",
      "action":"create"
   },
   "id":930,
   "tag_id":null,
   "name":"T-Shirt",
   "reference":null,
   "brand":null,
   "color":"blue",
   "size":null,
   "washcare":null,
   "material":null,
   "description":null,
   "theme":null,
   "collection":null,
   "dimensions":null,
   "px40":"/assets/fallback/default-product-px40.png",
   "px75":"/assets/fallback/default-product-px75.png",
   "px150":"/assets/fallback/default-product-px150.png",
   "px500":"/assets/fallback/default-product-px500.png",
   "archived":false,
   "category":null,
   "variants":[],
   "categories":[],
   "sizesets":[]
}

This product will now be available at http://www.winddle.com/products/930.

Create a Project + Project Line

Creating a Project (and its first project line, as a Project is mainly just a container for Project lines) is done simply by calling the /projects service with a POST verb.

In this example we'll reate a Project of type "Order" with the name/reference of an existing PO. This PO will re-use the product we just created in the previous example, and set a delivery date to June 1st 2014. We'll also re-use one of company defined workflow.

  curl -X POST -H 'Content-Type: application/json' \
        -d '{"auth_api_token":"ead96e[...]2eda2f8", \
             "name":"PO123466", \
             "reference":"PO123466", \
             "line_items":[ \
              {"product": 930,
               "deliver_at":"01-06-2014", \
               "template":"SIMPLEWF" } \
              ]}'
        http://www.winddle.com/api/v1/projects

Here is the response from the server: (status code 200)

{
   "resource":{
      "type":"project",
      "action":"create"
   },
   "id":375,
   "name":"PO123466",
   "company_id":1,
   "warehouse":null,
   "warehouse_code":null,
   "departure_place":null,
   "country_of_origin":null,
   "arrival_place":null,
   "transportation_mode":null,
   "payment_conditions":null,
   "factory":null,
   "incoterm":null,
   "project_type":"order",
   "reference":"PO123466",
   "laboratory":null,
   "archived":false,
   "final_customer":{},
   "supplier":{},
   "buyer":{ },
   "customs":[],
   "can_update":true,
   "can_manage":true,
   "line_items":[
      {
         "id":947,
         "line_item":{
            "id":947,
            "deliver_at":"2014-06-01",
            "start_at":"2014-02-18T03:29:45.655Z",
            "total_price":"0.0",
            "total_quantity":0,
            "season_code":null,
            "manufacturer":null,
            "reference":null,
            "packing_conditions":null,
            "locked":false,
            "archived":false
         },
         "product":{
            "id":930,
            "tag_id":null,
            "name":"T-Shirt",
            "reference":null,
            "brand":null,
            "color":"blue",
            "size":null,
            "washcare":null,
            "material":null,
            "description":null,
            "theme":null,
            "collection":null,
            "dimensions":null,
            "px40":"/assets/fallback/default-product-px40.png",
            "px75":"/assets/fallback/default-product-px75.png",
            "px150":"/assets/fallback/default-product-px150.png",
            "nc1000":"/assets/fallback/default-product-nc1000.png",
            "archived":false,
            "category":null,
            "variants":[],
            "categories":[],
            "sizesets":[],
            "customs":[],
            "used_variants":[]
         },
         "checkpoints":[
            {
               "id":34029,
               "name":"Inspection Booking",
               "master_checkpoint_id":19,
               "master_checklist_id":5,
               "status":null,
               "begin_at":"2014-04-10",
               "duration":1,
               "validated_at":null,
               "delay":0,
               "children":[34030],
               "parents":[],
               "delivery":false,
               "min_child_gap":0,
               "max_child_gap":0,
               "time_calculation_method":"fixed_date",
               "has_issue":false,
               "master_checkpoint":{
                  "id":19,
                  "name":"Inspection Booking",
                  "master_checklist_id":5,
                  "master_checklist":{
                     "id":5,
                     "name":"Default",
                     "order":4,
                     "icon":"icon-paper-plane"
                  }
               }
            }, ... //A few more checkpoints, as per the SIMPLEWF used
         ]
      }
   ]
}

This product will now be available at http://www.winddle.com/projects/375.

Validate a checkpoint

To validate a Checkpoint, the correct service is a PATCH request on /checkpoints/:id/validate

In this example, we will validate the first checkpoint of the project we have just created.

 curl -X PATCH -H 'Content-Type: application/json' \
                 -d '{"auth_api_token":"ead96e[...]2eda2f8"}' \
                 http://www.winddle.com/api/v1//line_items/947/checkpoints/34029/validate

Here is the response from the server: (status code 200)

{
  "resource":{
    "type":"checkpoint",
    "action":"validate"
  },
  "checkpoint":{
    "id":34029,
    "name":"Inspection Booking",
    "master_checkpoint_id":19,
    "master_checklist_id":5,
    "status":"validated",
    "begin_at":"2014-04-10",
    "duration":1,
    "validated_at":"2014-02-18T03:42:02.112Z",
    "delay":-52,
    "children":[34030],
    "parents":[],
    "delivery":false,
    "min_child_gap":0,
    "max_child_gap":0,
    "time_calculation_method":"fixed_date",
    "has_issue":false
  }
}