JSON REST API Documentation

Authentication

You need to be authenticated for most API requests. You can generate a party specific API key in the form of a JWT token in your Project Settings dashboard. Choose the DAML Party that will authorize the requests and then copy the token to your clipboard in the format of your choice. Copy token to clipboard

Add the JWT token to all requests as an HTTP Header parameter, in order to authenticate them to that party.

Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRhYmwtMjAxOS0wOC0wNy0xNz...

Most API requests require authentication. Requests that require authentication will fail unless you include a JWT Token. For more information on the API surface available for identity, see the IAM docs.

For streaming endpoints, in order to accommodate the requirement for an authentication token within the websocket protocol, the token needs to be passed by the "subprotocol" header. It is usually specified as a list, but can occasionally be specified in comma-separated form. Check the documentation for your WebSocket library of choice for details.

You must pass two subprotocols to establish proper handshake:

  • daml.ws.auth
  • jwt.token.[your-jwt-token-here]
Sec-Websocket-Protocol: jwt.token.eyJhbGciOiJSUzI1NiIsImtpZCI6ImRhYmwtMjAxOS0wOC0wNy0xNz..., daml.ws.auth

JSON API Endpoints

DABL supports a mirror of DAML SDK's JSON API endpoints:

Find full API Specs here.

Reading Data from the Ledger

GET /data/:ledgerId/v1/query

Description

The following example demonstrates fetch all contracts for given party token.

HTTP GET request

GET /data/:ledgerId/v1/query HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN

HTTP success Response

{
     "result": [
         {
             "agreementText": "",
             "contractId": "#48:0",
             "observers": [],
             "payload": {
                 "issuer": "f8htpbsywu4nef6x",
                 "owner": "f8htpbsywu4nef6x",
                 "name": "squidly"
             },
             "signatories": [
                 "f8htpbsywu4nef6x"
             ],
             "templateId": "b3488a9041bb7994eb9ec629cb700e78c1c619e9be7d711ff22b0cadfcce3fbe:Main:Asset"
         }
     ],
     "status": 200
 }

POST /data/:ledgerId/v1/query

Description

POST request with search query in JSON body for matching contracts based on user-defined criteria. Please see detailed reference for contract search language.

The following will fetch all contracts with templateId Iou.Iou

HTTP POST request

POST /data/:ledgerId/v1/query HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application/json
 {
     "templateIds": ["Iou:Iou"],
     "query": {"amount": 100.0}
 }

HTTP success Response

{
     "result": [
         {
             "agreementText": "",
             "contractId": "#470:0",
             "observers": [],
             "payload": {
                 "observers": [],
                 "issuer": "rztds0vfs6hgd1np",
                 "amount": "100.0",
                 "currency": "USD",
                 "owner": "rztds0vfs6hgd1np"
             },
             "signatories": [
                 "rztds0vfs6hgd1np"
             ],
             "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
         }
     ],
     "status": 200
 }

Empty Response

{
     "status": 200,
     "result": []
 }

HTTP Error Response

{
     "status": 400,
     "errors": [
         "JsonReaderError. Cannot read JSON: <{\"%templates\":[{\"moduleName\":\"Iou\"}]}>. Cause: Object is missing required member 'entityName'"
     ]
 }

POST /data/:ledgerId/v1/fetch

Description

POST request to lookup contract by contractID or contractKey.

The following will lookup contracts with contractId #1:0.

HTTP POST request

POST /data/:ledgerId/v1/fetch HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application/json
 {
   "contractId": "#1:0"
 }

Contract Found response

{
     "result": {
         "agreementText": "",
         "contractId": "#1:0",
         "observers": [],
         "payload": {
             "observers": [],
             "issuer": "rztds0vfs6hgd1np",
             "amount": "100.0",
             "currency": "USD",
             "owner": "rztds0vfs6hgd1np"
         },
         "signatories": [
             "rztds0vfs6hgd1np"
         ],
         "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
     },
     "status": 200
 }

Contract Not Found Response

{
     "status": 200,
     "result": null
 }

The following will lookup contracts with contractKey:

POST /data/:ledgerId/v1/fetch HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application/json
 {
     "templateId": "Account:Account",
     "key": [
         "Alice",
         "abc123"
     ]
 }

Contract Found Response

{
     "status": 200,
     "result": {
         "observers": [],
         "agreementText": "",
         "payload": {
             "owner": "Alice",
             "number": "abc123",
             "status": {
                 "tag": "Enabled",
                 "value": "2020-01-01T00:00:01Z"
             }
         },
         "signatories": [
             "Alice"
         ],
         "key": {
             "_1": "Alice",
             "_2": "abc123"
         },
         "contractId": "#697:0",
         "templateId": "11c8f3ace75868d28136adc5cfc1de265a9ee5ad73fe8f2db97510e3631096a2:Account:Account"
     }
 }

