NAV
shell

Introduction

Welcome to the SmartMES API! You can use our API to access SmartMES API endpoints, which can get information on different resources like production orders, states or even plugin based resources.

We have language bindings in Shell, Java, JavaScript! Java and JavaScript clients will come soon. You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.

Version

This document shows the current API version, which is v1.

Endpoint and Schema

The API is normally accessible via the /api endpoint, which is located under the root of the system. If you use a domain name, your endpoint can be found here:

http://www.example.com/api/

Since SmartMES may also be started within a private network, it may also be accessible via a certain IP and could also have a port. So, the API can be found like this:

http://10.0.0.1:8080/api/

Since it is not decidable, we’ll use the request URL path /api in all following examples. So, you have to prepend your hostname/IP and port to find your endpoint.

Plugins

SmartMES has a plugin machanism where a plugin can publish its own endpoint. All plugin endpoitns are located under /api/plugin.

Authentication

To authorize, use this code:


# With shell, you can just pass the correct header with each request
curl "api_endpoint_here"
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHAiOiIwOTAyNTM0MzhmNGM0Zm
  FlODU0NjBhNDc0YTE4MTdmZiIsImRhdGUiOiJUaHUsIDI4IEZlYiAyMDE2IDEyOjMyOjEyICswMDAwIiwidXJsIjoiL2F
  waS9wbHVnaW4vYXBwLWNvbm5lY3Rvci9vcmRlcnMvMSJ9.aQ282b3X-icxXPmIYAplqmgcSUwFgaz00DGag-iRxxs"

Make sure to replace eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHAiOiIwOTAyNTM0MzhmNGM0Zm FlODU0NjBhNDc0YTE4MTdmZiIsImRhdGUiOiJUaHUsIDI4IEZlYiAyMDE2IDEyOjMyOjEyICswMDAwIiwidXJsIjoiL2F waS9wbHVnaW4vYXBwLWNvbm5lY3Rvci9vcmRlcnMvMSJ9.aQ282b3X-icxXPmIYAplqmgcSUwFgaz00DGag-iRxxs with your authentication token.

SmartMES uses API keys to allow access to the API. You will need a pair of keys, an access key ID (called API-key) and a secret access key (called API-secret). You have to obtain this key pair from the SmartMES system before. You can find this under settings and applications.

Authentication Token: JSON Web Tokens (JWT)

