cURL JavaScript Python PHP Go

The Dock API

A complete solution for creating, managing and presenting Verifiable Credentials.

Dock provides a range of tools incorporating blockchain technology that enable businesses and developers to create and use verifiable credentials. Dock integrates industry-leading World Wide Web Consortium (W3C) and VCDM standards, allowing it to interoperate with other open source technologies. We provide a range of open-source software on GitHub that can be used alongside the API.

In addition to the code samples shown in these docs, we have provided various code samples for the common requests that you can easily access here.

We also offer a free trial, testnet sandboxing and fair monthly pricing. Sign up and start issuing credentials with our API console. Please read our Terms of Service before using the Dock API.

Primary Features

Getting Started

Prerequisites

You must first have an account and acquire your credentials (API keys) before accessing the Dock API.

You can register an account and generate a key in our API console.

Endpoints

The Dock API provides two endpoints based on which mode was selected when creating your API key. By default API keys are created for production. You can switch to test mode in the API console by clicking the "test mode" toggle in the top right next to your avatar icon. Once in test mode you will see only testnet transactions, API keys, webhooks etc. You can then create an API key from the API management screen to use with either endpoint. It should be noted that in test mode your used transaction count will not increase or hit monthly limits allowing for sandboxing on our testnet blockchain.

PLEASE NOTE: Any transaction you perform in test mode cannot be used for production. This means that, for example, any DID created in test mode will not work for issuing or verification in production.

Authentication

The Dock API uses API keys to authenticate requests. You can obtain an API Key by signing into the api console. Once a key has been generated, it should be included in all request headers as below:

Architecture Style

The Dock API is built using a REST architecture. Our API uses standard HTTP response codes, authentication, delivers JSON-encoded responses, accepts form-encoded request bodies, and accepts form-encoded request bodies.

HTTPS is required for all API requests. Requests performed via plain HTTP will be rejected. API requests that do not include authentication will also fail. JSON requests should typically be encoded as UTF-8.

HTTP Method Description
GET Get one or many resources
POST Creates a new resources
PATCH Partially update a resource
DELETE Delete a resource

Rate Limits

We allow you to make up to 200 requests in a 2 minute window (avg 100 reqs/min or 1.6 reqs/second). If you exceed beyond that, you will receive a 429 Too Many Requests response and have to wait up to a minute for the next request depending on when you hit the limit. If you require higher rate limits, please contact us.

Error Handling

Dock API uses standard HTTP response codes to indicate if an API request was successful or unsuccessful.

The table below shows the most frequent HTTP error messages:

Code Meaning
400 Bad Request -- Your request was rejected (e.g., missing mandatory field).
401 Unauthorized -- Do not own resource or have an invalid API key in the header.
404 Not Found -- The resource that you're trying to interact with could not be found on the server.
429 Too Many Requests -- You sent too many requests. Please try to reduce the number of requests.
500 Server Errors -- Something has gone wrong on the server. Contact us if this keeps happening.

Terminology

It is important to fully understand all the terminologies within the Dock ecosystem. The following are common terminologies within our ecosystem:

Terminology Description
DID DID stands for Decentralized Identifier. It is a new type of identifier that enables verifiable, decentralized digital identity. A DID refers to any subject (e.g., a person, organization, thing, data model, abstract entity, etc.) as determined by the controller of the DID. For more information, please refer here.
Anchoring A feature that allows users to store a digest of one or more credentials (or any files) on our blockchain so that they are associated with immutable timestamps and hence can be proven to have been created at a certain point in time.
Data Schema The structure that describes the logical view of the data. It is useful to enforce a specific structure on a collection of data like a Verifiable Credential.
Registries A process to verify credentials in such a way that each verified credential has its own unique number. This process references a credential definition and specifies how revocation of that credential type will be handled. 
Schema The structure of credentials which are shareable among issuers as they do not contain any cryptographic material and thus are created less frequently.
Blob Blob stands for Binary Large OBject. It is a collection of binary data stored as a single entity. The schemas are identified and retrieved by their unique blob id, which is a 32-byte long hex string.
DID Resolver The tool that initiates the process of learning the DID document.

DIDs

Endpoints

DID stands for Decentralized IDentifiers. DIDs are meant to be globally unique identifiers that allow their owner to prove cryptographic control over them. A DID identifies any subject (e.g., a person, organization, thing, data model, abstract entity, etc.) that the controller of the DID decides that it identifies.

DIDs in Dock are created by choosing a 32-byte unique (on Dock chain) identifier along with a public key. You can update and delete a DID as well as list all DIDs. DID is identified by a unique, random key.

Get DID

GET /dids/{did}

# You can also use wget
curl -X GET /dids/{did} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/dids/{did}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/dids/{did}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/dids/{did}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/dids/{did}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

