Ambrosus Gateway API API Reference

Welcome to Ambrosus Gateway API Documentation.

Warning This is the Documentation of the Alpha release of the Ambrosus gateway. You can use it but bear in mind that it is being under heavy developement and may likely evolve significantly until the Beta release due in Spring 2018.

Authentication

Before interacting with the Ambrosus API, you will first need to create an account. An account is a pair made of an address and secret (private key).

To create an account, you first need to request a verification token using the /verificationToken API endpoint (the token will be sent to your email address).

Once you receive the token via email, you will be able to create an account by sending the token to the /accounts endpoint.

This diagram illustrates this process.

Authentication sequence

Each state-modifying call needs to have the content.data.creator field with creator address and one of two fields:

  • content.signature: it is generated with ethereum sign function from the content.data object of call (JSON serialized using json-stable-stringify).
  • content.secret: You can supply your secret to API and gateway will calculate the signature for you. Warning: This is only allowed in development and testing environment. We strongly recommend against using it in a production environment.

Assets and events

The core of Ambrosus is based on two key types of resources: Assets and Events.

Following diagram illustrates a sequence of those operations.

Asset and events sequence

Read about them in detail in Assets and Events sections below.

Schema

Both assets and events have consist of three levels:

  • The most external level is a container for content addressable id.

  • The level below called content serves as a wrapping with signature . It may also contain optional object called metadata, which is of type dict and stores information created by the system .

  • Most nested is the data field with any standard and custom fields created by API client in the system . It's essentially all the data to store.

This is an example of an asset/event:

{
  id: "99ekk2934",
  content: {
    signature: "...",
    data: {
     creator:"...",
     owner:"...",
     created_at: "...",
     ...
    },
    metadata {  
      timestamp:"22:03...",
     ...
    }
  }
}

Asset linking

There is a possibility to link assets together to model a relationship between these assets. Such links indicate that the linking asset is subordinate to the linked asset and that events emitted on the latter are also to the former (when the case of wine was scanned at customs, so are the 12 assets for the bottles in the case).

For example, an asset representing a case of wine can the assets of 12 bottles of wine are inside it. In turn, the case asset can also be linked to another asset representing the pallet on which it's transported and to another asset linked to an order or a shipment. Location update events happening on the pallet will automatically apply to all the assets linked to it (the bottles, the order, etc.).

Adding and removing links is performed by creating a special event to the event stream of the linking asset.

Note, that linking is not reference counted:

  • Linking assets while it is already linked will be ignored
  • Unlinking an asset that is not linked will be ignored

E.g. When we get a history of the Coke, we can get measurements performed by a senson in a track while coke was inside

Immutability

Note: All data is immutable, therefore you will not find PUT or DELETE calls. The only way data about any asset can be updated is by creating a new event on that asset that contains the new data.

API Endpoint
https://network.ambrosus.com/
Contact: [email protected]
Schemes: http, https
Version: 0.1

Account

API for creating accounts, supplement to ethereum account creation.

Balance

An account has a balance of credits, which are required to perform any modifying API calls (read calls are free). Initially, a newly created account will receive a certain amount of points. Note this is only a placeholder as in the Alpha version all calls are free, so you don't need to worry about balances.

Note:

  • API calls will return 402 if there is not enough balance to execute the operation.
  • Values might change in the future significantly (and most probably will).
  • The balance of account created on Ambrosus blockchain will be mapped to Amber.

Create verification token used for account creation.

POST /accounts/verificationToken

Create verification token that will be sent over e-mail. Token will be required to create an account.

Email address used to send the verification token

email: string
Request Content-Types: application/json
Request Example
{
  "email": "[email protected]"
}
201 Created

Created.

401 Unauthorized

E-mail blocked

Response Content-Types: application/json
Response Example (201 Created)
{
  "validUntil": "1513589305"
}

Create account

POST /accounts

Account is a pair - public identifer (compatible with ethereum address) and secret (compatible with ethereum private key).

email: string

Email address used to send the verification token

token: string

verificationToken created by verificationToken API endpoint

Request Content-Types: application/json
Request Example
{
  "email": "[email protected]",
  "token": "abcd34"
}
201 Created

Created.

Response Content-Types: application/json
Response Example (201 Created)
{
  "address": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
  "secret": "0x17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55"
}

Get account by address

GET /accounts/{address}

Get basic account information by address

address

address of an account

type
string
in
path
200 OK

Found.

404 Not Found

Account not found

Response Content-Types: application/json
Response Example (200 OK)
{
  "address": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
}

Get balance of an account

GET /accounts/{address}/balance