Contract Not Found Response

{
     "status": 200,
     "result": null
 }

Writing Data to the Ledger

POST /data/:ledgerId/v1/create

Parameter Description
templateId TemplateId JsObject containing moduleName and entityName
payload JsObject containing list of key-value pairs defined in the target template's fields

request for Create:

POST /data/:ledgerId/v1/create HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application/json
 {
   "templateId": "Iou:Iou",
   "payload": {
     "observers": [],
     "issuer": "rztds0vfs6hgd1np",
     "amount": "999.99",
     "currency": "USD",
     "owner": "rztds0vfs6hgd1np"
   }
 }

HTTP Success response

{
     "result": {
         "agreementText": "",
         "contractId": "#474:0",
         "observers": [],
         "payload": {
             "observers": [],
             "issuer": "rztds0vfs6hgd1np",
             "amount": "999.99",
             "currency": "USD",
             "owner": "rztds0vfs6hgd1np"
         },
         "signatories": [
             "rztds0vfs6hgd1np"
         ],
         "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
     },
     "status": 200
 }

HTTP Error response

{
     "status": 400,
     "errors": [
         "JsonError: lookupLfIdentifier: PackageService input error: Cannot resolve templateId: TemplateId(None,Iou,Iou_Foo)"
     ]
 }

POST /data/:ledgerId/v1/exercise

Parameter Description
templateId TemplateId JsObject containing moduleName and entityName
contractId contractId of the target contract
choice Name of the choice to exercise
argument JsObject containing list of key-value pairs to the choice. if the choice does not accept any arguments then an empty object must be used.

request for exercise by contractId:

POST /data/:ledgerId/v1/exercise HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application/json
 {
     "templateId": "Iou:Iou",
     "contractId": "#474:0",
     "choice": "Iou_Transfer",
     "argument": {
         "newOwner": "Alice"
     }
 }

HTTP Success Response

{
     "result": {
         "events": [
             {
                 "archived": {
                     "contractId": "#474:0",
                     "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
                 }
             },
             {
                 "created": {
                     "agreementText": "",
                     "contractId": "#475:1",
                     "observers": [
                         "kx8tm3t10cxlapn5"
                     ],
                     "payload": {
                         "iou": {
                             "observers": [],
                             "issuer": "rztds0vfs6hgd1np",
                             "amount": "999.99",
                             "currency": "USD",
                             "owner": "rztds0vfs6hgd1np"
                         },
                         "newOwner": "kx8tm3t10cxlapn5"
                     },
                     "signatories": [
                         "rztds0vfs6hgd1np"
                     ],
                     "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:IouTransfer"
                 }
             }
         ],
         "exerciseResult": "#475:1"
     },
     "status": 200
 }

HTTP Error Response

{
    "status": 500,
    "errors": [
        "INVALID_ARGUMENT: Command interpretation error in LF-DAMLe: dependency error: couldn't find contract AbsoluteContractId(#21:0). Details: N/A."
    ]
}

Request for exercise by Contract Key:

POST /data/:ledgerId/command/exercise HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application/json
 {
     "templateId": "Account:Account",
     "key": ["Alice", "abc123"],
     "choice": "Archive",
     "argument": {}
 }

HTTP Success Response

{
      "status": 200,
      "result": {
          "exerciseResult": "#201:1",
          "events": [
              {
                  "archived": {
                      "contractId": "#124:0",
                      "templateId": "11c8f3ace75868d28136adc5cfc1de265a9ee5ad73fe8f2db97510e3631096a2:Iou:Iou"
                  }
              },
              {
                  "created": {
                      "observers": [],
                      "agreementText": "",
                      "payload": {
                          "iou": {
                              "observers": [],
                              "issuer": "Alice",
                              "amount": "999.99",
                              "currency": "USD",
                              "owner": "Alice"
                          },
                          "newOwner": "Alice"
                      },
                      "signatories": [
                          "Alice"
                      ],
                      "contractId": "#201:1",
                      "templateId": "11c8f3ace75868d28136adc5cfc1de265a9ee5ad73fe8f2db97510e3631096a2:Iou:IouTransfer"
                  }
              }
          ]
      }
  }

POST /data/:ledgerId/v1/create-and-exercise

Parameter Description
templateId TemplateId JsObject containing moduleName and entityName
payload JsObject containing list of key-value pairs defined in the target template's fields
choice Name of the choice to exercise
argument JsObject containing list of key-value pairs to the choice. if the choice does not accept any arguments then an empty object must be used.

HTTP POST request for Create:

