The Ledger API

To write an application around a Daml ledger, you will need to interact with the Ledger API.

Every ledger that Daml can run on exposes this same API.

What’s in the Ledger API

The Ledger API exposes the following services:

  • Submitting commands to the ledger
  • Reading from the ledger
    • Use the transaction service to stream committed transactions and the resulting events (choices exercised, and contracts created or archived), and to look up transactions.
    • Use the active contracts service to quickly bootstrap an application with the currently active contracts. It saves you the work to process the ledger from the beginning to obtain its current state.
  • Utility services
  • Testing services (on Sandbox only, not for production ledgers)
    • Use the time service to obtain the time as known by the ledger.

For full information on the services see The Ledger API Services.

You may also want to read the protobuf documentation, which explains how each service is defined as protobuf messages.

How to Access the Ledger API

You can access the Ledger API via the Java Bindings or the Python Bindings (formerly known as DAZL).

If you don’t use a language that targets the JVM or Python, you can use gRPC to generate the code to access the Ledger API in several supported programming languages. Further documentation provides a few pointers on how you may want to approach this.

You can also use the HTTP JSON API Service to tap into the Ledger API.

At its core, this service provides a simplified view of the active contract set and additional primitives to query it and exposing it using a well-defined JSON-based encoding over a conventional HTTP connection.

A subset of the services mentioned above is also available as part of the HTTP JSON API.


When you compile Daml source into a .dar file, the underlying format is Daml-LF. Daml-LF is similar to Daml, but is stripped down to a core set of features. The relationship between the surface Daml syntax and Daml-LF is loosely similar to that between Java and JVM bytecode.

As a user, you don’t need to interact with Daml-LF directly. But internally, it’s used for:

  • Executing Daml code on the Sandbox or on another platform
  • Sending and receiving values via the Ledger API (using a protocol such as gRPC)
  • Generating code in other languages for interacting with Daml models (often called “codegen”)

When You Need to Know About Daml-LF

Daml-LF is only really relevant when you’re dealing with the objects you send to or receive from the ledger. If you use any of the provided language bindings for the Ledger API, you don’t need to know about Daml-LF at all, because this generates idiomatic representations of Daml for you.

Otherwise, it can be helpful to know what the types in your Daml code look like at the Daml-LF level, so you know what to expect from the Ledger API.

For example, if you are writing an application that creates some Daml contracts, you need to construct values to pass as parameters to the contract. These values are determined by the Daml-LF types in that contract template. This means you need an idea of how the Daml-LF types correspond to the types in the original Daml model.

For the most part the translation of types from Daml to Daml-LF should not be surprising. This page goes through all the cases in detail.

For the bindings to your specific programming language, you should refer to the language-specific documentation.