Link Search Menu Expand Document

REST API

Nuvla provides a uniform and extensible HTTP-based RESTful API, for the management of Nuvla resources. A Nuvla resource can be anything you can perform an action on, through Nuvla, like your own user profile, a Nuvla application, credentials, etc.

Users have at their disposal all the usual CRUD (Create, Read, Update, Delete) operations, plus Searching and Querying.

Action HTTP Method Target
Search GET or PUT resource collection
Add (create) POST resource collection
Read GET resource
Edit (update) PUT resource
Delete DELETE resource

Finally, due to its versatility, Nuvla’s API also provide custom operations for certain resources. These will be covered individually in the subsections below.

Here are a few examples on how to construct the different HTTP requests:

  • GET all the resources of a specific type:

    GET /api/<resource-name>

  • GET a specific resource:

    GET /api/<resource-name>/<resource-uuid>

  • CREATE a new resource:

    POST       /api/<resource-name>
      HEADERS  Content-type:application/json
      DATA     <JSON resource>
    
  • EDIT an existing resource:

    PUT        /api/<resource-name>/<resource-uuid>
      HEADERS  Content-type:application/json
      DATA     <JSON with the attribute name and value to be changed>
    
  • DELETE a resource:

    DELETE /api/<resource-name>/<resource-uuid>

Understanding the Nuvla REST API output format

All the Nuvla API calls will return a JSON output, and you’ll notice that all of these outputs contain a set of common attributes:

  • id: unique resource identifier, defined by the API server
  • acl: fine-grained access-control list, used for managing authorization process for each resource and its collections of resources. If not defined by the user, the API server will default it based on the requesting user credentials.
  • created: timestamp of creation, defined by the API server
  • updated: timestamp of the last update, defined by the API server
  • resource-type: type of resource, defined by the API server
  • operations: set of available operations for that resource, defined by the API server
  • name: optional user-friendly name for a specific resource, defined by the user or defaulted to None if undefined
  • description: optional verbose description for a specific resource, defined by the user or defaulted to None if undefined

API Syntax

The Nuvla REST API endpoints are constructed with the following pattern:

/api/<resource-name>/<resource-uuid>/<action>/

where

  • <resource-name> is the Kebab Case name of the resource collection you’re accessing,
  • <resource-uuid> is the unique identifier for the specific resource you’re managing,
  • <action> is a custom additional operation that might be allowed for that resource.

On top of that, Nuvla’s REST API also offers searching and querying through a parameter-based set of keywords:

/api/<resource-name>?param=value&param=value...

where

Parameter Description Examples
filter Used to return only the set of resources that have an attribute matching a certain value ?filter=name="my-resource"

?filter=people/gender!="male" and people/age>=21

?filter=application-name^="my-app-"
orderby To order the returned resources by the specified attribute ?orderby=created:desc

?orderby=people/surname:asc
aggregation On top of the requested resources, it will also return on-the-fly aggregations based on the specified function. Available functions: avg, max, min, sum, cardinality, terms, stats, extendedstats, percentiles, value_count, missing ?aggregation=avg:people/age
last and first Returns a range of resources by setting the first and last (1-based) query parameters ?first=10&last=20
select Selects only certain attributes to be returned by the server. Avoiding sending information that will not be useful reduces the load on the network and the server ?select=people/id

Resources

Resources are managed individually, which means that the data schemas and available operations might defer from one to the other. These options are all explained and exemplified in the following sections.

cloud-entry-point

allowed:
GET
/api/cloud-entry-point

The primary directory of resources is the Cloud Entry Point (CEP), which contains a list of named resource collections and their URLs (in the href field) relative to the baseURI value. The CEP also contains some other metadata.

The endpoint is accessible for all registered and anonymous Nuvla users.


Examples

Get the cloud entry point
GET
/api/cloud-entry-point

curl https://nuvla.io/api/cloud-entry-point
Response:
{
  "acl" : {
    "view-acl" : [ "group/nuvla-anon" ],
    "view-meta" : [ "group/nuvla-anon" ],
    "view-data" : [ "group/nuvla-anon" ],
    "owners" : [ "group/nuvla-admin" ]
  },
  "id" : "cloud-entry-point",
  "resource-type" : "cloud-entry-point",
  "created" : "2019-06-24T13:01:15.720Z",
  "updated" : "2019-06-24T13:01:15.720Z",
  "base-uri" : "https://nuvla.io/api/",
  "collections" : {
    "nuvlabox" : {
      "href" : "nuvlabox"
    },
    "module-application" : {
      "href" : "module-application"
    },
    "session-template" : {
      "href" : "session-template"
    },
    "email" : {
      "href" : "email"
    },
    "cloud-entry-point" : {
      "href" : "cloud-entry-point"
    },
    "group" : {
      "href" : "group"
    },
    "infrastructure-service-template" : {
      "href" : "infrastructure-service-template"
    },
    "resource-metadata" : {
      "href" : "resource-metadata"
    },
    "data-record" : {
      "href" : "data-record"
    },
    "data-object" : {
      "href" : "data-object"
    },
    "user-identifier" : {
      "href" : "user-identifier"
    },
    "notification" : {
      "href" : "notification"
    },
    "infrastructure-service" : {
      "href" : "infrastructure-service"
    },
    "credential" : {
      "href" : "credential"
    },
    "data-object-public" : {
      "href" : "data-object-public"
    },
    "credential-template" : {
      "href" : "credential-template"
    },
    "data-record-key-prefix" : {
      "href" : "data-record-key-prefix"
    },
    "data-object-generic" : {
      "href" : "data-object-generic"
    },
    "configuration-template" : {
      "href" : "configuration-template"
    },
    "module-component" : {
      "href" : "module-component"
    },
    "module" : {
      "href" : "module"
    },
    "nuvlabox-peripheral" : {
      "href" : "nuvlabox-peripheral"
    },
    "voucher-report" : {
      "href" : "voucher-report"
    },
    "data-object-template" : {
      "href" : "data-object-template"
    },
    "infrastructure-service-group" : {
      "href" : "infrastructure-service-group"
    },
    "event" : {
      "href" : "event"
    },
    "user-template" : {
      "href" : "user-template"
    },
    "deployment-log" : {
      "href" : "deployment-log"
    },
    "deployment" : {
      "href" : "deployment"
    },
    "group-template" : {
      "href" : "group-template"
    },
    "data-record-key" : {
      "href" : "data-record-key"
    },
    "configuration" : {
      "href" : "configuration"
    },
    "deployment-parameter" : {
      "href" : "deployment-parameter"
    },
    "voucher" : {
      "href" : "voucher"
    },
    "nuvlabox-status" : {
      "href" : "nuvlabox-status"
    },
    "evidence-record" : {
      "href" : "evidence-record"
    },
    "callback" : {
      "href" : "callback"
    },
    "data-set" : {
      "href" : "data-set"
    },
    "user" : {
      "href" : "user"
    },
    "session" : {
      "href" : "session"
    },
    "job" : {
      "href" : "job"
    }
  }
}