The main concept is to use the API-key as an identifier and use the API-secret to create a signature of the request. The API-key and the signature must be put into the header of the request. The token is a JSON Web Token (JWT) (see also https://jwt.io).

A JWT consists of three parts: A header, a payload and the signature. To create a token, following steps are performed:

  1. The header is Base64 URL encoded
  2. The payload is Base64 URL encoded
  3. The encoded header and payload are concatinated using a “.”
  4. A signature of the concatinated header and payload is created using the API-secret.
  5. The signature is appended to the encoded header and payload using a “.”

So the authentication token should have this form:

<encoded header>.<encoded payload>.<signature>

In this example, we will use the follwing key pair:

Name Value
API-key 28379bhedi763b42i73t6
API-secret jn937848ugg7s6t3u4b76gf

JWT - Header

The header is a simple JSON object that contains the algorithm that is used for the signature and the token type. We only use HMAC-SHA256 (HS256) to create the signature and the token type is always JWT. So, the content of the header is always the same.

A JWT header looks like this

{
  "alg": "HS256",
  "typ": "JWT"
}

The Base64 URL encoded header is therefore (always) eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9, if your header does not contain any blanks and is equal to {"alg":"HS256","typ":"JWT"}.

Although the alg and typis always the same, it is highly recommended to encode the header yourself, because the encoded header must match to the one that is used for signature. The reason is, that the header could be, for example, {"alg":"HS256","typ":"JWT"} or even {"alg":"HS256", "typ":"JWT"}. Both headers describe the same algorithm and type, but will create two different encoded headers, which are eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 and eyJhbGciOiJIUzI1NiIsICAgICJ0eXAiOiJKV1QifQ== in this case. So, be aware of this behavior (or just use one of the existing JWT libraries).

JWT - Payload

The payload describes “who, when and what”. It contains the following parts:

  1. the apikey, which should be your Api-Key.
  2. the date, which is the current date of the request using a ISO 8601 token
  3. the url, which is the current URL of the endpoint (without the host) you want to request.

The date and url will be checked on the server, so that you cannot reuse the same payload for different endpoints or even recurring calls. We do this for security reasons, because a stolen token cannot be used more than once.

A JWT payload looks like this

{
  "apikey": "28379bhedi763b42i73t6",
  "date": "2016-02-28T12:48:15+01:00",
  "url": "/api/plugin/app-connector/orders/1"
}

The Base64 URL encoded version of the example payload is eyJhcGlrZXkiOiIyODM3OWJoZWRpNzYzYjQyaTczdDYiLCJkYXRlIjoiMjAxNi0wMi0yOFQxMjo0ODox NSswMTowMCIsInVybCI6Ii9hcGkvcGx1Z2luL2FwcC1jb25uZWN0b3Ivb3JkZXJzLzEifQ.

JWT - Signature Creation

The signature is created by using the API-secret and the concatinated encoded header and encoded payload. Both parts are concatinated with “.”. This is sign with HMAC-SHA256 algorithm using the API-secret.

A pseudo code example with a function called BASE64ENCODE(content) and a function for signing like HMACSHA256(content, secret)for the three variables called header, payload and apisecret would be: HMACSHA256(BASE64ENCODE(header)+"."+BASE64ENCODE(payload),apisecret)

According to the examples above, we have the encoded header

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

and the encoded payload

eyJhcGlrZXkiOiIyODM3OWJoZWRpNzYzYjQyaTczdDYiLCJkYXRlIjoiMjAxNi0wMi0yOFQxM jo0ODoxNSswMTowMCIsInVybCI6Ii9hcGkvcGx1Z2luL2FwcC1jb25uZWN0b3Ivb3JkZXJzLzEifQ

These are concatinated:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlrZXkiOiIyODM3OWJoZWRpNzYzYjQyaTczdDYiLCJkYXRlIjo iMjAxNi0wMi0yOFQxMjo0ODoxNSswMTowMCIsInVybCI6Ii9hcGkvcGx1Z2luL2FwcC1jb25uZWN0b3Ivb3JkZXJzLzEifQ

Afterwards, the signature is created. Using the API-secret, which is for example jn937848ugg7s6t3u4b76gf, the signature would be kFx3vRp7aujSe-1LEpVN8SbpmypqdjZ1xatR5G-O7kE. This signature is appeded to the concatinated header/payload with a “.”. Therefore, the final JWT is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJhcGlrZXkiOiIyODM3OWJoZWRpNzYzYjQyaTczdDYiLCJkYXRlIjoiMjAxNi0wMi0 yOFQxMjo0ODoxNSswMTowMCIsInVybCI6Ii9hcGkvcGx1Z2luL2FwcC1jb25uZWN0b3Ivb3JkZXJzLzEifQ. kFx3vRp7aujSe-1LEpVN8SbpmypqdjZ1xatR5G-O7kE.

Using the Authentication Token

SmartMES expects for the authentication token to be included in all API requests to the server in a header that looks like the following:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcGlrZXkiOiIyODM3OWJoZWRpNzYzYjQyaTczdDYiLCJkYXRl IjoiMjAxNi0wMi0yOFQxMjo0ODoxNSswMTowMCIsInVybCI6Ii9hcGkvcGx1Z2luL2FwcC1jb25uZWN0b3Ivb3JkZX JzLzEifQ.kFx3vRp7aujSe-1LEpVN8SbpmypqdjZ1xatR5G-O7k

Plugins

The SmartMES can be extended by plugins. Each plugin can publish its own endpoint. The endpoint is always located under /api/plugin/<plugin-id> where <plugin-id> is the unque ID of the plugin. Therefore, it is possible that two or more different plugins can publish the same endpoint name.

For example, there could be two plugins with the IDs example-plugin and acme-plugin. Both pubslish an endpoint called info. Then you’ll find two endpoints: /api/plugin/example-plugin/info and /api/plugin/acme-plugin/info.

All plugin-based endpoints are also secured by the SmartMES authorization token security. Therefore, you also have to create the token and put it into the header.

In the following, the core plugins are listed - thus this API may not describe the complete list of possibilities!

App-Connector Plugin

The ID of this plugin is app-connector. It offers some core possibilities to bind external applications to SmartMES, e.g. for creating new production orders.

Production Order Resource

This part describes all entities and their fields of a production order, its production order items and additional production information.

Production Order

A prodcution order describes all information for one order. It mainly consists of a list of order items (see below).

Field Description
id Unique resource ID of the order
number The business-related number of the production order
state The state of this production order (see next section)
orderDate The date when the production order was created.
caseHandler The person who is responsible for this procution order
orderer The personen who ordered this production order
productionOrderItems A list of production order items

Production Order State

A Production order can be in one of the following states:

State Description
New The production order was created and not yet approved
Approved The production order was approved, but no production order item was started for production yet
Started One of the production order items was started for production
Complete All production order items were produced and the production order is complete
Incomplete One of the production order items were aborted, so that the production order is incomplete
Aborted The production order was aborted, which forces all items to be aborted as well

A state is given by the system and cannot be set (e.g. when creating a new production order).

Production Order Item

A production order item is one product that should be produced. The system identifies and schedules this production order item using a BOM (bill of material). A BOM is identified by a identifier and revision. Therefore, a BOM (which is the combination of identifier and revision) is a unique and reusable description how the product should be moved through the different production steps within the factory. A BOM also describes several production information, e.g. related CAD or CAM files.

Field Description
id Unique resource ID of the item
name The name of the product
articlenumber The number of the product
count The quantity of items
dueDate The expected time until the product should be produced
priority A number between 0 and 100 to describe the priority of this product
identifier The identifier of the BOM
revision The revision of the BOM
remarks Any additional remarks for this item
productionInformations A list of additional production information (see below)

Production information

A production information allows to put additional key-value sets to each article item. It just contains of an unique key and a value. This is, for example, useful for adding necessary informations like the material or to define a certain tool.

Field Description
id Unique resource ID of the information
key The name of the information
value The value of the information

Get All Production Orders

curl "/api/app-connector/orders"
  -H "Authorization: Bearer <your authorization token>"

The above command returns JSON structured like this:

[
  {
    "id":1,
    "number":"7887580",
    "state": "Started",
    "orderDate":"2016-01-15",
    "caseHandler":null,
    "orderer":"John Doe",
    "productionOrderItems":   
      [
        {
          "id": 1,
          "name":"Product A",
          "description":"A simple product",
          "articlenumber":"78165198763",
          "count": 39,
          "dueDate":"2016-02-15",
          "priority":86,
          "identifier":"ABC_123",
          "revision":"A1",
          "remarks":"No remarks",
          "productionInformations":[]
        },
        {
          "id": 2,
          "name":"Product B",
          "description":"Another product",
          "articlenumber":"9834736763",
          "count": 223,
          "dueDate":"2016-03-11",
          "priority": 33,
          "identifier": "AB8_3DE",
          "revision":"B6",
          "remarks":"",
          "productionInformations":
            [
              {
                "id": 1,
                "key": "Matrial",
                "value": "X2CrNi12"
              }
            ]
          }
        ]
    },
    {
      "id":2,
      "number":"7887581",
      "state": "Approved",
      "orderDate":"2016-02-15",
      "caseHandler":"John Doe",
      "orderer": "Max Musterman",
      "productionOrderItems":   
        [          
          {
            "id": 2,
            "name":"Product B",
            "description":"Another product",
            "articlenumber":"9834736763",
            "count": 3,
            "dueDate":"2016-03-11",
            "priority": 33,
            "identifier": "AB8_3DE",
            "revision":"B6",
            "remarks":"",
            "productionInformations":
              [
                {
                  "id": 1,
                  "key": "Matrial",
                  "value": "X2CrNi12"
                }
              ]
            }
          ]
      }
    ]

This endpoint retrieves all production orders.

HTTP Request

GET /api/app-connector/orders

Query Parameters

This endpoint has no query parameters

Get one Production Order

curl "/api/app-connector/orders/2"
  -H "Authorization: Bearer <your authorization token>"

The above command returns JSON structured like this:

{
  "id":2,
  "number":"7887581",
  "state": "Approved",
  "orderDate":"2016-02-15",
  "caseHandler":"John Doe",
  "orderer": "Max Musterman",
  "productionOrderItems":   
    [          
      {
        "id": 2,
        "name":"Product B",
        "description":"Another product",
        "articlenumber":"9834736763",
        "count": 3,
        "dueDate":"2016-03-11",
        "priority": 33,
        "identifier": "AB8_3DE",
        "revision":"B6",
        "remarks":"",
        "productionInformations":
          [
            {
              "id": 1,
              "key": "Matrial",
              "value": "X2CrNi12"
            }
          ]
        }
      ]
  }

This endpoint retrieves a specific production order.

HTTP Request

GET /api/app-connector/orders/<ID>

URL Parameters

Parameter Description
ID The ID of the production order to retrieve

Create a Production Order

curl "/api/app-connector/orders"
  -X POST
  -H "Authorization: Bearer <your authorization token>"
  -d '{    
    "number":"7887583",
    "orderDate":"2016-03-11",
    "caseHandler":"John Doe",
    "orderer": "Max Musterman",
    "productionOrderItems":   
      [          
        {          
          "name":"Product C",
          "description":"Yet another product",
          "articlenumber":"4342123123",
          "count": 10,
          "dueDate":"2016-03-11",
          "priority": 33,
          "identifier": "ABC",
          "revision":"A1",
          "remarks":"",
          "productionInformations":
            [
              {                
                "key": "Tool",
                "value": "M1"
              }
            ]
          }
        ]
    }'

