NAV undefined
undefined
bash python javascript

Introduction

Welcome to the 4ZeroPlatform API!

You can use our API to access 4ZeroPlatform API endpoints, which can get and set information on 4ZeroPlatform entities.

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.

Entities organization

4ZeroPlatform entities are organized in workspaces and each entity can be contained only in one workspace at a time.

Entities can be further organized into groups called projects. For each project, one ore more apps can be present functioning as user interfaces.

When a user signs up a personal workspace is created where all the user entities will live. Additionally a main project is created and a console app is added to it. The console app is needed to add new entities into the workspace.

For example, a company foo can have all its devices (the entities) assigned to a foo workspace. The workspace is specified in the URL as a subdomain like this:

https://foo.4zeroplatfom.com/

The console is reachable at:

https://foo.4zeroplatfom.com/main/console

In general, the URL format is:

https://<workspace>.4zeroplatfom.com/<project>/<app>

API endpoints are versioned and exposed at all levels of entities grouping:

For ease of use there are also app endpoints https://<workspace>.4zeroplatfom.com/<project>/<app>/v1/... that are equal in terms of entities grouping to project endpoints.

Authentication

Authentication to the 4ZeroPlatform is handled in two different ways: JWT tokens for web access and API keys for programmatic access. Authentication is also scoped to the workspace and project.

JWT Tokens

JWT tokens authenticate an user of the 4ZeroPlatform. A JWT Token is obtained after a successful login and must be sent in the Authorization header like this:

Authorization: Bearer <jwt-token>

JWT tokens expire after a while and are not usable anymore after a user logs out.

API Keys

API keys can be generated from the console app with a scope that will allow access to all the API endpoints of the workspace. API keys must be sent in the Authorization header just like a JWT Token. API keys do not expire unless a new API key is requested for the same scope, effectively expiring the previous API key.

User

Users are identified by an email and a nickname

Sign up

To sign up a user:

import requests

url = "https://<workspace>.4zeroplatform.com/v1/user/register"
body = {
    "username": <email>,
    "password": <password>,
    "nickname": <nickname>
    }
res = requests.post(url,json=body)
curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"username":<username>,"password":<password>,"nickname":<nickname>}' \
  https://<workspace>.4zeroplatform.com/v1/user/register
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/user/register',
    {
        "username":<username>,
        "password":<password>,
        "nickname":<nickname>
    })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "uid": u1234567890
    }
}

The sign up endpoint creates a new user

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/user/register

Body Parameters

Parameter Description
username The user email
password A valid password
nickname A nick name

Sign in

To sign in a user:

import requests

url = "https://<workspace>.4zeroplatform.com/v1/user/login"
res = requests.post(url,auth=(<username>,<password>))
curl --header "Content-Type: application/json" \
  --request GET \
  --user username:password \
  https://<workspace>.4zeroplatform.com/v1/user/login
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/user/login',
    {
        auth: {
            username:<username>,
            password:<password>
        }
    })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "token": <jwt-token>
    }
}

The sign in endpoint returns a JWT Token to be used in all API that require authenticated access.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/user/login

Generate API Key

To generate a new API key:

import requests

url = "https://<workspace>.4zeroplatform.com/v1/user/apikey"
res = requests.post(url,headers={"Authorization":"Bearer "+<jwt or api key>})
curl --request POST \
  --header "Content-Type: application/json" \
  --header "Authorization: Bearer <jwt or api key>" \ 
  https://<workspace>.4zeroplatform.com/v1/user/apikey
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/user/apikey',
    {
        headers: {
            'Auhtorization':'Bearer '+<jwt or api key>
        }
    })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "key": <api key>,
        "scope": <workspace>._._,
        "roles": [<list of roles>]
    }
}

The apikey endpoint returns a new apikey for the workspace. The roles associated with the key are predefined.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/user/apikey

Devices

Handler for creating or managing devices. Every device is identified by a unique id.

Registration

import requests