Get balance of an account by address

address

address of an account

type
string
in
path
200 OK

Success.

404 Not Found

Account not found

Response Content-Types: application/json
Response Example (200 OK)
{
  "address": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
  "balance": "1000000000000000000000"
}

Asset

The asset is primary element moving through a supply chain. It can represent an ingredient, product, package of products or any other type of container.

Every significant information of an Asset should be included in its data field.

The list of predefined fields of data is given below

name description type required
name Human readable representation string Yes
owner Ethereum address of a responsible unit string(hex) Yes
creator Ethereum address of the asset creator string(hex) Yes
created_at Moment when the asset was created unt(timestamp) Yes
identifiers List of global identifiers (eg. isbn, gtin) array of strings No

Create an asset

POST /assets

Asset object fields that needs to be added to the store

Request Content-Types: application/json
Request Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Chocolate Bar",
      "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1503424923,
      "identifiers": {
        "isbn": "978-3-16-148410-0",
        "ean8": "96385074",
        "gtin": "00788932473277"
      }
    }
  }
}
201 Created

Created. Following fields will be added: id, created_at

401 Unauthorized

Authentication error: address/secret it not supplied or incorrect.

402 Payment Required

Not enough balance

405 Method Not Allowed

Invalid input

Response Content-Types: application/json
Response Example (201 Created)
{
  "id": "d3ec34f4425a416a89e408b51ae8de45",
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Chocolate Bar",
      "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1503424923,
      "identifiers": {
        "isbn": "978-3-16-148410-0",
        "ean8": "96385074",
        "gtin": "00788932473277"
      }
    }
  }
}

Get Asset by ID

GET /assets/{id}

Returns a single asset by id e.g.:

/assets/d3ec34f4425a416a89e408b51ae8de45

id

ID of an asset to return

type
string
in
path
200 OK

Success. Asset found.

400 Bad Request

Invalid Asset ID supplied

404 Not Found

Asset not found

Response Content-Types: application/json
Response Example (200 OK)
{
  "id": "d3ec34f4425a416a89e408b51ae8de45",
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Chocolate Bar",
      "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1503424923,
      "identifiers": {
        "isbn": "978-3-16-148410-0",
        "ean8": "96385074",
        "gtin": "00788932473277"
      }
    }
  }
}

Find assets by custom id

GET /assets/find/{query}

Returns zero or more assets based on custom identifier, e.g.:

/assets/find/isbn:978-3-16-148410-0

Ids have to be stored in identifiers object inside data object, e.g.:

Asset { 
    name: 'Mineral water bottle 0.5', 
    data: {
        type: 'soft-drinks',
        identifiers: {
            gtin: '4008429008535'
        }, 
        ...
    }
}
query

Query which is in form identifierName:identifierValue.

type
string
in
path
200 OK

Success. Zero or more assets found.

400 Bad Request

Invalid query supplied

Response Content-Types: application/json
Response Example (200 OK)
{
  "id": "d3ec34f4425a416a89e408b51ae8de45",
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Chocolate Bar",
      "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1503424923,
      "identifiers": {
        "isbn": "978-3-16-148410-0",
        "ean8": "96385074",
        "gtin": "00788932473277"
      }
    }
  }
}

Event

Events describe something that happened in a supply chain.

Events can be used to link assets.

Every significant information of an Event should be included in its data field similarly to Assets.

The list of predefined fields of data is given below

name description type required
type Type of the event string Yes
created_at Moment when the event has happened unt(timestamp) Yes
creator Ethereum address of event creator string(hex) Yes
subject Asset Id associated with the event string(assetId) Yes
linkAssets Asset Ids that should be linked array of strings No
unlinkAssets Asset Ids that should be unlinked array of strings No

However it can include any other data describing the event.

Create

POST /assets/{assetId}/events

Asset object fields that needs to be added to the store

assetId

ID of an event subject (asset).

type
string
in
path
Request Content-Types: application/json
Request Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "type": "measurement.temperature",
      "subject": "89e4d3ec425a416a34f4ae8de4508b51",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1515688325,
      "value": "17000",
      "photoUrls": [
        [
          "bzz://photos.ambrosus/cool-photo2345.png",
          "https://ambrosus.com/somepicture786234.jpg"
        ]
      ],
      "unit": "Celcius"
    }
  }
}
200 OK

Event created. Following fields will be added: id, timestamp

400 Bad Request

Invalid Asset ID supplied

401 Unauthorized

Authentication error: address/secret it not supplied or incorrect.

402 Payment Required

Not enough balance

404 Not Found