credential

allowed:
POST
GET
PUT
DELETE
/api/credential/uuid

The credential resource is used to save all the credentials necessary to manage your Nuvla resources. From API keys, to Container Orchestration Engine credentials, TLS certificates, etc. Most of the credentials are expected to be provided by the user, some are generated by Nuvla (e.g. API key).


Examples

Generate an API key credential
POST
/api/credential

curl -XPOST https://nuvla.io/api/credential -H 'content-type:application/json' -b cookies -d '
{
  "template": {
    "method": "generate-api-key",
    "ttl": 0,
    "href": "credential-template/generate-api-key"
  }
}
'

Response:
{
  "status" : 201,
  "message" : "credential/<key_uuid> created",
  "resource-id" : "credential/<key_uuid>",
  "secret-key" : "<secret>"
}
Docker Swarm token credential
POST
/api/credential

curl -XPOST https://nuvla.io/api/credential -H 'content-type:application/json' -b cookies -d '
{
  "template": {
    "parent": "infrastructure-service/<UUID of your Docker Swarm Infrastructure in Nuvla>",
    "method": "swarm-token",
    "href": "credential-template/swarm-token",
    "scope": "WORKER | MANAGER",
    "token": "abcs1234token"
  }
}
'

Response:
{
  "status" : 201,
  "message" : "credential/92dc58ce-15c2-4140-acc9-cff07ea47ba5 created",
  "resource-id" : "credential/92dc58ce-15c2-4140-acc9-cff07ea47ba5"
}
Infrastructure Service S3 credential
POST
/api/credential

curl -XPOST https://nuvla.io/api/credential -H 'content-type:application/json' -b cookies -d '
{
  "name": "S3 credential",
  "description": "S3 credential",
  "template": {
    "href": "credential-template/infrastructure-service-minio",
    "parent": "infrastructure-service/<UUID of the S3 Infrastructure in Nuvla>",
    "access-key": "",
    "secret-key": ""
  }
}
'

Response:
{
  "status" : 201,
  "message" : "credential/992fd969-d14b-4d55-967a-094bbae5fc1a created",
  "resource-id" : "credential/992fd969-d14b-4d55-967a-094bbae5fc1a"
}
Infrastructure Service Docker Swarm HTTP API credential
POST
/api/credential