POST /data/:ledgerId/create-and-exercise HTTP/1.1
 Host: api.projectdabl.com
 Authorization: Bearer YOUR_TOKEN
 Content-Type: application.json
 {
   "templateId": "Iou:Iou",
   "payload": {
     "observers": [],
     "issuer": "dz1ys3yl4g41e1m2",
     "amount": "999.99",
     "currency": "USD",
     "owner": "dz1ys3yl4g41e1m2"
   },
   "choice": "Iou_Transfer",
   "argument": {
     "newOwner": "lopiw5orw840lr01"
   }
 }

Http Success Response

{
    "result": {
        "events": [
            {
                "created": {
                    "agreementText": "",
                    "contractId": "#190:0",
                    "observers": [],
                    "payload": {
                        "observers": [],
                        "issuer": "dz1ys3yl4g41e1m2",
                        "amount": "999.99",
                        "currency": "USD",
                        "owner": "dz1ys3yl4g41e1m2"
                    },
                    "signatories": [
                        "dz1ys3yl4g41e1m2"
                    ],
                    "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
                }
            },
            {
                "archived": {
                    "contractId": "#190:0",
                    "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:Iou"
                }
            },
            {
                "created": {
                    "agreementText": "",
                    "contractId": "#190:2",
                    "observers": [
                        "lopiw5orw840lr01"
                    ],
                    "payload": {
                        "iou": {
                            "observers": [],
                            "issuer": "dz1ys3yl4g41e1m2",
                            "amount": "999.99",
                            "currency": "USD",
                            "owner": "dz1ys3yl4g41e1m2"
                        },
                        "newOwner": "lopiw5orw840lr01"
                    },
                    "signatories": [
                        "dz1ys3yl4g41e1m2"
                    ],
                    "templateId": "ec4ff7a9c2adb530faf269fac0678b700aa0f99faa7624f3fdb97536b544830f:Iou:IouTransfer"
                }
            }
        ],
        "exerciseResult": "#190:2"
    },
    "status": 200
}

Streaming Data from the Ledger

Get all contracts for a party continuously

Streaming /data/:ledgerId/v1/stream/query

See how to pass a token with websockets here.

Stream Query Parameters

  • URL: /v1/stream/query
  • Scheme: ws
  • Protocol: WebSocket

Lists currently active contracts that match a given query, with continuous updates.

A body of content type application/json must be sent first, formatted according to contract search query doc.

{"templateIds": ["Iou:Iou"]}

Multiple queries may be specified in an array, for overlapping or different sets of template IDs:

[
     {"templateIds": ["Iou:Iou"], "query": {"amount": {"%lte": 50}}},
     {"templateIds": ["Iou:Iou"], "query": {"amount": {"%gt": 50}}},
     {"templateIds": ["Iou:Iou"]}
 ]

Output is a series of JSON documents, each payload formatted according to contract search query doc.

{
     "events": [
         {
             "created": {
                 "observers": [],
                 "agreementText": "",
                 "payload": {
                     "observers": [],
                     "issuer": "Alice",
                     "amount": "999.99",
                     "currency": "USD",
                     "owner": "Alice"
                 },
                 "signatories": [
                     "Alice"
                 ],
                 "contractId": "#1:0",
                 "templateId": "b70bbfbc77a4790f66d4840cb19f657dd20848f5e2f64e39ad404a6cbd98cf75:Iou:Iou"
             },
             "matchedQueries": [
                 1,
                 2
             ]
         }
     ]
 }

Upstream documentation is here.

Streaming /data/:ledgerId/v1/stream/fetch

See how pass a token with websockets here.

Stream Fetch Parameters

  • URL: /v1/stream/fetch
  • Scheme: ws
  • Protocol: WebSocket

List currently active contracts that match one of the given {templateId, key} pairs, with continuous updates.

application/json body must be sent first, formatted according to the following rule:

[
     {"templateId": "<template ID 1>", "key": <key 1>},
     {"templateId": "<template ID 2>", "key": <key 2>},
     ...
     {"templateId": "<template ID N>", "key": <key N>}
 ]

Where:

  • templateId -- contract template identifier, same as in :ref:create request <create-request>,
  • key -- contract key, formatted according to the :doc:lf-value-specification,

Example:

[
     {"templateId": "Account:Account", "key": {"_1": "Alice", "_2": "abc123"}},
     {"templateId": "Account:Account", "key": {"_1": "Alice", "_2": "def345"}}
 ]

The output stream has the same format as the output from the Contracts Query Stream_. We further guarantee that for every archived event appearing on the stream there has been a matching created event earlier in the stream.

Upstream documentation here.

Summary

These interfaces together form an API surface to enable both RPC style and streaming access to your DAML contracts using conventional web access norms.