> For the complete documentation index, see [llms.txt](https://docs.kaiko.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kaiko.com/on-chain/kaiko-data/kaiko-reference-rates/data-on-ramp/canton-request-response-oracle.md).

# Canton request-response oracle

{% hint style="info" %}
This guide provides step-by-step instructions for creating market data requests to Kaiko using the Kaiko oracle on the Canton blockchain. You can see our full range of Reference Rates and Multi-Asset Indices available on Canton [here](https://explorer.kaiko.com/).
{% endhint %}

{% hint style="success" icon="copy" %}
DAR files must be uploaded on your node to use this Oracle [\[Click here to download\]](https://kaiko-delivery-links.s3.us-east-1.amazonaws.com/prepaid-oracle-kaiko-0.0.1.zip)
{% endhint %}

## Overview

The Kaiko oracle enables secure, paid/licensed requests for real-time Reference Rates and Multi-Asset Indices through the Canton blockchain. The system follows the standard request-response oracle workflow:<br>

1. **Prepare request parameters:** Format the Kaiko-specific payload.
2. **Retrieve contracts:** Get the current Amulet rules and open mining round contracts.
3. **Exercise a contract choice:** Submit a transaction to create a data request.

The oracle processes the request off-chain (settling payment via Amulets) and posts the Kaiko market data response back on-ledger.

## Prerequisites

### Required information

You need the following information before starting:

* **Canton participant endpoint:** URL of your Canton participant JSON API
* **Canton authentication token:** Valid token for API access
* **Consumer party ID:** Your party identifier in Canton (e.g., `Consumer::1220...)`
* **RequestFactory contract ID:** Contract ID for the request factory
* **DSO party ID:** DSO party identifier
* **Data provider details (provider-dependent):** Data request payload (stringified JSON)
* **Amulet contract ID:** An Amulet contract to fund payment
* **Payment locked amount:** Amount to lock for the request

### Environment setup

Ensure you have:

* A Canton node connected to the same domain as the oracle node
* The Prepaid Oracle DAR uploaded to your Canton node
* Sufficient Amulet balance for the request

## Creating a Data Request

### Prepare provider request parameters

The Kaiko oracle accepts requests for one or more tickers (real-time reference rates and indices).

#### Input model (Kaiko)

You must prepare the payload as valid JSON and then stringify it for the Canton command.

You must first select the Asset Class for the ticker you need to request. One asset class is allowed per request.

Asset Classes:

* `crypto`: Array of Kaiko tickers for Crypto Assets. E.g.:
  * `KK_RFR_BTCUSD`
  * `KK_RFR_CCUSD`
* `equity`: Array of Kaiko tickers for Equity Assets. E.g.:
  * `KK_RFR_TSLAUSD`

Example Request 1: Accessing Crypto Data

```json
JSON
{
    "crypto": ["KK_RFR_BTCUSD", "KK_RFR_CCUSD"]
}
```

Example Request 2: Accessing Equity Data

```json
{
    "equity": ["KK_RFR_TSLAUSD"]
}
```

#### Stringified payload

When sending the request to Canton, pass the **stringified** version (quotes escaped):

```
"{\"crypto\":[\"KK_RFR_BTCUSD\",\"KK_RFR_CCUSD\"]}"
```

### Submit the request creation transaction

Make a POST request to Canton to exercise the `CreateRequest` choice.

#### **Request Endpoint:**

**POST**

`{PARTICIPANT_NODE_JSON_API_URL}/v2/commands/submit-and-wait-for-transaction-tree`

**Headers**

* `Authorization: Bearer {CANTON_TOKEN}`
* `Content-Type: application/json`

**Request body example:**

```json
{
    "actAs": [
        "{YOUR_CONSUMER_PARTY}"
    ],
    "commandId": "kaiko-request-1",
    "commands": [
        {
            "actAs": [
                "{YOUR_CONSUMER_PARTY}"
            ],
            "commandId": "kaiko-request-1",
            "ExerciseCommand": {
                "contractId": "{REQUEST_FACTORY_CONTRACT_ID}",
                "templateId": "{PACKAGE_ID}:PrepaidOracle.RequestFactory:RequestFactory",
                "choice": "CreateRequest",
                "choiceArgument": {
                    "dso": "{DSO_PARTY}",
                    "amuletRulesCid": "{AMULET_RULES_CONTRACT_ID}",
                    "openRoundCid": "{OPEN_ROUND_CONTRACT_ID}",
                    "inputs": [
                        {
                            "tag": "InputAmulet",
                            "value": "{YOUR_AMULET_CONTRACT_ID}"
                        }
                    ],
                    "dataRequest": "{\"rates\":[\"KK_RFR_BTCUSD\",\"EGLXRT\"]}",
                    "lockedAmount": {PAYMENT_LOCKED_AMOUNT
                    }
                }
            }
        }
    ],
    "disclosedContracts": [
        {
            "templateId": "{AMULET_PACKAGE_ID}:Splice.AmuletRules:AmuletRules",
            "contractId": "{AMULET_RULES_CONTRACT_ID}",
            "synchronizerId": "{GLOBAL_DOMAIN_SYNCHRONIZER_ID}",
            "createdEventBlob": "{AMULET_RULES_DISCLOSED_BLOB}"
        },
        {
            "templateId": "{AMULET_PACKAGE_ID}:Splice.Round:OpenMiningRound",
            "contractId": "{OPEN_ROUND_CONTRACT_ID}",
            "synchronizerId": "{GLOBAL_DOMAIN_SYNCHRONIZER_ID}",
            "createdEventBlob": "{OPEN_ROUND_DISCLOSED_BLOB}"
        }
    ]
}
```

## Reading the `FilledRequest`

Once the oracle processes your request, it archives the pending request and creates a `FilledRequest` contract containing the Kaiko data.

### Query for `FilledRequest`

Use the active contracts endpoint to retrieve the result.

#### Request endpoint

**POST**

`{PARTICIPANT_NODE_JSON_API_URL}/v2/state/active-contracts`

#### Request body filter: filter for template

`{PACKAGE_ID}:PrepaidOracle.Request:FilledRequest.`

### Kaiko response structure

In the resulting `FilledRequest` contract, the `responseData` field contains the stringified Kaiko output.

#### Response data model (Kaiko)

The response is a JSON object keyed by rate id(s), containing the returned value(s).

**Example (conceptual):**

```json
{
    "KK_RFR_BTCUSD": "{\"value\": 76293.2345454545, \"timestamp\": 1772633545286}",
    "KK_RFR_CCUSD": "{\"value\": 0.1698132000, \"timestamp\": 1772633526495}"
}
```

**Example `FilledRequest` content**

```json
{
    "oracle": "{ORACLE_PARTY}",
    "consumer": "{YOUR_CONSUMER_PARTY}",
    "requestData": "{\"rates\":[\"KK_RFR_BTCUSD\",\"KK_RFR_BTCUSD\"]}",
    "responseData": "{\"KK_RFR_BTCUSD\": \"{\\\"value\\\": 76293.2345454545, \\\"timestamp\\\": 1772633545286}\",\"KK_RFR_CCUSD\": \"{\\\"value\\\": 0.1698132000, \\\"timestamp\\\": 1772633526495}\"}",
    "serviceAmountCharged": "1.0000000000"
}
```

## Troubleshooting

### Invalid JSON structure

* **Cause**: The `dataRequest` string was not properly escaped or contained invalid JSON.
* **Solution**: Ensure your stringified JSON does not contain unescaped quotes, stray backslashes, or newlines.

### Unknown/unsupported rate identifier

* Cause: One or more requested rate identifiers are not available to your entitlement, are misspelled, or are not supported by the oracle.
* Solution: Validate the exact rate tickers (e.g., `KK_RFR_BTCUSD)`, confirm access/entitlements, and retry with supported identifiers.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kaiko.com/on-chain/kaiko-data/kaiko-reference-rates/data-on-ramp/canton-request-response-oracle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