curl -XPOST https://nuvla.io/api/credential -H 'content-type:application/json' -b cookies -d '''
{
    "name": "Docker Swarm",
    "description": "Docker Swarm",
    "template": {
        "href": "credential-template/infrastructure-service-swarm"
        "parent": "infrastructure-service/<UUID of the Docker Swarm Infrastructure in Nuvla>",
        "key": "client-private-certificate",
        "ca": "ca-public-certificate",
        "cert": "client-public-certificate",
    }
}
'''

Response:
{
  "status" : 201,
  "message" : "credential/530f1429-fd41-41e9-9956-38c27db0ebd5 created",
  "resource-id" : "credential/530f1429-fd41-41e9-9956-38c27db0ebd5"
}
Infrastructure Service Kubernetes HTTP API credential
POST
/api/credential

curl -XPOST https://nuvla.io/api/credential -H 'content-type:application/json' -b cookies -d '
{
  "name": "Kubernetes",
  "description": "Kubernetes",
  "template": {
    "parent": "infrastructure-service/<UUID of the Kubernetes Infrastructure in Nuvla>",
    "href": "credential-template/infrastructure-service-swarm"
    "key": "client-private-certificate",
    "ca": "ca-public-certificate",
    "cert": "client-public-certificate",
  }
}
'

Response:
{
  "status" : 201,
  "message" : "credential/130f1429-fd41-41e9-9956-38c27db0ebd0 created",
  "resource-id" : "credential/130f1429-fd41-41e9-9956-38c27db0ebd0"
}

data-record

allowed:
POST
GET
PUT
DELETE
/api/data-record/uuid

The data-record resource lets user to provide user-specified metadata for describing any types of data located on any storage. This allows rich, domain-specific metadata to be attached to any of the user data and consequently, precise searching for the relevant data. In essence, the collection of the data records constitutes a metadata catalogue. The immediate usage of the data records is with data-object.

infrastructure-service is the only required attribute.

The optional attributes are

  • bucket: S3 bucket name
  • object: object path
  • bytes: number of bytes in the data
  • md5sum: MD5 checksum of the data
  • content-type: format (mimetype) of the data
  • geometry: Point or area(s) associated with data. Defined as map with type and coordinates attributes. The value of type is one of: Polygon, MultiPolygon, or Point as defined for GeoJSON in https://datatracker.ietf.org/doc/html/rfc7946#section-3.1 The coordinates is a list of closed polygons as [[[longitude, latitude[, altitude]], ...], ...] when type is Polygon or MultiPolygon, and [longitude, latitude[, altitude]] when type is Point.
  • location: Deprecated, instead use geometry with { "type": "Point", "coordinates": [longitude, latitude[, altitude]]}. Location [longitude, latitude[, altitude]] associated with the data.
  • mount: options to mount data on container

Apart from the above-listed pre-defined required and optional attributes, users can define their own namespaced attributes. Although the schema is open, all the key prefixes must be defined as data-record-key-prefix resources. Having prefixed attributes avoids collisions between domains. For details see Create namespaced data record sub-section under the Examples below and data-record-key-prefix section. In turn, the data-record-key resource is there to provide human-readable description (documentation) of the key prefixes to help to enforce the correct semantics on the data provided in the attributes.


Examples

Create minimal data record
POST
/api/data-record

curl -XPOST https://nuvla.io/api/data-record -H 'content-type:application/json' -b cookies -d '''
{
  "infrastructure-service": "infrastructure-service/9d5ab25e-7351-48a5-a149-8021c71bcadd"
}
'''

Response:
{
  "status" : 201,
  "message" : "data-record/66e2bd32-dfe5-4742-90fe-6a9d8810e2aa created",
  "resource-id" : "data-record/66e2bd32-dfe5-4742-90fe-6a9d8810e2aa"
}
Create with basic metadata
POST
/api/data-record

curl -XPOST https://nuvla.io/api/data-record -H 'content-type:application/json' -b cookies -d '''
{
  "infrastructure-service": "infrastructure-service/9d5ab25e-7351-48a5-a149-8021c71bcadd",
  "name": "Antarctica Kemp Land",
  "bucket": "satellite-images",
  "object": "antarctica-kemp-land.png",
  "md5sum": "9d9121966c738889a7624a8e1954a9c7",
  "content-type": "image/png",
  "geometry": {"type": "Polygon",
               "coordinates": [[[51.19789400000002, -66.411528],
                                [74.04920700000002, -66.779189],
                                [74.55776200000003, -71.867558],
                                [50.275495999999976, -71.748152],
                                [51.19789400000002, -66.411528]]]}
}
'''

Response:
{
  "status" : 201,
  "message" : "data-record/2893fd0e-5768-4b6c-8b28-05d0bd746c81 created",
  "resource-id" : "data-record/2893fd0e-5768-4b6c-8b28-05d0bd746c81"
}

The example above registers an S3 object /satellite-images/antarctica-kemp-land.png stored on infrastructure-service/9d5ab25e-7351-48a5-a149-8021c71bcadd. Providing content-type allows for dynamic selection of applications that can be used to open this object. The geometry/Polygon and geometry/coordinates allow geographically based filtering to discover the object.

Create namespaced data record

Prerequisite: in the example below traffic prefix key of type data-record-key-prefix must exist. See data-record-key-prefix section for details on how to create unique key prefixes.

POST
/api/data-record

curl -XPOST https://nuvla.io/api/data-record -H 'content-type:application/json' -b cookies -d '''
{
  "infrastructure-service": "infrastructure-service/5a061253-b9e4-414d-89fc-0a834a72c2a7",
  "name": "Speed Camera ABC-123",
  "description": "Speed Camera Location and Configuration",
  "bucket": "traffic-infra",
  "object": "speed-cameras/ABC-123.config",
  "md5sum": "4ebade9a86436b884020d3eb7ef8d431",
  "content-type": "plain/text",
  "geometry": {"type": "Point",
               "coordinates": [-4.193438, 55.881071, 0]},
  "traffic:attr1": "value1",
  "traffic:attr2": [1, 2, 3, 5, 8, 13],
  "traffic:attr2": {"property1": "operational", "property2": true}
}
'''

Response:
{
  "status" : 201,
  "message" : "data-record/44c796f7-065b-428f-873c-89a4f8d56721 created",
  "resource-id" : "data-record/44c796f7-065b-428f-873c-89a4f8d56721"
}

This example showcases the openness of the data record schema giving users an ability to define custom attributes of any type for their data records.

NOTE: once a value of a certain type for an attribute was provided, it will not be possible to change the type of the value. E.g.: after the integer value was used {"life:meaning": 42} it will not be possible to provide any other type (like string, boolean etc.). The workaround is to create a differently named attribute and use the value of the new required type. E.g.: {"life:meaning_monty_python": "Well, it's nothing very special."}

Search data records by POLYGON

When data records contain geometry attribute, it’s possible to search the records using Well-Known Text (WKT) geometry query.

For example, to find all the data records (defined as Polygon, MultiPolygon or Point in geometry attribute) which are either inside or are touching a certain geographical area the following geometry intersects 'POLYGON ((...))' query can be used

geometry intersects 'POLYGON ((-0.4672 51.7731, 0.4489 51.8135, 0.3508 51.3666, -0.4593 51.3325, -0.4672 51.7731))'

PUT
/api/data-record

curl -k -X PUT https://nuvla.io/api/data-record -b cookies \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "filter=geometry intersects 'POLYGON ((-0.4672 51.7731, 0.4489 51.8135, 0.3508 51.3666, -0.4593 51.3325, -0.4672 51.7731))'"

Response:
{
  "count" : 92,
  "acl" : {
    "query" : [ "group/nuvla-user" ],
    "add" : [ "group/nuvla-user" ],
    "bulk-delete" : [ "group/nuvla-user" ]
  },
  "resource-type" : "data-record-collection",
  "id" : "data-record",
  "resources" : [ {
    "description" : "S1B_IW_SLC__1SDV_20211222T060624_20211222T060651_030134_039922_8E84.SAFE",
    "tags" : [ "eo" ],
    "eo:swath" : "IW1 IW2 IW3",
    "eo:resolution" : 2.3,
    ...
    "object" : "/Sentinel-1/SAR/RAW/2021/12/10/S1B_IW_RAW__0SDV_20211210T060557_20211210T060629_029959_039396_D1EA.SAFE",
    "eo:cloudCover" : -1,
    "bucket" : "eodata",
    "platform" : "S3"
  } ],
  "operations" : [ {
    "rel" : "add",
    "href" : "data-record"
  }, {
    "rel" : "bulk-delete",
    "href" : "data-record"
  } ]
}

NOTE: The POLYGON in the query must be closed (i.e., its last point must be equal to the first one). The POLYGON must contain minimum three points.

Coordinates for geometry points can be 2D (x, y) or 3D (x, y, z), which translates into the geographical points [longitude, latitude[, altitude]].

The longitude must be in the range -180:180, and latitude -90:90.

The following query operations are defined:

  • intersects: return data records whose geometry attribute (point or polygon) intersects the query geometry.
  • disjoint: return data records whose geometry attribute (point or polygon) nothing in common with the query geometry.
  • within: return data records whose geometry attribute (point or polygon) is within the query geometry.
  • contains: return data records whose geometry attribute (point or polygon) contains the query geometry.

data-record-key-prefix

allowed:
POST
GET
PUT
DELETE
/api/data-record-key-prefix/uuid

Required attributes

  • prefix: unique namespace prefix for collections of data record keys
  • uri: globally-unique URI associated with prefix

WARNING: Only the Nuvla administrator can define the prefixes. Please make a request to support [ at ] sixsq.com.

See data-record-key resource that allows to define and describe the corresponding attributes that are expected to be provided under the user-defined namespace (key prefix).


Examples

Create data record key prefix
POST
/api/data-record-key-prefix

curl -XPOST https://nuvla.io/api/data-record-key-prefix -H 'content-type:application/json' -b cookies -d '''
{
  "name": "Road traffic.",
  "description": "Namespace for the road traffic telemetry resources.",
  "prefix": "traffic",
  "uri": "https://sixsq.com/prefixes/edge/traffic"
}
'''

Response:
{
  "status" : 201,
  "message" : "data-record-key-prefix/6792db3d-d80b-43d5-a63c-62ae19adabe3 created",
  "resource-id" : "data-record-key-prefix/6792db3d-d80b-43d5-a63c-62ae19adabe3"
}

data-record-key

allowed:
POST
GET
PUT
DELETE
/api/data-record-key/uuid

Required attributes

  • name: short, human-readable name for resource
  • description: human-readable description of resource
  • prefix: namespace prefix for data record attribute
  • key: a unique name of attribute within prefix namespace
  • subtype: subtype of resource (keyword consisting of lowercased words separated by dashes)

NOTE: It is strongly recommended providing a data-record-key resource for each domain-specific (namespaced) attribute of the data-record. The data-record-key resources provide semantic information about the attributes to help humans provide the right information.


Example

Create data record key
POST
/api/data-record-key

curl -XPOST https://nuvla.io/api/data-record-key -H 'content-type:application/json' -b cookies -d '''
{
  "name": "camera frame rate",
  "description": "frame rate of the camera (in fps)",
  "prefix": "traffic",
  "key": "camera_rate_fps",
  "subtype": "integer"
}
'''

Response:
{
  "status" : 201,
  "message" : "data-record-key/747261666669633a63616d6572615f726174655f667073 created",
  "resource-id" : "data-record-key/747261666669633a63616d6572615f726174655f667073"
}

data-object

allowed:
POST
GET
PUT
DELETE
/api/data-object/uuid

This resource is a proxy for data stored in a bucket/object within S3 from a given provider. This resource manages the lifecycle of an S3 object, allowing easy upload and download of the data.

Prerequisites: existing credential of type S3.

To upload/register/download/delete an S3 object with the help of Nuvla API see the workflow steps in the Examples below.


Examples

Creating

The full workflow consists of the following steps:

  1. Create data-object resource by providing bucket, object, and S3 credential.
  2. Request pre-signed upload URL via “upload” action.
  3. Use pre-signed upload URL to upload object contents to S3.
  4. Mark object as “ready” (and read-only) via the “ready” action.
Create data object

data-object is a templated resource with two possible subtypes (generic or public). The required attributes under the template key are

  • bucket: name of the S3 bucket
  • object: name of the S3 object
  • credential: credential of type S3 that provides access to the S3 object
  • subtype: subtype of the data-object (generic or public)

Optional attributes under template key:

  • name: object name
  • description: object extended description
  • tags: list of tags associated with the object
  • md5sum: MD5 checksum of the data

This request creates and returns the ID of the data-object resource. The returned data object ID must be used in all the successive operations.

POST
/api/data-object

curl -XPOST https://nuvla.io/api/data-object -H 'content-type:application/json' -b cookies -d '''
{
    "name": "Speed Camera ABC-123",
    "description": "Speed Camera ABC-123 Configuration",
    "template": {
        "bucket": "traffic-infra",
        "object": "speed-cameras/ABC-123.config",
        "content-type": "plain/text",
        "credential": "credential/ec203c16-c39e-4949-9980-e52c945eed5f",
        "subtype": "generic"
    }
}'''

Response:
{
  "status" : 201,
  "message" : "data-object/919d8e93-f015-39de-9771-5590db29350b created",
  "resource-id" : "data-object/919d8e93-f015-39de-9771-5590db29350b"
}
Request pre-signed upload URL
POST
/api/data-object/uuid/upload

curl -XPOST https://nuvla.io/api/data-object/919d8e93-f015-39de-9771-5590db29350b/upload -b cookies

Response:
{
  "uri" : "https://sos-ch-gva-2.exo.io/traffic-infra/speed-cameras/ABC-123.config?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220104T090913Z&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Expires=899&X-Amz-Credential=EXOXXX%2F20220104%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=06337f91515d7cb5ea6b5fd7b3504ee70e06060581999aa9b47f3861ac2df7cf"
}

https://sos-ch-gva-2.exo.io in the url of the above example response corresponds to the URL of the S3 infrastructure-service behind the provided S3 credential.

Upload data object to S3

Provided the user file is named ABC-123.config and contains text data, the uploading of the file using the S3 one-time pre-signed upload URL will look as follows. Note: this is the direct upload of the file to the S3 using the one-time pre-signed URL obtained in the previous step.

curl -XPUT \
    -H 'content-type: plain/text' \
   'https://sos-ch-gva-2.exo.io/traffic-infra/speed-cameras/ABC-123.config?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220104T102216Z&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Expires=899&X-Amz-Credential=EXOXXX%2F20220104%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=08b7e645819622235d955a0629d9c4f40ea863033ad0deb81ca989538d268f61' \
   -d@ABC-123.config
Response:
Mark object as READY

After the successful uploading of the file to S3, the corresponding data-object must be marked as READY. After that the object is ready to be used.

POST
/api/data-object/uuid/ready

curl -XPOST https://nuvla.io/api/data-object/919d8e93-f015-39de-9771-5590db29350b/ready -b cookies

Response:
{
  "description" : "Speed Camera ABC-123 Configuration",
  "updated" : "2022-01-04T10:30:19.446Z",
  "name" : "Speed Camera ABC-123",
  "credential" : "credential/ec203c16-c39e-4949-9980-e52c945eed5f",
  "created" : "2022-01-04T08:37:57.501Z",
  "state" : "READY",
  "updated-by" : "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6",
  "created-by" : "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6",
  "id" : "data-object/919d8e93-f015-39de-9771-5590db29350b",
  "resource-type" : "data-object",
  "content-type" : "plain/text",
  "acl" : {
    "edit-data" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "owners" : [ "group/nuvla-admin" ],
    "view-acl" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "delete" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "view-meta" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "edit-acl" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "view-data" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "manage" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ],
    "edit-meta" : [ "user/e5be6cc1-6942-4991-acf4-7d5cf95b9cc6" ]
  },
  "bytes" : 1024,
  "object" : "speed-cameras/ABC-123.config",
  "bucket" : "traffic-infra",
  "subtype" : "generic"
}

Downloading

Downloading of object is a two-step workflow.

  1. Request pre-signed download URL via the “download” action.
  2. Use pre-signed download URL to download object contents from S3.
Request pre-signed download URL
POST
/api/data-object/uuid/download

curl -XPOST https://nuvla.io/api/data-object/919d8e93-f015-39de-9771-5590db29350b/download -b cookies

Response:
{
  "uri" : "https://sos-ch-gva-2.exo.io/traffic-infra/speed-cameras/ABC-123.config?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220104T105644Z&X-Amz-SignedHeaders=host&X-Amz-Expires=899&X-Amz-Credential=EXOXXX%2F20220104%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b647ee325f14b0e5b312bb4bb5918a3a0229cf338223a35b707120db731869aa"
}

https://sos-ch-gva-2.exo.io in the url of the above example response corresponds to the URL of the S3 infrastructure-service behind the provided S3 credential.

Download data object from S3

Provided desired local file name is ABC-123.config, downloading of the file using the S3 one-time pre-signed download URL will look as follows.

curl -XGET \
   -o ABC-123.config \
   'https://sos-ch-gva-2.exo.io/traffic-infra/speed-cameras/ABC-123.config?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220104T105644Z&X-Amz-SignedHeaders=host&X-Amz-Expires=899&X-Amz-Credential=EXOXXX%2F20220104%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b647ee325f14b0e5b312bb4bb5918a3a0229cf338223a35b707120db731869aa'
Response:

Note: this is the direct download of the file from the S3 using the one-time pre-signed URL obtained in the previous step.

Deleting

Delete data object
DELETE
/api/data-object/uuid

curl -XDELETE https://nuvla.io/api/data-object/919d8e93-f015-39de-9771-5590db29350b -b cookies
Response:
{
  "status" : 200,
  "message" : "data-object/919d8e93-f015-39de-9771-5590db29350b deleted",
  "resource-id" : "data-object/919d8e93-f015-39de-9771-5590db29350b"
}

As the result of the call:

  1. Server verifies access and deletes the object from S3.
  2. Server also deletes the bucket if it is empty.

data-set

allowed:
POST
GET
PUT
DELETE
/api/data-set/uuid

This resource defines dynamic collections of data-object and/or data-record resources via filters.

The resource doesn’t have required attributes. The optional attributes are:

  • data-object-filter: filter for data-object resources associated with this data set
  • data-record-filter: filter for data-record resources associated with this data set
  • module-filter: filter for applications associated with this data set

Examples

Create data set
POST
/api/data-set

curl -XPOST https://nuvla.io/api/data-set -H 'content-type:application/json' -b /Users/konstan/code/nuvla/tests/cookies -d '''
{
   "name": "Configurations of Speed Cameras in Switzerland",
   "description": "Configurations of Speed Cameras in Switzerland",
   "tags": ["traffic", "camera", "config"],
   "module-filter": "data-accept-content-types='plain/text'",
   "data-record-filter": "traffic:country='Switzerland' and traffic:object_kind='config'"
}
'''

Response:
{
  "status" : 201,
  "message" : "data-set/78918cfa-0fc6-42be-a736-ae49ea855962 created",
  "resource-id" : "data-set/78918cfa-0fc6-42be-a736-ae49ea855962"
}

deployment

allowed:
POST
GET
PUT
DELETE
/api/deployment/uuid

The deployment resource allows you to deploy an instance of a module.


Examples

Start/Stop an application
POST
PUT
GET
/api/deployment

# Initialize a deployment by creating an instance of module/<uuid>
ID=$(curl -X POST -s https://nuvla.io/api/deployment -H 'content-type: application/json' -b cookies -d '''
    {
        "module": {
            "href": "module/<uuid>"
        }
    }
