Skip to main content
External calls require a synchronizer running protocol version 36 or later and a Daml package targeting LF 2.4 or later.
External calls let a Daml choice invoke a function on an extension service: a deterministic service that the participant node operator configures and runs alongside the participant. The call’s result is recorded in the transaction, so every confirming participant can validate it against its own extension service before approving the transaction. This extends the ledger model with computations that are impractical to express in Daml (for example, verifying an exotic signature scheme) while preserving the guarantee that all stakeholders agree on the result. This page explains the protocol: how a call travels through the transaction and what the participants verify. For the practical side — a worked example, participant configuration, and the externalCall function — see Using External Calls.

External Call Flow

1

Execute the call at submission time

When a submitted command exercises a choice that uses externalCall, the submitting participant sends the call’s configuration and input payloads to the extension service configured under the requested extension identifier and records the service’s output. Interpretation fails if the extension is not configured, the service cannot be reached after the configured retries, or the service reports an error.
2

Record the result in the transaction

The recorded result — extension identifier, function identifier, configuration, input, and output — travels with the transaction on the exercise node that made the call. Parties that see the exercise node see the recorded result. For externally signed transactions, the recorded results are part of the prepared transaction and are covered by the signed transaction hash (hashing scheme V4).
3

Validate the result at confirmation time

Confirming participants validate recorded results twice over:
  • Consistency — All visible occurrences of the same call (same extension, function, configuration, and input) must record the same output. On a disagreement, every participant that receives the affected views logs a warning with error code EXTERNAL_CALL_RESULT_DISAGREEMENT_ALARM and rejects those views with LOCAL_VERDICT_EXTERNAL_CALL_RESULT_DISAGREEMENT.
  • Re-validation — Participants hosting a checking party of a recorded call re-execute the call against their own extension service and compare the output with the recorded one. A mismatch is treated the same way as a recorded disagreement. A participant that cannot re-validate (for example, because no extension service is configured) abstains from confirming instead of approving.
The checking parties of a call are the surrounding node’s signatories and acting parties. Every call is re-validated by the participants hosting its checking parties; other participants that see the node do not re-execute the call.
4

Use the result

The choice body receives the service output as the result of the externalCall update and can use it like any other value; the transaction commits only if validation succeeds on the confirming participants.

Operational and Security Assumptions

Determinism

Extension services must be deterministic: for a given extension, function, configuration, and input, every honest service instance must always return the same output. The protocol detects non-determinism — validation compares recorded and recomputed outputs — and treats it as suspicious behavior: the affected views are rejected and the EXTERNAL_CALL_RESULT_DISAGREEMENT_ALARM warning is logged. A service that depends on wall-clock time, randomness, or mutable external state will make transactions fail non-deterministically.

Topology and Connectivity

Which nodes need to reach an extension service:
  • The submitting participant executes the call at submission time and therefore needs the extension configured and reachable.
  • Every confirming participant that hosts a checking party of a recorded call re-executes the call at validation time and therefore also needs the same extension (same identifier, semantically identical service) configured and reachable. A confirming participant without the extension abstains, which can prevent the transaction from being committed.
  • Participants that only observe the transaction do not contact the service.
Operators of participants that confirm external-call workflows should treat the extension service as part of the participant’s availability domain: if the service is down, submissions fail at the submitting participant, and validations abstain at the confirming participants.

Trust Model

  • A participant trusts its own extension service to produce correct, deterministic outputs. The service runs under the participant operator’s control and is addressed over an operator-configured endpoint (with optional TLS and bearer-token authentication).
  • A participant does not need to trust another participant’s extension service, nor the submitter: recorded results are re-validated locally against the participant’s own service before confirmation.
  • The extension service sees the configuration and input payloads of every call routed to it, including at validation time for transactions submitted by others. Canton itself never writes payload contents to its logs or error messages — diagnostics carry payload sizes only — but the service must be trusted with the payload data it receives (including what it echoes into its own error responses).

Next Steps

  • Using External Calls — A worked example, the participant configuration, and the externalCall function reference.
  • External Signing Hashing Algorithm — Hashing scheme V4 covers recorded external-call results in externally signed transactions.
  • Error Codes Reference — The external-call validation error codes carry explanations and resolutions generated from the participant sources.