Quickstart
Your first API call in 5 minutes.
Prerequisites
- curl — for making HTTP requests
- jq — for parsing and pretty-printing JSON responses
- A terminal — any shell will do
- Network access to the Medici dev environment (canton.dev.medici.loan and keycloak.dev.medici.loan)
Dev credentials — These examples use the dev environment well-known credentials.
For production, use your own Keycloak client secret and token.
Step 1: Get a Keycloak Token
The Medici protocol uses Keycloak for identity. Every API call needs a Bearer token.
Request one with the client_credentials grant:
# Request a service-account token (RS256 JWT, 5-minute expiry) TOKEN=$(curl -s -X POST \ "https://keycloak.dev.medici.loan/realms/AppUser/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=medici-app" \ -d "client_secret=" \ | jq -r '.access_token') # Verify the token echo "Token length: ${#TOKEN} chars" echo "Token preview: ${TOKEN:0:50}..." # Decode the payload (middle segment) to inspect claims echo "$TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq
Token expiry: RS256 tokens live 5 minutes. The Ledger Service auto-refreshes,
but if you are calling Canton directly you must refresh before expiry.
Step 2: Health Check
Verify the Ledger Service is up and connected to Canton:
curl -s "https://canton.dev.medici.loan/api/v1/health" | jq
# Expected response:
# {
# "status": "ok",
# "canton": "connected",
# "uptime": "12s"
# }
If you are using the Ledger Service (recommended), check its health endpoint:
# Ledger Service health (if running locally) curl -s "http://localhost:8080/api/v1/health" | jq
Step 3: Read Active Contracts
Query active contracts on the Canton ledger. This example reads PublishedPrice
contracts (the public price feed):
# Via Ledger Service (recommended — simpler, handles Canton quirks)
curl -s \
-H "Authorization: Bearer $TOKEN" \
"http://localhost:8080/api/v1/contracts/OptionIndex.Oracle/PublishedPrice" \
| jq
# Direct Canton query (advanced — raw /v2/state/active-contracts)
curl -s -X POST \
"https://canton.dev.medici.loan/v2/state/active-contracts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"activeAtOffset": "",
"templateIds": ["#option-index-tracker-v3:OptionIndex.Oracle:PublishedPrice"],
"includeCreatedEventBlob": false
}' | jq
Package ID note: The package reference uses the upgrade-transparent
package-name form (
#option-index-tracker-v3), not a content hash. This
ensures the reference never goes stale across DAR rebuilds.
Step 4: Submit a Command (Optional)
Create a SplitRequest to split collateral into P and N tokens
(requires a funded party on the ledger):
# Via Ledger Service — see /api/ for the full submit schema
curl -s -X POST \
"http://localhost:8080/api/v1/commands/submit" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"templateId": "OptionIndex.Core.SplitRequest",
"payload": {
"depositor": "",
"vaultAdmin": "",
"amount": "100.0",
"strike": "50.0",
"maturity": "2027-01-01T00:00:00Z",
"ticker": "BTC/USDC",
"baseAsset": "ETH",
"quoteAsset": "USDC",
"oracle": "",
"admin": "",
"settlementDelaySeconds": "0",
"refCid": null
}
}' | jq
Next Steps
| Topic | Page |
|---|---|
| Understand authentication in depth | Authentication |
| Full API reference (all 13 endpoints) | Ledger Service API |
| Template field-by-field reference | DAML Templates |
| How the system fits together | Architecture |
| Learn the concepts behind the protocol | Learn |
| Strategies and intent-based trading | Strategy Engine |