The above command returns JSON structured like this:

{
  "id":12,
  "number":"7887583",
  "state": "New",
  "orderDate":"2016-03-11",
  "caseHandler":"John Doe",
  "orderer": "Max Musterman",
  "productionOrderItems":   
    [          
      {
        "id": 43,
        "name":"Product C",
        "description":"Yet another product",
        "articlenumber":"4342123123",
        "count": 10,
        "dueDate":"2016-03-11",
        "priority": 33,
        "identifier": "ABC",
        "revision":"A1",
        "remarks":"",
        "productionInformations":
          [
            {
              "id": 14,
              "key": "Tool",
              "value": "M1"
            }
          ]
        }
      ]
  }

This endpoint creates a production order.

HTTP Request

POST /api/app-connector/orders

URL Parameters

This endpoint has no URL parameters.

Errors

For each request, the API returns a HTTP code. If everything is ok, it will be 200. If a request was not successfull, the API uses a set of HTTP error codes for different failures. If the HTTP itself was correct, but the given information was not appropriate for SmartMES, a Bad Request with a more detailed API error code is returned.

HTTP Errors

The API uses the following HTTP error codes:

HTTP Error Code Meaning
400 Bad Request – Your request is faulty. See API Error Codes for details.
401 Unauthorized – Your authentication token is wrong
403 Forbidden – You are not allowed to use this endpoint
404 Not Found – The specified entity could not be found
405 Method Not Allowed – You tried to access a method that does not exist
406 Not Acceptable – You requested a format that isn’t json
410 Gone – The endpoint has been removed
500 Internal Server Error – We had a problem with our server. Try again later.
503 Service Unavailable – We’re temporarially offline for maintanance. Please try again later.

API Errors

The API uses the following special error codes, which are part of Such an error code is nested in a result with a bad request HTTP error.

An example, if the posted JSON object was not correctly formatted (e.g. a missing comma)

{
"code": 1000,
"message": "Invalid JSON object. Object could not be parsed"
}
API Error Code Name Meaning
1000 Invalid object Your JSON object that was sent using POST or PUT, was not correctly formatted for the expected object.
1010 Object could not be written The requested object could not be written into a JSON object.
1020 Object could not be saved The given object could not be saved.
1030 Required attributes missing The endpoint expects one or more attributes to be present, but they are missing.
1040 Attributes are invalid The given attributes are invalid, e.g. if one does not match the type or expected ranges.
1050 Object not unique The object with the given ID (which must be unique) already exists.
1060 Attribute not unique Object has an attribute that is already used, although it should be unique.