''' | jq -r '."resource-id"')

# Retain the ID of the created instance
echo ${ID}

# Associate an infrastructure credential with that instance
curl -X PUT https://nuvla.io/api/${ID} -H 'content-type: application/json' -b cookies -d '''
    {
        "parent": "credential/<uuid>"
    }
'''

# Start the deployment
curl https://nuvla.io/api/${ID}/start -b cookies

# Stop the deployment
curl https://nuvla.io/api/${ID}/stop -b cookies
Response:
{
  "status": 201,
  "message": "deployment/38401e41-25ea-4f45-a3b1-456df8d71918 created",
  "resource-id": "deployment/38401e41-25ea-4f45-a3b1-456df8d71918"
}
{
  "parent" : "credential/<uuid>",
  "updated" : "2019-10-29T12:35:33.308Z",
  "created" : "2019-10-29T12:30:53.296Z",
  "state" : "CREATED",
  "api-endpoint" : "https://nuvla.io",
  "module" : {
    "description" : "Example of the things you can do with Nuvla",
    "path" : "yourspace/random/things-you-can-do-with-nuvla",
    "content" : {
      "urls" : [ [ "My App", "http://192.168.43.192/" ] ],
      "updated" : "2019-10-17T09:53:53.414Z",
      "created" : "2019-10-17T09:53:53.414Z",
      "output-parameters" : [ ],
      "author" : "Bruce Wayne",
      "id" : "module-application/<uuid>",
      "commit" : "no commit message",
      "docker-compose" : "version: '3'\n\nservices:\n  blinkt:\n    image: hello-world\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n    deploy:\n      placement:\n        constraints:\n          - node.role == manager"
    },
    "updated" : "2019-10-17T09:53:53.432Z",
    "name" : "THINGS YOU CAN DO WITH NUVLA",
    "created" : "2019-10-17T09:53:53.432Z",
    "parent-path" : "yourspace/random",
    "data-accept-content-types" : [ ],
    "id" : "module/<uuid>",
    "resource-type" : "module",
    "acl" : {
      "edit-data" : [ "group/nuvla-admin" ],
      "owners" : [ "user/<uuid>" ],
      "view-acl" : [ "group/nuvla-admin" ],
      "delete" : [ "group/nuvla-admin" ],
      "view-meta" : [ "group/nuvla-admin" ],
      "edit-acl" : [ "group/nuvla-admin" ],
      "view-data" : [ "group/nuvla-admin" ],
      "manage" : [ "group/nuvla-admin" ],
      "edit-meta" : [ "group/nuvla-admin" ]
    },
    "logo-url" : "https://cdn.pixabay.com/photo/2019/08/20/12/12/lego-4418625_960_720.png",
    "href" : "module/<uuid>",
    "subtype" : "application"
  },
  "id" : "deployment/38401e41-25ea-4f45-a3b1-456df8d71918",
  "api-credentials" : {
    "api-key" : "credential/<key_uuid>",
    "api-secret" : "secret"
  },
  "resource-type" : "deployment",
  "acl" : {
    "edit-data" : [ "group/nuvla-admin" ],
    "owners" : [ "user/<uuid>" ],
    "view-acl" : [ "group/nuvla-admin" ],
    "delete" : [ "group/nuvla-admin" ],
    "view-meta" : [ "group/nuvla-admin" ],
    "edit-acl" : [ "group/nuvla-admin" ],
    "view-data" : [ "group/nuvla-admin" ],
    "manage" : [ "group/nuvla-admin" ],
    "edit-meta" : [ "group/nuvla-admin" ]
  }
}
{
  "status" : 202,
  "message" : "starting deployment/38401e41-25ea-4f45-a3b1-456df8d71918 with async job/2b0b6058-6f7e-4d59-8f09-8ae30cfbdce9",
  "resource-id" : "deployment/38401e41-25ea-4f45-a3b1-456df8d71918",
  "location" : "job/2b0b6058-6f7e-4d59-8f09-8ae30cfbdce9"
}

evidence-record

allowed:
POST
GET
PUT
DELETE
/api/evidence-record/uuid

The evidence-record resource allows you to create and manage audit evidence records that can afterwards help you keep track of your infrastructures’ compliance to certain standards and certification schemas.


Examples

Create an evidence record
POST
/api/evidencerecord

curl -XPOST https://nuvla.io/api/evidence-record -H 'content-type:application/json' -b cookies -d '''
{
	"end-time": "2018-06-20T11:34:52.555Z",
	"class" : "de.who.class.type.checks.location.GeoIPResult",
	"start-time" : "2018-06-21T11:34:52.000Z",
	"plan-id" : "abcde",
 	"passed" : true
}
'''
Response:
{
  "status" : 201,
  "message" : "evidence-record/270cc74e-91be-4415-9e1c-eb137a37a0e4 created",
  "resource-id" : "evidence-record/270cc74e-91be-4415-9e1c-eb137a37a0e4"
}

infrastructure-service

allowed:
POST
GET
PUT
DELETE
/api/infrastructure-service/uuid

The infrastructure-service resource represents any manageable service with a working endpoint. This resource is templated, which means, like session and credential, you can also create infrastructure-services of different types.


Examples

Create Docker Swarm infrastructure service
POST
/api/infrastructure-service-swarm

curl -XPOST https://nuvla.io/api/infrastructure-service -H 'content-type:application/json' -b cookies -d '
{
  "template": {
    "name": "Docker swarm",
    "description": "Docker swarm",
    "parent": "infrastructure-service-group/<UUID of your IS group>",
    "subtype": "swarm",
    "href": "infrastructure-service-template/generic",
    "endpoint": "https://service.example.org:1234"
  }
}
'
Response:
{
  "status" : 201,
  "message" : "infrastructure-service/5b65b608-b362-4053-bdda-6088f60109b1 created",
  "resource-id" : "infrastructure-service/5b65b608-b362-4053-bdda-6088f60109b1"
}
Create Kubernetes infrastructure service
POST
/api/infrastructure-service

curl -XPOST https://nuvla.io/api/infrastructure-service -H 'content-type:application/json' -b cookies -d '''
{
    "template": {
        "name": "Kubernetes",
        "description": "Kubernetes",
        "parent": "infrastructure-service-group/<UUID of your IS group>",
        "subtype": "kubernetes",
        "href": "infrastructure-service-template/generic",
        "endpoint": "https://service.example.org:1234"
    }
}
'''
Response:
{
  "status" : 201,
  "message" : "infrastructure-service/5b65b608-b362-4053-bdda-6088f60109b1 created",
  "resource-id" : "infrastructure-service/5b65b608-b362-4053-bdda-6088f60109b1"
}
Create S3 infrastructure service
POST
/api/infrastructure-service

curl -XPOST https://nuvla.io/api/infrastructure-service -H 'content-type:application/json' -b cookies -d '''
{
  "template": {
    "name": "S3",
    "description": "S3",
    "parent": "infrastructure-service-group/<UUID of your IS group>",
    "subtype": "s3",
    "href": "infrastructure-service-template/generic",
    "endpoint": "https://service.example.org:1234"
  }
}
'
Response:
{
  "status" : 201,
  "message" : "infrastructure-service/2b65b608-b362-4053-bdda-6088f60109b3 created",
  "resource-id" : "infrastructure-service/2b65b608-b362-4053-bdda-6088f60109b3"
}
Create generic infrastructure service
POST
/api/infrastructure-service