url = "https://<workspace>.4zeroplatform.com/v1/devices/"
body = {
    "zname": "MyDevice",
    "name": "MyDevice",
    "model": "4zerobox_v1",
    "category": "esp32",
    "on_chip_id": "ff123456abcdef",
    "zerynth_based": true
}
res = requests.post(url,headers={"Authorization":"Bearer xyzabc123"},json=body)
curl --request POST \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  --data '{"zname": "MyDevice", "name": "MyDevice", "model": "4zerobox_v1", "category": "esp32", "on_chip_id": "ff123456abcdef", "zerynth_based": true}' \
  https://<workspace>.4zeroplatform.com/v1/devices/
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/devices/', {
    "zname": "MyDevice",
    "name": "MyDevice",
    "model": "4zerobox_v1",
    "category": "esp32",
    "on_chip_id": "ff123456abcdef",
    "zerynth_based": true
  }, {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": "DEV1234567"
}

Register a new device into the current user and workspace. If the zerynth_based flag is set, the device is also registered into Zerynth using zname as a short name (note that this name can coincide with name).

The returned data contains the string representing an unique identifier for the device, used for manage this device in other endpoints.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/devices/

Body Parameters

Parameter Description
name A short name for the device
model The model of the used board
category The chip model of the board
on_chip_id The unique identifier of the board
zname A short name of the device for Zerynth
zerynth_based Boolean flag, if set the device is also registered in Zerynth

List devices

import requests

url = "https://<workspace>.4zeroplatform.com/v1/devices/"
res = requests.get(url,headers={"Authorization":"Bearer xyzabc123"})
curl --request GET \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  https://<workspace>.4zeroplatform.com/v1/devices/
const axios = require('axios');

axios.get('https://<workspace>.4zeroplatform.com/v1/devices/', {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": [
        {
            "last_seen": "2018-10-29T09:41:12.053000",
            "workspace": "u123123123",
            "enabled": true,
            "shard": 0,
            "total_messages": 165768,
            "online": true,
            "uid": "DEV123123abcde",
            "endpoints": [],
            "ordering": 0,
            "provisioning": {
                "endpoint": "abcdef.iot.eu-west-1.amazonaws.com",
                "zerynth_device": false
            },
            "mqtt_enabled": true,
            "name": "MyDevice",
            "mqtt": {},
            "model": "4zerobox_v1",
            "daily_messages": 8112,
            "push_enabled": true
        },
        <devices list>,
        ...
    ]
}

Get a list of all devices registered in this workspace.

HTTP Request

GET https://<workspace>.4zeroplatform.com/v1/devices/

Get single device

import requests

url = "https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>"
res = requests.get(url,headers={"Authorization":"Bearer xyzabc123"})
curl --request GET \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>
const axios = require('axios');

axios.get('https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>', {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "enabled": true,
        "total_messages": 165924,
        "model": "4zerobox_v1",
        "online": true,
        "daily_messages": 8268,
        "ordering": 0,
        "name": "DEV123123abcde",
        "provisioning": {
            "endpoint": "abcdef.iot.eu-west-1.amazonaws.com",
            "zerynth_device": false
        },
        "push_enabled": true,
        "uid": "DEV123123abcde",
        "shard": 0,
        "workspace": "u1234567890",
        "last_seen": "2018-10-29T09:41:12.053000",
        "mqtt_enabled": true,
        "endpoints": [],
        "mqtt": {
            "endpoints": {
                "ws": "ws://u1234567890:apikey@abc.4zeroplatform.com:8083",
                "wss": "wss://u1234567890:apikey@abc.4zeroplatform.com:8084",
                "std": "mqtt://u1234567890:apikey@abc.4zeroplatform.com:1883",
                "ssl": "mqtts://u1234567890:apikey@abc.4zeroplatform.com:8883",
            },
            "topics": {
                "data": "/u1234567890/devices/DEV123123abcde",
                "all_events": "/u1234567890/device_events/#",
                "all_data": "/u1234567890/devices/#",
                "events": "/u1234567890/device_events/DEV123123abcde"
            }
        }
    }
}

Get details for a single device.

HTTP Request

GET https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>

Edit device settings

import requests