The process of learning the DID Document of a DID is called DID resolution, and the tool that resolves is called the resolver.

Dock supports DID resolvers for resolving DIDs and Dock will return the DID document that contains DID id as fully qualified, e.g., did:dock:5CEdyZkZnALDdCAp7crTRiaCq6KViprTM6kHUQCD8X6VqGPW

Parameters

Name In Type Required Description
did path DID true Represents a specific DID that uniquely identifies the key resource.

200 Response

{
  "@context": [
    "string"
  ],
  "id": "did:dock:xyz",
  "authentication": [
    {}
  ]
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will return the DID doc. To view an example of a DID doc, please refer here. DIDDoc
404 Not Found The requested DID was not found. Error

Update DID

PATCH /dids/{did}

# You can also use wget
curl -X PATCH /dids/{did} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{
  "controller": "did:dock:xyz",
  "keyType": "sr25519"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/dids/{did}',
{
  method: 'PATCH',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.patch('/dids/{did}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('PATCH','/dids/{did}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("PATCH", "/dids/{did}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

The public key or the controller of an on-chain DID can be updated by preparing a signed key update. Updates the specified key by setting the values of the parameters passed. Any parameters not provided will be left unchanged. For example, if you pass the keyType parameter, that becomes the DID’s active source on the blockchain for all transactions in the future.

To rotate the key of an existing DID, the current key is used to sign an update message containing the new public key and optionally the new controller (if a controller is not supplied, the controller remains unchanged). The update message contains the block number for the last update of the DID.

Body parameter

{
  "controller": "did:dock:xyz",
  "keyType": "sr25519"
}

Parameters

Name In Type Required Description
did path DID true Represents a specific DID that uniquely identifies the key resource.
controller body DID false DID as fully qualified, e.g., did:dock:. The default value of the controller is the DID value.
keyType body KeyType false Type of the public key for DID. The default value of the keyType is sr25519.

An example Dock DID: did:dock:5CEdyZkZnALDdCAp7crTRiaCq6KViprTM6kHUQCD8X6VqGPW

Enumerated Values

Parameter Value Description
keyType sr25519 or ed25519 or secp256k1 keyType signature variants.

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK The request was successful and will update DID. JobId
401 Unauthorized The request was unsuccessful, because you don't own the DID. Error
404 Not Found The DID does not exist. Error

Delete DID

DELETE /dids/{did}

# You can also use wget
curl -X DELETE /dids/{did} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/dids/{did}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.delete('/dids/{did}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','/dids/{did}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "/dids/{did}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

A DID can be deleted from the blockchain by sending the corresponding message signed with the current key. However, further attempts to resolve this DID will fail.

It should be noted that the accounts used to send the transactions are unrelated to the keys connected with the DID. As a result, the DID may have been created with one account, updated, and deleted with another account. In the data model, the accounts are irrelevant, and they are not connected with the DID in the chain state.

Parameters

Name In Type Required Description
did path DID true Represents a specific DID that uniquely identifies the key resource.

An example Dock DID: did:dock:5CEdyZkZnALDdCAp7crTRiaCq6KViprTM6kHUQCD8X6VqGPW

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK The request was successful and will remove DID. JobId
401 Unauthorized The request was unsuccessful, because you don't own the DID. Error
404 Not Found The DID does not exist. Error

List DIDs

GET /dids

# You can also use wget
curl -X GET /dids \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/dids',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/dids', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/dids', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/dids/", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Return a list of all user's DIDs you've previously created. The DIDs are returned into a sorted DID document.

200 Response

[
  {
    "@context": [
      "string"
    ],
    "id": "did:dock:xyz",
    "authentication": [
      {}
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK All of a user's DIDs fully resolved into DID documents. DIDDoc

Create DID

POST /dids

# You can also use wget
curl -X POST /dids \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{
  "did": "did:dock:xyz",
  "controller": "did:dock:xyz",
  "keyType": "sr25519"
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/dids',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/dids', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/dids', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/dids", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

A DID, a public key, and a controller are required to create a new DID. The controller is both the owner of the public key and a DID. The DID can be created using an auto-generated keypair, and the controller will be the same as the DID unless otherwise specified. The DID and public key have no cryptographic relation.

It is important to have a public key of one of its three supported types. Dock supports 3 types of public keys: sr25519, ed25519, and secp256k1. These public keys are supported by 3 classes: PublicKeySr25519, PublicKeyEd25519, and PublicKeySecp256k1.

Body parameter

{
  "did": "did:dock:xyz",
  "controller": "did:dock:xyz",
  "keyType": "sr25519"
}

Parameters

Name In Type Required Description
did body DID false DID as fully qualified, e.g., did:dock:. You cannot specify your own DID, the DID value will be randomly generated.
controller body DID false DID as fully qualified, e.g., did:dock:. The default value of the controller is the DID value.
keyType body KeyType false Type of public key for DID. The default value of the keyType is sr25519.

Enumerated Values

Parameter Value Desctiprion
keyType sr25519 or ed25519 or secp256k1 keyType signature variants.

200 Response

{
  "id": "string",
  "data": {
    "did": did:dock:xyz,
    "hexDid": 0x00,
  }
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will try to create DID. NOTE: DID does not exist on network until the job identified in the response is complete. JobStartedResult
400 Bad Request The request was unsuccessful, because of invalid params. Error

Credentials

Blockchain Credentials are credentials that have been recorded on the blockchain in order to increase security and prevent fraud. Blockchain credentials are very hard to fake or modify, and they are simple to verify. In Dock, you are allowed to create and issue a verifiable credential with supplied data.

Issue a credential

POST /credentials

# You can also use wget
curl -X POST /credentials/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{
  "credential": {
    "id": "http://example.com",
    "context": [
      "string"
    ],
    "type": [
      "string"
    ],
    "subject": {},
    "issuer": "did:dock:xyz",
    "issuanceDate": "2019-08-24T14:15:22Z",
    "expirationDate": "2019-08-24T14:15:22Z",
    "status": {}
  }
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/credentials',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/credentials', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/credentials', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/credentials", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

To issue a verifiable credential, the issuer needs to have a public key that is accessible by the holder and verifier to verify the signature (in proof) in the credential. Though the VCDM spec does not mandate it, an issuer in Dock must have a DID on a chain.

This DID may be found in the issuer field of the credential. Dock retrieves an issuer as a string, which can be a URI string (DID as fully qualified, e.g., did:dock:) or an object with a property ID that is a uri/DID.

Body parameter

{
  "credential": {
    "id": "http://example.com",
    "context": [
      "string"
    ],
    "type": [
      "string"
    ],
    "subject": {},
    "issuer": "did:dock:xyz",
    "issuanceDate": "2019-08-24T14:15:22Z",
    "expirationDate": "2019-08-24T14:15:22Z",
    "status": {}
  }
}

Parameters

Name In Type Required Description
credential body Credential true Credential format expected by API caller.

200 Response

{
  "@context": [
    "string"
  ],
  "id": "http://example.com",
  "type": [
    "string"
  ],
  "credentialSubject": {},
  "issuer": "did:dock:xyz",
  "issuanceDate": "2019-08-24T14:15:22Z",
  "expirationDate": "2019-08-24T14:15:22Z",
  "credentialStatus": {},
  "proof": {
    "type": "Sr25519Signature2020",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "string",
    "created": "2019-08-24T14:15:22Z",
    "proofValue": "string"
  }
}

Responses

Status Meaning Description Schema
200 OK The request was successful and returns the created Verifiable Credential. VerifiableCredential
400 Bad Request The request was unsuccessful, because of invalid/insufficient credential params. Error
401 Unauthorized The request was unsuccessful, either because the authorization token was missing/invalid or you don't own the DID. Error

Presentations

The presentation is signed using the holder's private key as it is being created. To validate the presentation, the verifier must also check the issuer's signature and the holder's public key. One way to achieve this is to make the holder have a DID too, so that the verifier can look up the DID on the chain and learn the public key.

The API allows you to create and sign a verifiable presentation out of one or more Verifiable Credentials.

Create a presentation

POST /presentations

# You can also use wget
curl -X POST /presentations/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{
  "holder": "did:dock:xyz",
  "challenge": "string",
  "domain": "string",
  "credentials": [
    {
      "@context": [
        "string"
      ],
      "id": "http://example.com",
      "type": [
        "string"
      ],
      "credentialSubject": {},
      "issuer": "did:dock:xyz",
      "issuanceDate": "2019-08-24T14:15:22Z",
      "expirationDate": "2019-08-24T14:15:22Z",
      "credentialStatus": {},
      "proof": {
        "type": "Sr25519Signature2020",
        "proofPurpose": "assertionMethod",
        "verificationMethod": "string",
        "created": "2019-08-24T14:15:22Z",
        "proofValue": "string"
      }
    }
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/presentations',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/presentations', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/presentations', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/presentations", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

The holder while creating the presentation signs it with his private key. For the verifier to verify the presentation, in addition to verifying the issuer's signature, he/she needs to verify this signature as well, and for that he must know the holder's public key.

This is an operation to create and sign a verifiable presentation out of one or more Verifiable Credentials.

Body parameter

{
  "holder": "did:dock:xyz",
  "challenge": "string",
  "domain": "string",
  "credentials": [
    {
      "@context": [
        "string"
      ],
      "id": "http://example.com",
      "type": [
        "string"
      ],
      "credentialSubject": {},
      "issuer": "did:dock:xyz",
      "issuanceDate": "2019-08-24T14:15:22Z",
      "expirationDate": "2019-08-24T14:15:22Z",
      "credentialStatus": {},
      "proof": {
        "type": "Sr25519Signature2020",
        "proofPurpose": "assertionMethod",
        "verificationMethod": "string",
        "created": "2019-08-24T14:15:22Z",
        "proofValue": "string"
      }
    }
  ]
}

Parameters

Name In Type Required Description
holder body DIDQualified true DID as fully qualified, e.g., did:dock:....
challenge body string false Presentation's Challenge in a string format. The default value for this is random hex string.
domain body string false A domain for the proof in a string format. The default value for the domain is dock.io.
credentials body VerifiableCredential false Verifiable (signed) Credential returned by API.

Enumerated Values

Parameter Value Description
type Sr25519Signature2020 or Ed25519Signature2018 or EcdsaSecp256k1Signature2019 Type of Signature.
proofPurpose assertionMethod or authentication The purpose the credential will be used for.

200 Response

{

  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://www.w3.org/2018/credentials/examples/v1"
  ],
  "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5",
  "type": ["VerifiablePresentation", "CredentialManagerPresentation"],
  "verifiableCredential": [{  }],
  "proof": [{  }]
  }
}

Responses

Status Meaning Description Schema
200 OK The request was successful and returns a Verifiable Presentation. VerifiablePresentation
400 Bad Request The request was unsuccessful, because of invalid/insufficient parameters. Error
401 Unauthorized The request was unsuccessful, either because of a missing/invalid auth header or you don't own the DID. Error

Registries

Revocation means deleting or updating a credential. On Dock, credential revocation is managed with a revocation registry.

There can be multiple registries on the chain, and each registry has a unique id. It is recommended that the revocation authority create a new registry for each credential type. Dock API allows you to create, delete, and revoke/unrevoke the credential. You can retrieve a specified registry as well as a list of all registries created by the user.

Delete registry

DELETE /registries/{id}

# You can also use wget
curl -X DELETE /registries/{id} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/registries/{id}',
{
  method: 'DELETE',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.delete('/registries/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('DELETE','/registries/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("DELETE", "/registries/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

A registry can be deleted, leading to all the corresponding revocation ids being deleted as well. This requires the signature from the owner, similar to the other updates.

Parameters

Name In Type Required Description
id path Hex32 true Revocation registry id.

200 Response

{
  "id": "string",
  "data": {
    "did": did:dock:xyz,
    "hexDid": 0x00,
  }
}

Responses

Status Meaning Description Schema
200 OK The request was successful and revocation registry will be deleted. JobStartedResult
404 Not Found The request was unsuccessful, because the registry was not found. Error

Get registry

GET /registries/{id}

# You can also use wget
curl -X GET /registries/{id} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/registries/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/registries/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/registries/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/registries/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Get the details of an existing registry, such as policy, add-only status, when it was last updated, and controller(s). You need only supply the revocation registry id that was returned upon revocation registry creation.

Parameters

Name In Type Required Description
id path Hex32 true Revocation registry id.

200 Response

{
  "addOnly": true,
  "policy": [
    "did:dock:xyz"
  ]
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will return the revocation registry metadata. Registry
404 Not Found The request was unsuccessful, because the registry was not found. Error

Revoke/unrevoke credential

POST /registries/{id}

# You can also use wget
curl -X POST /registries/{id} \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{
  "action": "revoke",
  "credentialIds": [
    "http://example.com"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/registries/{id}',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/registries/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/registries/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/registries/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Credential revocation is managed with on-chain revocation registries. To revoke a credential, its id (or hash of its id) must be added to the credential. It is advised to have one revocation registry per credential type. Revoking an already revoked credential has no effect.

Similar to the replay protection mechanism for DIDs, the last modified block number is kept for each registry, which is updated each time a credential is revoked or unrevoked. Unrevoking an unrevoked credential has no effect.

In this API, simply add Revoke/Unrevoke into the action parameter and input the desired credential ids.

Body parameter

{
  "action": "revoke",
  "credentialIds": [
    "http://example.com"
  ]
}

Parameters

Name In Type Required Description
id path Hex32 true Revocation registry id.
action body string false The action taken, either revoke or unrevoke. The default value is "revoke"
credentialIds body array true The list of credential ids to act upon.

Enumerated Values

Parameter Value Description
action revoke or unrevoke Action to take on the registry.

200 Response

{
  "id": "string",
  "data": {
    "did": did:dock:xyz,
    "hexDid": 0x00,
  }
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will try to revoke/unrevoke the credential. JobStartedResult
400 Bad Request The request was unsuccessful, because of invalid params. Error
404 Not Found The request was unsuccessful, because the registry was not found. Error

List registries

GET /registries

# You can also use wget
curl -X GET /registries/ \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/registries',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/registries', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/registries', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/registries", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Return a list of all registries created by the user. The list is returned with the registry id and policy of the revocation registry.

200 Response

[
  {
    "id": "string",
    "registry": {
      "addOnly": true,
      "policy": [
        "did:dock:xyz"
      ]
    }
  }
]

Responses

Status Meaning Description Schema
200 OK The request was successful and will return all registries created by the user. Inline

Create registry

POST /registries

# You can also use wget
curl -X POST /registries/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{
  "addOnly": true,
  "policy": [
    "did:dock:xyz"
  ]
}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/registries',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/registries', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/registries', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/registries", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

To create a registry, you have to create a policy object for which a DID is needed. It is advised that the DID is registered on the chain first. Otherwise, someone can look at the registry and register the DID, thus gaining control of the registry.

Body parameter

{
  "addOnly": true,
  "policy": [
    "did:dock:xyz"
  ]
}

Parameters

Name In Type Required Description
addOnly body boolean false True/false options. The default value is "false".
policy body [DID] true The DIDs which control this registry. You must own a DID listed here to use the registry. Only one policy supported as of now: OneOf DID in list.

200 Response

{
  "id": "string",
  "data": {
    "did": did:dock:xyz,
    "hexDid": 0x00,
  }
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will try to create the registry. JobStartedResult
400 Bad Request The request was unsuccessful, because of invalid params, e.g., policy not supported. Error

Revocation Status

Once the registry is being revoked or unrevoked, you can check its status with the registry id and revocation id.

Get revocation status

GET /revocationStatus/{regId}/{revId}

# You can also use wget
curl -X GET /revocationStatus/{regId}/{revId} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/revocationStatus/{regId}/{revId}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/revocationStatus/{regId}/{revId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/revocationStatus/{regId}/{revId}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/revocationStatus/{regId}/{revId}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

To check if an id is revoked or not, you can check its status with the registry id (regId) and revocation id (revId).

Parameters

Name In Type Required Description
regId path Hex32 true Revocation registry id.
revId path Hex32 true Credential revocation id.

200 Response

{
  "type": true
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will return true, if the credential is revoked, false otherwise. Inline
404 Not Found The request was unsuccessful, because the registry was not found. Error

Credential Schemas

Schemas are useful when enforcing a specific structure on a collection of data like a Verifiable Credential. Data Verification schemas, for example, are used to verify that the structure and contents of a Verifiable Credential conform to a published schema. On the other hand, Data Encoding schemas are used to map the contents of a Verifiable Credential to an alternative representation format, such as a binary format used in a zero-knowledge proof.

Before diving further into Schemas, it is important to understand how they are stored in the Dock chain. Schemas are stored on chain as a Blob in the Blob Storage module. They are identified and retrieved by their unique blob id, a 32 byte long hex string. They are authored by a DID and have a max size of 1024 bytes.

Get schema

GET /schemas/{schemaId}

# You can also use wget
curl -X GET /schemas/{schemaId} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/schemas/{schemaId}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/schemas/{schemaId}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/schemas/{schemaId}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/schemas/{schemaId}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Reading a Schema from the Dock chain can easily be achieved by using the get method which will return the JSON schema to a specific schema ID.

Parameters

Name In Type Required Description
schemaId path Hex32 true A schema id.

200 Response

{
  "id": "string",
  "schema": {}
}

Responses

Status Meaning Description Schema
200 OK The request was successful and returns the requested Schema. Inline
404 Not Found The request was unsuccessful, because the schema was not found. Error

List schemas

GET /schemas

# You can also use wget
curl -X GET /schemas \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/schemas',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/schemas/', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/schemas', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/schemas", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Return a list of all schemas created by the authenticated user.

200 Response

[
  {}
]

Responses

Status Meaning Description Schema
200 OK The request was successful and will return all schemas created by the user. Inline

Create schema

POST /schemas

# You can also use wget
curl -X POST /schemas \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/schemas',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/schemas', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/schemas', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/schemas", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

The first step to creating a Schema is to initialize it. We can do that using the Schema class constructor, which accepts an (optional) id string as the sole argument. When an id isn't passed, a random blobId will be assigned as the schema's id.

Body parameter

{}

Parameters

Name In Type Required Description
body body object true JSON-schema.

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK The request was successful and will try to create schema. JobId
400 Bad Request The request was unsuccessful, because of invalid params, e.g., size not supported or not JSON. Error

Anchors

Anchoring allows users to store a digest of one or more credentials (or any files) on our blockchain, tying them to immutable timestamps and proving that they were generated at a certain moment in time. By enabling this feature, users will have more options for auditing credentials given and timestamping any documents.

The Dock Blockchain includes a module explicitly intended for proof of existence. You post the hash of a document on-chain at a specific block. Later you can use that hash to prove the document existed at or before that block.

The API allows you to create, get, and retrieve anchors as well as a list of all anchors created by the user.

Get anchor

GET /anchors/{anchor}

# You can also use wget
curl -X GET /anchors/{anchor} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/anchors/{anchor}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/anchors/{anchor}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/anchors/{anchor}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/anchors/{anchor}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Get a specific anchor with the given ID.

Parameters

Name In Type Required Description
anchor path Hex32 true An anchor id.

200 Response

{
  "anchor": "string",
  "blockHash": "string",
  "root": "string"
}

Responses

Status Meaning Description Schema
200 OK The request was successful and returns the anchor's details, e.g., blockHash and root. Anchor
404 Not Found The request was unsuccessful, because the anchor was not found. Error

List anchors

GET /anchors

# You can also use wget
curl -X GET /anchors \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/anchors',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/anchors', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/anchors', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/anchors", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Return a list of all anchors created by the authenticated user, regardless of whether they have contributed to the batching or not.

200 Response

[
  {}
]

Responses

Status Meaning Description Schema
200 OK The request was successful and will return all anchors created by the user. Inline

Create anchor

POST /anchors

# You can also use wget
curl -X POST /anchors \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '[
  "string"
]';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/anchors/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/anchors', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/anchors', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/anchors", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

To create an anchor, you can use more than one document; it is called Batching. Batching (combining multiple anchors into one) can be used to save on transaction costs by anchoring multiple documents in a single transaction as a Merkle tree.

The anchoring module is hashing algorithm and hash length agnostic. You can post a multi hash, or even use the identity hash; the chain doesn't care. One thing to note is that rather than storing your anchor directly, the anchoring module will store the blake2b256 hash of the anchor. Dock provides a fully functioning reference client for anchoring.

Body parameter

[
  "string"
]

Parameters

Name In Type Required Description
body body any true Documents.

200 Response

"string"

Responses

Status Meaning Description Schema
200 OK The request was successful and will try to create an anchor on the blockchain. JobId
400 Bad Request The request was unsuccessful, because of invalid params. Error

Jobs

API requests that involve writing data to the blockchain trigger Jobs to do that work asynchronously.

You can track the current job status by querying the job id returned as part of the initial API response that triggered the job.

Get job status and data

GET /jobs/{Id}

# You can also use wget
curl -X GET /jobs/{id} \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'


const headers = {
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/jobs/{id}',
{
  method: 'GET',

  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.get('/jobs/{id}', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('GET','/jobs/{id}', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("GET", "/jobs/{id}", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

To check the Job status and data, you can use the GET method and simply put the Job id. It will return information related to the job being processed and its associated blockchain transaction. On completion or failure, the job data will be updated with a response from the blockchain.

Parameters

Name In Type Required Description
id path JobId true Represents a Job id.

200 Response

{
  "id": "string",
  "status": "todo",
  "result": {}
}

Responses

Status Meaning Description Schema
200 OK The request was successful and return the job description. JobDesc
404 Not Found The request was unsuccessful, because the Job id was not found. Error

Verify

A Verifier upon receiving a verifiable presentation verifies the validity of each credential in the presentation. This includes checking the correctness of the data model of the credential, the authenticity by verifying the issuer's signature and revocation status if the credential is revocable. It then checks whether the presentation contains the signature from the holder on the presentation, including his given challenge.

Verify a credential or presentation

POST /verify

# You can also use wget
curl -X POST /verify \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'DOCK-API-TOKEN: API_KEY'

const inputBody = '{}';
const headers = {
  'Content-Type':'application/json',
  'Accept':'application/json',
  'DOCK-API-TOKEN':'API_KEY'
};

fetch('/verify/',
{
  method: 'POST',
  body: inputBody,
  headers: headers
})
.then(function(res) {
    return res.json();
}).then(function(body) {
    console.log(body);
});

import requests
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'DOCK-API-TOKEN': 'API_KEY'
}

r = requests.post('/verify', headers = headers)

print(r.json())

<?php

require 'vendor/autoload.php';

$headers = array(
    'Content-Type' => 'application/json',
    'Accept' => 'application/json',
    'DOCK-API-TOKEN' => 'API_KEY',
);

$client = new \GuzzleHttp\Client();

// Define array of request body.
$request_body = array();

try {
    $response = $client->request('POST','/verify', array(
        'headers' => $headers,
        'json' => $request_body,
       )
    );
    print_r($response->getBody()->getContents());
 }
 catch (\GuzzleHttp\Exception\BadResponseException $e) {
    // handle exception or api errors.
    print_r($e->getMessage());
 }

 // ...

package main

import (
       "bytes"
       "net/http"
)

func main() {

    headers := map[string][]string{
        "Content-Type": []string{"application/json"},
        "Accept": []string{"application/json"},
        "DOCK-API-TOKEN": []string{"API_KEY"},
    }

    data := bytes.NewBuffer([]byte{jsonReq})
    req, err := http.NewRequest("POST", "/verify", data)
    req.Header = headers

    client := &http.Client{}
    resp, err := client.Do(req)
    // ...
}

Once your Verifiable Credential (VCDM credential) has been signed, you can verify it with the verify method. The verify method takes an object of arguments and is optional.

Also, when your Verifiable Presentation (presentation JSON-LD object) has been signed, you can verify it with the verify method.

Please note that the verification is an async process that returns an object when the promise resolves. This object contains separate results for the verification processes of the included Verifiable Credentials and the overall Verifiable Presentation.

Body parameter

{}

Parameters

Name In Type Required Description
body body VerifiableCredential or VerifiablePresentation true JSON-schema.

200 Response

{
  "verified": true
}

Responses

Status Meaning Description Schema
200 OK The request was successful and will return the verification result. VerificationResponse
400 Bad Request The request was unsuccessful, because of invalid credential params. Error

Schemas

Data Schemas are useful when enforcing a specific structure on a collection of data like a Verifiable Credential. Other than that, Data Verification schema and Data Encoding Schemas are used to verify and map the structure and contents of a Verifiable Credential.

These are the schemas used in all API operations mentioned before, such as Error, Credential, Jobs, Anchor, Registry, and so on.

Error

{
  "status": 0,
  "type": "string",
  "message": "string"
}

This is a schema for an API Error.

Properties

Name Type Required Description
status integer false Status of the error.
type string false Type of the error.
message string false Message of the error.

Hex32

"string"

32 byte hex string. Ignoring higher base (base64) for simplicity.

Properties

Name Type Required Description
Hex32 string false 32 byte hex string. Ignoring higher base (base64) for simplicity.

JobStartedResult

{
  "id": "string",
  "data": {
    "did": did:dock:xyz,
    "hexDid": 0x00,
  }
}

Object containing unique id of the background task and associated data. This id can be used to query the job status.

Properties

Name Type Description
id JobId Unique id of the background task. This id can be used to query the job status.
data object Data of the object.

JobId

"string"

Unique id of the background task. This id can be used to query the job status

JobStatus

"todo"

This is a schema used in Job operation to get a status of the job.

Enumerated Values

Property Value Description
JobStatus todo or finalized or in_progress or error. Job Status variants.

JobDesc

{
  "id": "string",
  "status": "todo",
  "result": {}
}

This is a schema used in Job operation to get description of the job including the result if it is available.

Properties

Name Type Description
id JobId Unique id of the background task. This id can be used to query the job status.
status JobStatus Status of the job.
result object false

DIDQualified

"did:dock:xyz"

This is a schema used in some operations that used DID as fully qualified, e.g., did:dock:xyz.

Properties

Name Type Required Description
DIDQualified string(uri) false DID as fully qualified, e.g., did:dock:xyz.

DID

"did:dock:xyz"

DID as fully qualified, e.g., did:dock:.

Properties

Name Type Required Description
DID string false DID as fully qualified, e.g., did:dock:. You cannot specify your own DID, the DID value will be randomly generated.

KeyType

"sr25519"

This is a schema type of public key for DID.

Enumerated Values

Property Value Description
KeyType sr25519 or ed25519 or secp256k1 keyType DID variants.

SigType

"Sr25519Signature2020"

This is a schema used in Presentation operation that represents a type of signature.

Enumerated Values

Property Value Description
SigType Sr25519Signature2020 or Ed25519Signature2018 or EcdsaSecp256k1Signature2019 SigType signature variants.

ProofPurpose

"assertionMethod"

This is a schema that represents a purpose of credential.

Enumerated Values

Property Value Description
ProofPurpose assertionMethod or authentication Purpose of credential.

Context

[
  "string"
]

This is a schema that represents a JSON-LD context used in DID and Presentation.

DIDDoc

{
  "@context": [
    "string"
  ],
  "id": "did:dock:xyz",
  "authentication": [
    {}
  ]
}

This is a schema that represents a DID document. The current set of properties is incomplete

Properties

Name Type Required Description
@context Context false JSON-LD context.
id DIDQualified false DID as fully qualified, e.g., did:dock:.
authentication array false DID authentication.

Credential

{
  "id": "http://example.com",
  "context": [
    "string"
  ],
  "type": [
    "string"
  ],
  "subject": {},
  "issuer": "did:dock:xyz",
  "issuanceDate": "2019-08-24T14:15:22Z",
  "expirationDate": "2019-08-24T14:15:22Z",
  "status": {}
}

This is a schema that represents a credential format expected by API caller.

Properties

Name Type Required Description
id string(uri) false Credential ID. The default value is a creds.dock.io uri with random ID.
context array false Credential context. The default value is https://www.w3.org/2018/credentials/v1.
type [string] false Credential type. The default value is ['VerifiableCredential']
subject object true Credential subject.
issuer DIDQualified false Credential issuer. DID as fully qualified, e.g., did:dock:. If not supplied the credential will not be signed.
issuanceDate string(date-time[RFC3339]) false The date and time in GMT that the credential was issued specified in RFC 3339 format. The issuanceDate will be automatically set if not provided.
expirationDate string(date-time[RFC3339]) false The date and time in GMT that the credential expired is specified in RFC 3339 format. The default value of the expirationDate will be empty if the user does not provide it.
status object or string false Revocation registry id or user supplied status object.

VerifiablePresentation

{
  "@context": [
    "string"
  ],
  "id": "http://example.com",
  "type": [
    "string"
  ],
  "verifiableCredential": {
    "@context": [
      "string"
    ],
    "id": "http://example.com",
    "type": [
      "string"
    ],
    "credentialSubject": {},
    "issuer": "did:dock:xyz",
    "issuanceDate": "2019-08-24T14:15:22Z",
    "expirationDate": "2019-08-24T14:15:22Z",
    "credentialStatus": {},
    "proof": {
      "type": "Sr25519Signature2020",
      "proofPurpose": "assertionMethod",
      "verificationMethod": "string",
      "created": "2019-08-24T14:15:22Z",
      "proofValue": "string"
    }
  },
  "proof": {
    "type": "Sr25519Signature2020",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "string",
    "created": "2019-08-24T14:15:22Z",
    "proofValue": "string"
  }
}

This is a schema that represents a Verifiable (signed) Presentation returned by API. The current set of properties is almost complete

Properties

Name Type Required Description
@context Context true JSON-LD context.
id string(uri) true Verifiable (signed) presentation id.
type string true Verifiable (signed) presentation type.
verifiableCredential VerifiableCredential true Verifiable (signed) Credential returned by API. The current set of properties is almost complete.
proof object true Proof of credential.

Child Properties of Proof

Name Type Required Description
type SigType true Type of signature.
proofPurpose ProofPurpose true Purpose of credential.
verificationMethod string true Verification method.
created string(date-time[RFC3339]) true The date and time in GMT that the credential was created specified in RFC 3339 format.
proofValue string true none

VerifiableCredential

{
  "@context": [
    "string"
  ],
  "id": "http://example.com",
  "type": [
    "string"
  ],
  "credentialSubject": {},
  "issuer": "did:dock:xyz",
  "issuanceDate": "2019-08-24T14:15:22Z",
  "expirationDate": "2019-08-24T14:15:22Z",
  "credentialStatus": {},
  "proof": {
    "type": "Sr25519Signature2020",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "string",
    "created": "2019-08-24T14:15:22Z",
    "proofValue": "string"
  }
}

This is a schema that represents a verifiable (signed) Credential returned by API. The current set of properties is almost complete.

Properties

Name Type Required Description
@context Context false JSON-LD context.
id string(uri) false Credential id.
type [string] false Credential type.
credentialSubject any false Credential subject.
issuer DIDQualified false Credential issuer or DID as fully qualified, e.g., did:dock:.
issuanceDate string(date-time[RFC3339]) false The date and time in GMT that the credential was issued specified in RFC 3339 format. The issuanceDate will be automatically set if not provided.
expirationDate string(date-time[RFC3339]) false The date and time in GMT that the credential expired is specified in RFC 3339 format. The default value of the expirationDate will be empty if the user does not provide it.
credentialStatus any false Revocation registry id or user supplied status object.
proof object false Proof of credential.

Child Properties of Proof

Name Type Required Description
type SigType false Type of signature.
proofPurpose ProofPurpose false Purpose of credential.
verificationMethod string false Verification method.
created string(date-time[RFC3339]) false The date and time in GMT that the credential was created specified in RFC 3339 format.
proofValue string false Value of credential.

Anchor

{
  "anchor": "string",
  "blockHash": "string",
  "root": "string"
}

An anchor. Either a batched or single. Data includes anchor, type (single, batch), block hash, block number and accompanying data (root, proofs) if any. The data depends if the anchor was created using API or not.

Registry

{
  "addOnly": true,
  "policy": [
    "did:dock:xyz"
  ]
}

This is a schema that represents a Revocation registry used in Revocation or Unrevocation.

Properties

Name Type Required Description
addOnly boolean false If the addOnly value is true, they cannot unrevoke and delete the registry. The default value for this is false.
policy [DID] false Only one policy supported as of now called OneOf.

VerificationResponse

{
  "verified": true
}

This is a schema that used to define whether a credential/presentation is verified or not

Response

{
  "code": 0
}

This is a schema that represents a default response for a request made.