curl -XPOST https://nuvla.io/api/infrastructure-service -H 'content-type:application/json' -b cookies -d '
{
  "template": {
    "name": "Generic",
    "description": "Generic",
    "parent": "infrastructure-service-group/<UUID of your IS group>",
    "subtype": "generic",
    "href": "infrastructure-service-template/generic",
    "endpoint": "https://service.example.org:1234"
  }
}
'
Response:
{
  "status" : 201,
  "message" : "infrastructure-service/a147218d-b331-411d-a0d2-b226b77617b4 created",
  "resource-id" : "infrastructure-service/a147218d-b331-411d-a0d2-b226b77617b4"
}

infrastructure-service-group

allowed:
POST
GET
DELETE
/api/infrastructure-service-group/uuid

The infrastructure-service-group resource is a logical container for your infrastructure-service and respective credential and data resources.


Examples

Create an infrastructure-service-group
POST
/api/infrastructure-service-group

curl -XPOST https://nuvla.io/api/infrastructure-service-group -H 'content-type:application/json' -b cookies -d '''
{
    "description": "there are no mandatory attributes for this resource",
    "name": "My Group"
}
'''


Response:
{
  "status" : 201,
  "message" : "infrastructure-service-group/2d40a72e-c6cd-4e6c-8904-e4d17ea0fc76 created",
  "resource-id" : "infrastructure-service-group/2d40a72e-c6cd-4e6c-8904-e4d17ea0fc76"
}

session

allowed:
POST
GET
DELETE
/api/session/uuid

The session resource allows you to use your credentials for authenticating with Nuvla.

NOTE: for later usage, we store the authenticated session in a file called cookies


Examples

Login with username and password
POST
/api/session

curl -XPOST https://nuvla.io/api/session -H 'content-type:application/json' -c cookies -d '''
    {
      "template": {
        "href": "session-template/password",
        "username": "your_username",
        "password": "your_password"
      }
    }