url = "https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>"
body = {
    "ordering": 1,
    "name": "MyNewDevice",
    "mqtt_enabled": true,
    "chunk_enabled": true,
    "enabled": true,
    "endpoints": [
        {
            "endpoint": "https://mywebsite.com/device",
            "token": "my custom token"
        }
    ]
}
res = requests.put(url,headers={"Authorization":"Bearer xyzabc123"},json=body)
curl --request PUT \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  --data '{"ordering": 1, "name": "MyNewDevice", "mqtt_enabled": true, "chunk_enabled": true, "enabled": true, "endpoints": [{"endpoint": "https://mywebsite.com/device", "token": "my custom token"}]}' \
  https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>
const axios = require('axios');

axios.put('https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>', {
    "ordering": 1,
    "name": "MyNewDevice",
    "mqtt_enabled": true,
    "chunk_enabled": true,
    "enabled": true,
    "endpoints": [
        {
            "endpoint": "https://mywebsite.com/device",
            "token": "my custom token"
        }
    ]
  }, {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns status code 200 if the request succeded.

Update a device settings, every parameter is optional: only the ones to be updated should be specified in the request.

HTTP Request

PUT https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>

Body Parameters

Parameter Description
ordering Integer used for ordering in lists
name Nickname for the device
mqtt_enabled Bool for enabling/disabling MQTT data transmission
chunk_enabled Bool for enabling/disabling data sending to webhooks
enabled Bool for enabling/disabling entirely the device
endpoints List of webhooks object, containing an endpoint and a custom token

Provision a device

import requests

url = "https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/provision"
body = {
    "csr": "MY CSR"
}
res = requests.post(url,headers={"Authorization":"Bearer xyzabc123"},json=body)
curl --request POST \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  --data '{"csr": "MY CSR"}' \
  https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/provision
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/provision', {
    "csr": "MY CSR"
  }, {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "certificate": "ABCDEF12341234",
        "endpoint": "abcabc.amazonaws.com",
        "thing": "xyzqwert",
        "solution": "fzp"
    }
}

Send a CSR and get a certificate, together with other parameters, needed to send data to AWS services.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/provision

Body Parameters

Parameter Description
csr Your CSR for AWS

FOTA update

import requests

url = "https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/fota"
body = {
    "vm_slot": 0,
    "bc_slot": 1,
    "fw": {},
    "vm_uid": "abcdef1234"
}
res = requests.post(url,headers={"Authorization":"Bearer xyzabc123"},json=body)
curl --request POST \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  --data '{"vm_slot": 0, "bc_slot": 1, "fw": {}, "vm_uid": "abcdef1234"}' \
  https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/fota
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/fota', {
    "vm_slot": 0,
    "bc_slot": 1,
    "fw": {},
    "vm_uid": "abcdef1234"
  }, {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        TODO
    }
}

Update a Zerynth firmware via internet of a specific device.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/device/<DEVUID>/fota

Body Parameters

Parameter Description
vm_slot The VM slot to be updated
bc_slot One of the bytecode slot
fw The new firmware to be flashed
vm_uid The VM id of the device

Virtual Machines

Zerynth Virtual Machines are created and managed through the 4ZeroPlatform API, and are identified by a unique ID.

Create a new Zerynth VM

import requests

url = "https://<workspace>.4zeroplatform.com/v1/vms"
body = {
    "name": "My Device",
    "dev_uid": "DEV12345",
    "rtos": "esp32-rtos",
    "features": [
        "ota"
    ]
}
res = requests.post(url,headers={"Authorization":"Bearer xyzabc123"},json=body)
curl --request POST \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  --data '{"name": "My Device", "dev_uid": "DEV12345", "rtos": "esp32-rtos", "features": ["ota"]}' \
  https://<workspace>.4zeroplatform.com/v1/vms
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/vms', {
    "name": "My Device",
    "dev_uid": "DEV12345",
    "rtos": "esp32-rtos",
    "features": [
        "ota"
    ]
  }, {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "uid": "VMID123123"
    }
}

Request the creation of a new Zerynth Virtual Machine for the specified device. The unique ID of this virtual machine is returned in the response.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/vms

