Using JSON API with CANTON
I am trying to setup my canton arquitecture with json api,
When i try to create contracts with json api i get this error:
allocateParty creates a new party everytime you run it. So if you run your Daml Script multiple times you get different parties each time which sounds like that’s what’s been happening here: You’ve run it once via initializeUser and then once via allocateParties directly. I recommend to have initializeUser return LedgerParties and then only run that once. If you run it via daml start, you can set the --output-file flag via daml start --script-option --output-file=parties.json. For the Alice::… …
At first i tried with the commands in this post, but as i am creating my canton network i follow the example in documentation : Getting Started — Daml SDK 2.7.6 documentation
A participant is created, which connects to a domain, the dar file is uploaded, but it is not possible to create the contract,
What am i missing here?
Can you share your Canton setup & config? How did you create the participant, connect the domain, …?
Participant1 (remote) config file:

Participant1 init:

Participant1 status:
Participant2 (remote) config file:

Participant2 init:

Participant2 status:
Domain (remote) config file:

Domain status:
To create contrats i use the party id in the parties.json file as you said in this topic:
Hello cocreature, thanks for the answer, I understood what i got wrong, and i already create a contract with JSON API, First my partyid was wrong, i got it from navigator: [image] ALICE: party-cf4ce109-c007-45d7-839e-2f7756e5e5de::1220124aba0791c61bac337ed9319ce99bf9e96259acb554c2fbb244d20155bcfc95 BOB: party-660bf503-c37d-4aca-88ed-b2df54d1e940::1220124aba0791c61bac337ed9319ce99bf9e96259acb554c2fbb244d20155bcfc95 I fill out asker with partyid ALICE and answerer with partyid BOB, This …
Are you trying to do a multi-party submission, i.e., does your user have actAs & readAs rights for both Alice & Bob (or if you’re not using user management, do you have a token with actAs & readAs claims for both)?
All parties you submit for must be hosted on the same participant.
Yes, i want to create contracts with alice and exercise them with bob, (both remote participants) and then store the contracts in postgres.
I have a JWT token with actAs (partyID Alice) and readAs (partyID Bob), but i got these partyID from the json file created early whit this command:
daml start --script-option --output-file=parties.json
I was uploading the dar file on the participants and not in the domain.
participants.all.dars.upload(“Project/.daml/dist/Project-0.0.1.dar”)
Dar uploaded in the domain and now i am getting this error, and i have not changed the code, any clue?
Just to clarify, the party ids in this canton arquitecture ( Participant1, Participant2 and Domain) are the same as the ones created in the json file? because i uploaded that dar, correct?
Thank you
The parties in the JSON file will be on the Canton participant if the daml script command that produced the JSON file was run agains that participant.
Party creation has nothing to do with DAR uploads; the fact that daml script can run a DAR does not mean that uploading that same DAR to a ledger has any effect.
It’s unclear that parties or party IDs are the problem in your screenshot, though. That screenshot does look like a missing DAR files on the Canton ledger.
Hello Gary, thanks for the answer, i understand now the connection between the JSON file and Canton, but i am still getting that error,
I run the command “daml start --script-option --output-file=parties.json” in remote domain that updated the JSON file.
I uploaded the dar in the remote domain with the comand:
participants.all.dars.upload(“Project/.daml/dist/Project-0.0.1.dar”)
and checked in both remote participants with the command:
participant1.dars.list()
participant2.dars.list()
Using Json Api in participant1 and with the parties in json file created by first command, i try to create a contract without success,
What am i doing wrong?
Hi @Bernardo,
We’ll need a little bit more information on exactly how you’ve set things up here. First off, daml start is a development convenience tool that may not be suitable at all. It generally starts a sandbox and runs its scripts against it, which may not be related to any of your otherwise running participants.
Can you share, specifically:
- Your daml.yaml.
- Whether you run any other command than
daml start(e.g. to start an additional participant, or the JSON API), and if so which ones.
Thank you for your support,
My yaml file:
sdk-version: 2.1.1 name: Project source: daml version: 0.0.1 init-script: Lights:initializeUser dependencies: - daml-prim - daml-stdlib - daml-script
My file.daml:
module Lights where import Daml.Script type RequestChangeId = ContractId RequestChange type ChangeId = ContractId Change data Place = Room | Living_Room | Hall | Conference_Room deriving(Eq,Show) data State = ON | OFF deriving(Eq,Show) -- LEDGER_PARTIES_BEGIN data LedgerParties = LedgerParties with alice : Party bob : Party -- LEDGER_PARTIES_END template RequestChange with asker : Party answerer : Party place : Place currentState : State where signatory asker observer answerer choice Accept : ChangeId with feedback : Text newState : State controller answerer do assertMsg "A state cannot be changed for equal." (currentState /= newState) create Change with .. template Change with asker : Party answerer : Party place : Place newState : State feedback : Text where signatory asker, answerer -- INITIALIZE_USER_BEGIN initializeUser : Script LedgerParties initializeUser = do partyAlice <- allocatePartyWithHint "alice" (PartyIdHint "alice") partyBob <- allocatePartyWithHint "bob" (PartyIdHint "bob") alice <- validateUserId "alice" bob <- validateUserId "bob" _ <- createUser (User alice (Some partyAlice)) [CanActAs partyAlice] _ <- createUser (User bob (Some partyBob)) [CanActAs partyBob] --pure() pure (LedgerParties partyAlice partyBob) -- INITIALIZE_USER_END
To initialize Domain:
To initialize Participant1:
To initialize Participant2:
After Initialization in Domain (Participants connected):
Upload Dar in domain:
Check in Participant1:
start JSON API in participant1:
JSON API ERROR:
Can you run daml damlc inspect-dar --json path/to/your/dar | jq '.main_package_id' to get the package id of the DAR you’re uploading and then check if it’s contained in the list of package ids you see in the JSON API log?
.main_package_id wasn’t a placeholder. You should actually run that.
You missed the dot before main_package_id.
Any chance you could get us the text of those messages instead of screenshots? It’s really hard to check whether that template ID is in the list given by the JSON API based on screenshots.
Of course,
daml damlc inspect-dar --json .daml/dist/Project-0.0.1.dar | jq ‘.main_package_id’
“3db632339c92e02b15d4c15df0cb4363f41a9ff91c7a8eecf7eb67a35ff07b54”
JSON API
DAML_SDK_VERSION=2.1.1 daml json-api --ledger-host 192.168.61.128 --ledger-port 5011 --http-port 7575 --allow-insecure-tokens
07-06-2022 11:35:00.790 [main] INFO com.daml.http.Main - Config(ledgerHost=192.168.61.128, ledgerPort=5011, address=127.0.0.1, httpPort=7575, portFile=None, packageReloadInterval=5 seconds, packageMaxInboundMessageSize=None, maxInboundMessageSize=4194304, tlsConfig=TlsConfiguration(false,None,None,None,None,REQUIRE,false,None), jdbcConfig=None, staticContentConfig=None, allowNonHttps=true, wsConfig=None, nonRepudiationCertificateFile=None, nonRepudiationPrivateKeyFile=None, nonRepudiationPrivateKeyAlgorithm=None, surrogateTpIdCacheMaxEntries=None), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:01.235 [http-json-ledger-api-akka.actor.default-dispatcher-6] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
07-06-2022 11:35:01.595 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.HttpService - HTTP Server pre-startup, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:01.932 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempting to connect to the ledger 192.168.61.128:5011 (600 attempts), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.697 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempt 1/600 succeeded!, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.702 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempting to connect to the ledger 192.168.61.128:5011 (600 attempts), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.707 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.LedgerClient - Attempt 1/600 succeeded!, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:02.708 [http-json-ledger-api-akka.actor.default-dispatcher-9] INFO com.daml.http.HttpService - contractDao: None, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:35:03.437 [http-json-ledger-api-akka.actor.default-dispatcher-8] INFO com.daml.http.Main - Started server: (ServerBinding(/127.0.0.1:7575),None), context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”}
07-06-2022 11:36:07.481 [http-json-ledger-api-akka.actor.default-dispatcher-6] INFO com.daml.http.Endpoints - Incoming POST request on http://localhost:7575/v1/create from unknown, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”, request_id: “d8318328-9493-44c5-a1bb-4b95571012ec”}
07-06-2022 11:36:11.659 [http-json-ledger-api-akka.actor.default-dispatcher-15] INFO com.daml.http.PackageService - new package IDs loaded: 86828b9843465f419db1ef8a8ee741d1eef645df02375ebf509cdc8c3ddd16cb, cc348d369011362a5190fe96dd1f0dfbc697fdfd10e382b9e9666f0da05961b7, 6839a6d3d430c569b2425e9391717b44ca324b88ba621d597778811b2d05031d, 99a2705ed38c1c26cbb8fe7acf36bbf626668e167a33335de932599219e0a235, e22bce619ae24ca3b8e6519281cb5a33b64b3190cc763248b4c3f9ad5087a92c, d58cf9939847921b2aab78eaa7b427dc4c649d25e6bee3c749ace4c3f52f5c97, 6c2c0667393c5f92f1885163068cd31800d2264eb088eb6fc740e11241b2bf06, 8a7806365bbd98d88b4c13832ebfa305f6abaeaf32cfa2b7dd25c4fa489b79fb, c1f1f00558799eec139fb4f4c76f95fb52fa1837a5dd29600baa1c8ed1bdccfd, 733e38d36a2759688a4b2c4cec69d48e7b55ecc8dedc8067b815926c917a182a, 65921e553a353588e950cbc87e98a127730e63295f7ad8d3adae952ef0133b3e, f20de1e4e37b92280264c08bf15eca0be0bc5babd7a7b5e574997f154c00cb78, 3f4deaf145a15cdcfa762c058005e2edb9baa75bb7f95a4f8f6f937378e86415, bfcd37bd6b84768e86e432f5f6c33e25d9e7724a9d42e33875ff74f6348e733f, 57b5c520512c24035057aa4c783cb7ac7f3f49db29806280962e188be7aadb66, 518032f41fd0175461b35ae0c9691e08b4aea55e62915f8360af2cc7a1f2ba6c, cb0552debf219cc909f51cbb5c3b41e9981d39f8f645b1f35e2ef5be2e0b858a, 76bf0fd12bd945762a01f8fc5bbcdfa4d0ff20f8762af490f8f41d6237c6524f, 852d8e3a8ccf952acc73e17522846bc1eb41498e840d637e519ddcca7dbc7671, d14e08374fc7197d6a0de468c968ae8ba3aadbf9315476fd39071831f5923662, 057eed1fd48c238491b8ea06b9b5bf85a5d4c9275dd3f6183e0e6b01730cc2ba, e491352788e56ca4603acc411ffe1a49fefd76ed8b163af86cf5ee5f4c38645b, 40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7, 97b883cd8a2b7f49f90d5d39c981cf6e110cf1f1c64427a28a6d58ec88c43657, context: {ledger_id: “participant1”, request_id: “d8318328-9493-44c5-a1bb-4b95571012ec”, instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”, application_id: “foobar”, read_as: “List(bob::1220649b43530aabe92d941de529d021b18ac09cefd0880f5df928a47effd80f40c8)”, act_as: “List(alice::1220649b43530aabe92d941de529d021b18ac09cefd0880f5df928a47effd80f40c8)”}
07-06-2022 11:36:11.671 [http-json-ledger-api-akka.actor.default-dispatcher-15] INFO com.daml.http.Endpoints - Responding to client with HTTP 400 Bad Request, context: {instance_uuid: “443f6023-8541-430b-94b7-ceec4c2634d1”, request_id: “d8318328-9493-44c5-a1bb-4b95571012ec”}
i checked the package IDs loaded and it is not there
Looking at your earlier logs, I don’t see the DAR actually uploaded: participant1.dars.list() shows only the builtin AdminWorkflows not your own DAR.
Maybe try uploading via daml ledger upload-dar to participant 1.
Hi @Bernardo,
That error is not actually surprising at that point. Let’s go back a step: when you tell the domain to upload a DAR to all participants, the DAR does not get added to participant1. But when you explicitly upload to participant1, that works, so participant1 itself is not broken.
This suggests that your first issue is that the domain and the participants are somehow not talking to each other, which seems to be corroborated by this new error message. I’m also a bit surprised that the result to your participants.all.dars.upload command is empty. I’d somehow expect a map of participant to result there.
I’m not familiar enough with Canton to help with debugging this but I think that’s the first thing you should look into. (Moving forward, we’ve still not solved the daml start issue either, but one thing at a time.)
when you tell the domain to upload a DAR to all participants, the DAR does not get added to participant1. But when you explicitly upload to participant1, that works, so participant1 itself is not broken.
I updated the domain conf file, and added both participants:
canton { domains { mydomain { storage.type = memory admin-api { port = 10017 address = 192.168.61.129 // is the default value if omitted } public-api { port = 10018 address = 192.168.61.129 // is the default value if omitted } } } remote-participants { participant1 { admin-api { port = 5012 address = 192.168.61.128 } ledger-api { port = 5011 address = 192.168.61.128 } } } remote-participants { participant2 { admin-api { port = 5012 address = 192.168.61.130 } ledger-api { port = 5011 address = 192.168.61.130 } } } }
This is why now i am able to upload the dar and it is visible to participant1 and 2
(Moving forward, we’ve still not solved the
daml startissue either, but one thing at a time.)
I just use the daml start --script-option --output-file=parties.json to get the Party ids, in order to create contracts with json api. I need the Party id for alice and bob that are specified in that file.
Thank you for your time, hope Moritz can help me
Thank you for your time, hope Moritz can help me
It’s not entirely clear what problem you’re now facing. You tell us the dar upload is now working; can you explain what you still need help with? What error are you now seeing?
That’s a weird error essage, but let’s assume for a second it may be related to the daml start issue. When you run daml start, by default it will run a local sandbox and run its commands against that. I’m not seeing anything in your daml.yaml or your CLI arguments to overwrite that default behaviour. This means that the parties you have created with your script get created on the sandbox created by daml start, and not on the participants in your domain.
In order to create the parties, you’ll need to run the script against the appropriate participant (I imagine that, as you have two participants, you probably want to create different parties in each one). You can do that with the daml script command, which, unlike daml start, does not start its own sandbox but instead runs against the participant you point it to (run daml script --help for details). You’ll need to first compile the DAR containing your script with daml build, then run something like:
daml script --dar PATH_TO_DAR \
--ledger-host 192.168.61.128 \
--ledger-port 5011 \
--output-file PARTIES_PART1.json \
--script-name module:function \
--input-file INPUT_PART1.json
with uppercase things changed to appropriate values (you may or may not need an input-file, depending on the details of your script).
It worked! Thank you very much! ![]()
The correct party id was the participant’s!
Happy to help!
Would you mind marking the question as resolved? You can always open a new thread if you have further questions down the line.