'''

Response:
{
  "status" : 201,
  "message" : "session/689df57a-b217-43eb-bf94-85a0ab638e2c created",
  "resource-id" : "session/689df57a-b217-43eb-bf94-85a0ab638e2c"
}
Login with API keys
POST
/api/session

curl -XPOST https://nuvla.io/api/session -H 'content-type:application/json' -b cookies -d '''
    {
      "template": {
        "href": "session-template/api-key",
        "key": "credential/<apikey_uuid>",
        "secret": "<secret>"
      }
    }
'''

Response:
{
  "status" : 201,
  "message" : "session/b48ba610-7192-457d-952a-3549c6653ca7 created",
  "resource-id" : "session/b48ba610-7192-457d-952a-3549c6653ca7"
}
Switch group

Groups in Nuvla is the way of simplifying management of the Access Control to the resources.

When users authenticate with Nuvla, their session contains a list of associated principals; this list is sometimes referred to as the user’s “claims”. There is always an “active claim” that is used to validate user’s access rights to the resources and operations on them.

The active claim can be a group in the form group/<group name>.

To act on a resource on behalf of a group user is part of, user needs to explicitly set the group as the “active claim” using the following call (provided current session ID is session/1c490310-402f-4968-9d66-b9d3838d2286 and the group name is acme).

POST
/api/session/uuid/switch-group

curl -XPOST https://nuvla.io/api/session/1c490310-402f-4968-9d66-b9d3838d2286/switch-group \
   -H 'content-type:application/json' \
   -c cookies -b cookies \
   -d '''
    {
      "claim": "group/acme"
    }