Body Parameters

Parameter Description
name The device nickname
dev_uid The device unique id
rtos The requested RTOS version
features List of requested VM extra features

Download a VM

import requests

url = "https://<workspace>.4zeroplatform.com/v1/vms/<VM_ID>"
res = requests.get(url,headers={"Authorization":"Bearer xyzabc123"})
curl --request GET \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  https://<workspace>.4zeroplatform.com/v1/vms/<VM_ID>
const axios = require('axios');

axios.get('https://<workspace>.4zeroplatform.com/v1/vms/<VM_ID>', {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "vm": <JSON containing the virtual machine>
    }
}

Download an already created virtual machine. This can be then virtualized (flashed) into a device using Zerynth.

HTTP Request

GET https://<workspace>.4zeroplatform.com/v1/vms/<VM_ID>

Remote Procedure Call (RPC)

Make a RPC

import requests

url = "https://<workspace>.4zeroplatform.com/v1/rpcs"
body = {
    "dev_uid": "DEV123123",
    "method": "mymethod",
    "args": [
        0,
        20
    ]
}
res = requests.post(url,headers={"Authorization":"Bearer xyzabc123"},json=body)
curl --request POST \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  --data '{"dev_uid": "DEV123123", "method": "mymethod", "args": [0, 20]}' \
  https://<workspace>.4zeroplatform.com/v1/rpcs
const axios = require('axios');

axios.post('https://<workspace>.4zeroplatform.com/v1/rpcs', {
    "dev_uid": "DEV123123",
    "method": "mymethod",
    "args": [
        0,
        20
    ]
  }, {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": "RPCID123123"
}

Register a new RPC method into the specified device. The unique RPC id will be returned as a response if the registration was successfully.

A RPC can be async, if there are no results to be awaited. Otherwise, after a RPC is sent to the device the result is forwarded to the appropriate MQTT channel.

HTTP Request

POST https://<workspace>.4zeroplatform.com/v1/rpcs

Body Parameters

Parameter Description
dev_uid Device id of the target device
method Method name to be called
args List of arguments for the method
timeout Optional, timeout (in seconds) for waiting a result from the device
async Optional, bool, if set the result is not awaited

Get RPC status

import requests

url = "https://<workspace>.4zeroplatform.com/v1/rpc/<RPC_ID>"
res = requests.get(url,headers={"Authorization":"Bearer xyzabc123"})
curl --request GET \
  --header "Authorization: Bearer xyzabc123" \
  --header "Content-Type: application/json" \
  https://<workspace>.4zeroplatform.com/v1/rpc/<RPC_ID>
const axios = require('axios');

axios.get('https://<workspace>.4zeroplatform.com/v1/rpc/<RPC_ID>', {
    "headers": {
      "Authorization": "Bearer xyzabc123"
    }
  })
  .then(response => {
    console.log(response);
  })
  .catch(error => {
    console.log(error);
  });

The above snippet returns JSON structured like this:

{
    "data": {
        "async": true,
        "method": "mymethod",
        "finished": null,
        "status": "sent",
        "create_date": "2018-10-26T09:23:00.033875",
        "uid": "123abc12345",
        "sent": "2018-10-26T09:23:03.654631",
        "result": null,
        "args": [0, 20],
        "timeout": 3600,
        "dev_uid": "DEV123123"
    },
}

Get the current status for an ongoing RPC. This method can be used for checking if a timeout or an error occurred while sending the RPC to the device

HTTP Request

GET https://<workspace>.4zeroplatform.com/v1/rpc/<RPC_ID>

Errors

Every successful JSON response is in the format:

{
    "status": "success",
    "code": 200,
    "data": <a JSON object or array>
}

Instead, if an error occurred or the request was malformed, the response is in the format:

{
    "status": "error",
    "code": <err_code>,
    "msg": "A description of the error"
}

See the code column for the structure of the response JSON objects.

Our API uses the following error codes:

Error Code Meaning
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
405 Method Not Allowed
500 Internal Server Error
503 Service Unavailable