Asset not found

Response Content-Types: application/json
Response Example (200 OK)
{
  "id": "d3ec34f4425a416a89e408b51ae8de45",
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "type": "measurement.temperature",
      "subject": "89e4d3ec425a416a34f4ae8de4508b51",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1515688325,
      "value": "17000",
      "photoUrls": [
        [
          "bzz://photos.ambrosus/cool-photo2345.png",
          "https://ambrosus.com/somepicture786234.jpg"
        ]
      ],
      "unit": "Celcius"
    },
    "metadata": {
      "timestamp": 1514458940
    }
  }
}

Get events by asset id

GET /assets/{assetId}/events
assetId

ID of asset for which events need to be feched

type
string (hex)
in
path
from_timestamp

From timestamp for filtering by timestamp

type
integer (timestamp)
in
query
to_timestamp

To timestamp for filtering by timestamp

type
integer (timestamp)
in
query
depth

Maximum depth of graph search

type
integer (int64 or Infinity) 0
in
query

Successful operation

400 Bad Request

Invalid Asset ID supplied

404 Not Found

Asset not found

Response Content-Types: application/json
Response Example (200 OK)
[
  {
    "id": "d3ec34f4425a416a89e408b51ae8de45",
    "content": {
      "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
      "data": {
        "type": "measurement.temperature",
        "subject": "89e4d3ec425a416a34f4ae8de4508b51",
        "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
        "created_at": 1515688325,
        "value": "17000",
        "photoUrls": [
          [
            "bzz://photos.ambrosus/cool-photo2345.png",
            "https://ambrosus.com/somepicture786234.jpg"
          ]
        ],
        "unit": "Celcius"
      },
      "metadata": {
        "timestamp": 1514458940
      }
    }
  }
]

Organisation

Organisations aggregating accounts into groups.

Create an organisation

POST /organisations

Asset object fields that need to be added to the store

Request Content-Types: application/json
Request Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Ambrosus",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
    }
  }
}
201 Created

Created. Following fields will be added: id, created_at

401 Unauthorized

Authentication error: address/secret it not supplied or incorrect.

402 Payment Required

Not enough balance

Response Content-Types: application/json
Response Example (201 Created)
{
  "content": {
    "data": {
      "name": "Ambrosus",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
    }
  },
  "address": "0x7deb888ce1...8410796f1b032",
  "accounts": [
    {
      "address": "0x8410...f1b0",
      "permissions": 0
    }
  ]
}

Get organisation by address

GET /organisations/{address}

Get basic organisation information by address

address

address of a organisation

type
string
in
path

Found.

404 Not Found

Organisation not found

Response Content-Types: application/json
Response Example (200 OK)
{
  "content": {
    "data": {
      "name": "Ambrosus",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
    }
  },
  "address": "0x7deb888ce1...8410796f1b032",
  "accounts": [
    {
      "address": "0x8410...f1b0",
      "permissions": 0
    }
  ]
}

Add or remove an account to/from organisation

POST /organisations/accounts

Asset object fields that need to be added to the store

content: object
Request Content-Types: application/json
Request Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "accountAddress": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "organisationAddress": "0x31f45701727a53801cd181cd38eb5bbd7a162a44",
      "action": "add | remove",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
    }
  }
}
201 Created

Success.

401 Unauthorized

Authentication error: invalid signature.

403 Forbidden

Permission denied: not an organisation creator.

Response Content-Types: application/json

Schema Definitions

OrganisationRequest: object

content: object
Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Ambrosus",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
    }
  }
}

OrganisationResponse: object

content: object
address: string
accounts: array
Example
{
  "content": {
    "data": {
      "name": "Ambrosus",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd"
    }
  },
  "address": "0x7deb888ce1...8410796f1b032",
  "accounts": [
    {
      "address": "0x8410...f1b0",
      "permissions": 0
    }
  ]
}

AddAccountRequest: object

data: object
Example
{
  "data": {
    "organisationAddress": "",
    "accountAddress": ""
  }
}

RemoveAccountResponse: object

data: object
Example
{
  "data": {
    "organisationAddress": "",
    "accountAddress": ""
  }
}

AssetRequest: object

content: AssetContent
Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Chocolate Bar",
      "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1503424923,
      "identifiers": {
        "isbn": "978-3-16-148410-0",
        "ean8": "96385074",
        "gtin": "00788932473277"
      }
    }
  }
}

AssetResponse: object