'''

Response:
{
  "active-claim" : "group/acme",
  "client-ip" : "192.168.1.201",
  "expiry" : "2022-01-13T13:13:13.000Z",
  "method" : "password",
  "updated" : "2022-01-07T13:13:13.000Z",
  "roles" : "group/acme group/nuvla-anon group/nuvla-user session/1c490310-402f-4968-9d66-b9d3838d2286",
  "updated" : "2022-01-07T13:13:13.000Z",
  "template" : {
    "href" : "session-template/password"
  },
  "updated-by" : "user/31d08575-77c2-45fb-9174-9b34bca81dc4",
  "created-by" : "group/nuvla-anon",
  "id" : "session/1c490310-402f-4968-9d66-b9d3838d2286",
  "resource-type" : "session",
  "identifier" : "user@acme.com",
  "acl" : {
    "edit-data" : [ "group/nuvla-admin" ],
    "owners" : [ "session/1c490310-402f-4968-9d66-b9d3838d2286" ],
    "view-acl" : [ "group/nuvla-admin" ],
    "delete" : [ "group/nuvla-admin" ],
    "view-meta" : [ "group/nuvla-admin" ],
    "edit-acl" : [ "group/nuvla-admin" ],
    "view-data" : [ "group/nuvla-admin" ],
    "manage" : [ "group/nuvla-admin" ],
    "edit-meta" : [ "group/nuvla-admin" ]
  },
  "groups" : "group/acme group/acme-dev group/acme-ops",
  "user" : "user/31d08575-77c2-45fb-9174-9b34bca81dc4"
}

NOTE: -b cookies contains the current session token and -c cookies is the resulting updated session token containing group/acme as the active claim.

user

allowed:
POST
GET
PUT
DELETE
/api/user/uuid

The user resource allows you to create a new user account on Nuvla.


Examples

Create a user with an email and a password
POST
/api/user

curl -XPOST https://nuvla.io/api/user -H 'content-type:application/json' -c cookies -d '
{
  "template": {
    "href": "user-template/email-password",
    "email": "your_email",
    "password": "your_password"
  }
}
'

Response:
{
  "status" : 201,
  "message" : "user/689df57a-b217-43eb-bf94-85a0ab638e2c created",
  "resource-id" : "user/689df57a-b217-43eb-bf94-85a0ab638e2c"
}

Password must contain at least one uppercase character, one lowercase character, one digit, one special character, and at least 8 characters in total.

The creation of a user with email-password template does not require a session.

The user will receive an email with a callback that he have to follow to activate his account. After following the link, the state attribute of user document will transit from NEW to ACTIVE.

voucher

allowed:
POST
GET
PUT
DELETE
/api/voucher/uuid

The voucher resource let’s you create and manage digital vouchers, associated with any digital service provider, for better tracking and accounting of voucher consumption.


Examples

Create a new voucher
POST
/api/voucher

curl -XPOST https://nuvla.io/api/voucher -H 'content-type:application/json' -b cookies -d '''
{
    "owner": "user/ef5cddf8-5d70-4c29-19ff-079ef7f90976",
    "supplier": "providerS",
    "target-audience": "researchers@institute.org",
    "amount": 50.0,
    "currency": "EUR",
    "code": "UnIqUeXYZ",
    "state": "NEW",
    "name": "My voucher",
    "description": "Description of my voucher",
    "service-info-url": "https://providerA/redeem-here",
    "wave": "wave 1",
    "batch": "batch_id_1234"
}
'''
Response:
{
  "status" : 201,
  "message" : "voucher/932e3f49-d594-3eb7-b289-12f4988bcece created",
  "resource-id" : "voucher/932e3f49-d594-3eb7-b289-12f4988bcece"
}

Python API

(coming soon…)