id: string (^[0-9a-f]{32}$)
content: AssetContent
Example
{
  "id": "d3ec34f4425a416a89e408b51ae8de45",
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "name": "Chocolate Bar",
      "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1503424923,
      "identifiers": {
        "isbn": "978-3-16-148410-0",
        "ean8": "96385074",
        "gtin": "00788932473277"
      }
    }
  }
}

AssetContent: object

signature: string (int64)
data: AssetData
Example
{
  "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
  "data": {
    "name": "Chocolate Bar",
    "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
    "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
    "created_at": 1503424923,
    "identifiers": {
      "isbn": "978-3-16-148410-0",
      "ean8": "96385074",
      "gtin": "00788932473277"
    }
  }
}

AssetData: object

name: string
owner: string (int64)
creator: string (int64)
created_at: integer (timestamp)
identifiers: identifiers
Example
{
  "name": "Chocolate Bar",
  "owner": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
  "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
  "created_at": 1503424923,
  "identifiers": {
    "isbn": "978-3-16-148410-0",
    "ean8": "96385074",
    "gtin": "00788932473277"
  }
}

EventRequest: object

Example
{
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "type": "measurement.temperature",
      "subject": "89e4d3ec425a416a34f4ae8de4508b51",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1515688325,
      "value": "17000",
      "photoUrls": [
        [
          "bzz://photos.ambrosus/cool-photo2345.png",
          "https://ambrosus.com/somepicture786234.jpg"
        ]
      ],
      "unit": "Celcius"
    }
  }
}

EventRequestContent: object

signature: string (int64)
data: EventData
Example
{
  "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
  "data": {
    "type": "measurement.temperature",
    "subject": "89e4d3ec425a416a34f4ae8de4508b51",
    "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
    "created_at": 1515688325,
    "value": "17000",
    "photoUrls": [
      [
        "bzz://photos.ambrosus/cool-photo2345.png",
        "https://ambrosus.com/somepicture786234.jpg"
      ]
    ],
    "unit": "Celcius"
  }
}

EventListResponse: array

Example
[
  {
    "id": "d3ec34f4425a416a89e408b51ae8de45",
    "content": {
      "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
      "data": {
        "type": "measurement.temperature",
        "subject": "89e4d3ec425a416a34f4ae8de4508b51",
        "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
        "created_at": 1515688325,
        "value": "17000",
        "photoUrls": [
          [
            "bzz://photos.ambrosus/cool-photo2345.png",
            "https://ambrosus.com/somepicture786234.jpg"
          ]
        ],
        "unit": "Celcius"
      },
      "metadata": {
        "timestamp": 1514458940
      }
    }
  }
]

EventResponse: object

id: string
content: EventContent
Example
{
  "id": "d3ec34f4425a416a89e408b51ae8de45",
  "content": {
    "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
    "data": {
      "type": "measurement.temperature",
      "subject": "89e4d3ec425a416a34f4ae8de4508b51",
      "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
      "created_at": 1515688325,
      "value": "17000",
      "photoUrls": [
        [
          "bzz://photos.ambrosus/cool-photo2345.png",
          "https://ambrosus.com/somepicture786234.jpg"
        ]
      ],
      "unit": "Celcius"
    },
    "metadata": {
      "timestamp": 1514458940
    }
  }
}

EventContent: object

signature: string (int64)
data: EventData
metadata: object
Example
{
  "signature": "0x30755ed65396facf86c53e6...65c5cfd04be400",
  "data": {
    "type": "measurement.temperature",
    "subject": "89e4d3ec425a416a34f4ae8de4508b51",
    "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
    "created_at": 1515688325,
    "value": "17000",
    "photoUrls": [
      [
        "bzz://photos.ambrosus/cool-photo2345.png",
        "https://ambrosus.com/somepicture786234.jpg"
      ]
    ],
    "unit": "Celcius"
  },
  "metadata": {
    "timestamp": 1514458940
  }
}

EventData: object

type: string
subject: string
creator: string (hex)
created_at: number
value: string
photoUrls: string[]
unit: string

Unit for measurement

Example
{
  "type": "measurement.temperature",
  "subject": "89e4d3ec425a416a34f4ae8de4508b51",
  "creator": "0x162a44701727a31f457a53801cd181cd38eb5bbd",
  "created_at": 1515688325,
  "value": "17000",
  "photoUrls": [
    [
      "bzz://photos.ambrosus/cool-photo2345.png",
      "https://ambrosus.com/somepicture786234.jpg"
    ]
  ],
  "unit": "Celcius"
}

identifiers: object

isbn: string
ean8: string
gtin: string
Example
{
  "isbn": "978-3-16-148410-0",
  "ean8": "96385074",
  "gtin": "00788932473277"
}