> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Datasets

> Create datasets to test LLM models at scale. Define inputs, messages, and expected outputs for experiments. Manage datasets via the AI Studio, API, or Orq MCP.

Datasets hold the test data that powers [Experiments](/docs/experiments/build). Each dataset row contains up to three fields:

* **Inputs**: Variables injected into the prompt at runtime, e.g. `{{firstname}}`.
* **Messages**: The prompt template, structured with system, user, and assistant roles.
* **Expected Outputs**: Reference responses evaluators compare against model outputs.

You don't need all three fields in every dataset. A dataset with only inputs, or only messages, is valid.

## Use Cases

<AccordionGroup>
  <Accordion title="Regression and pre-deployment testing" icon="flask">
    Run the same dataset through your prompts before and after a change to verify that updates haven't degraded performance in any area.
  </Accordion>

  <Accordion title="Compare models and prompt variants" icon="sparkles">
    Use the same dataset across multiple models or prompt configurations in an [Experiment](/docs/experiments/build) to find the best combination of quality, cost, and latency.
  </Accordion>

  <Accordion title="Curated datasets for fine-tuning" icon="sliders">
    Have domain experts review and correct model outputs, then save those verified input/output pairs as a curated dataset to use as fine-tuning reference data.
  </Accordion>

  <Accordion title="Synthetic data generation at scale" icon="wand-magic-sparkles">
    Use the Orq MCP to generate hundreds of realistic test cases programmatically and add them directly to a dataset without leaving your IDE.
  </Accordion>

  <Accordion title="Vision and image datasets" icon="image">
    Build datasets with image messages for testing vision models. Supports JPEG, PNG, GIF, and WebP via the AI Studio or API.
  </Accordion>
</AccordionGroup>

## Create a Dataset

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Use the `+` button on a [Project](/docs/projects/overview) folder and select **Dataset**. Enter a title to open the **Table View**.

    The table has three columns: **Inputs**, **Messages**, and **Expected Outputs**. Add as many rows as needed.

    ![Create a Dataset](https://files.readme.io/6c5eb05e76d2417de2b84c55fd348af92f7f96183510b62d5b080312476ee05f-datasetsv2.gif)
  </Tab>

  <Tab title="API & SDK" icon="code">
    Use the [Create Dataset API](/reference/datasets/create-a-dataset). A unique `display_name` and a `path` (the Project folder) are required.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/datasets \
           --header 'accept: application/json' \
           --header 'authorization: Bearer ORQ_API_KEY' \
           --header 'content-type: application/json' \
           --data '{
        "display_name": "MyDataset",
        "path": "Default"
      }'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          res = orq.datasets.create(request={
              "display_name": "MyDataset",
              "path": "Default",
          })
          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({ apiKey: process.env["ORQ_API_KEY"] ?? "" });

      const result = await orq.datasets.create({
        displayName: "MyDataset",
        path: "Default",
      });

      console.log(result);
      ```
    </CodeGroup>

    The response includes a `_id` field (the dataset ID) used in subsequent calls.

    <Tip>See the full [Create Dataset API reference](/reference/datasets/create-a-dataset).</Tip>
  </Tab>

  <Tab title="MCP" icon="https://mintcdn.com/orqai/i7ZhKI7LFRfXU7ox/images/logos/mcp.svg?fit=max&auto=format&n=i7ZhKI7LFRfXU7ox&q=85&s=cef7916eb5fe1f6bb97541398d3f7639" width="16" height="16" data-path="images/logos/mcp.svg">
    **Create a dataset:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Create a dataset called "Support Training Data" in the Default project
    ```

    The assistant uses `create_dataset` with the display name and path.

    ***

    **Generate a synthetic dataset:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Generate 50 realistic customer support questions about a SaaS product and create a dataset called "Support Training Data"
    ```

    The assistant generates the entries, uses `create_dataset` to create the dataset, then uses `create_datapoints` to add all entries in bulk.

    ***

    **Find an existing dataset:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Find the "user-queries" dataset in my workspace
    ```

    The assistant uses `search_entities` with `type: "dataset"` to locate it by name.
  </Tab>
</Tabs>

### Add Datapoints

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    **Manually:** Click **Add Row** and fill in each cell.

    **From CSV:** Click **Import** and drag-and-drop a `.csv` file. Map each CSV column to a Dataset field (Inputs, Messages, Expected Outputs). Each row becomes a separate datapoint.
  </Tab>

  <Tab title="API & SDK" icon="code">
    Use the [Create Datapoints API](/reference/datasets/create-a-datapoint). Send between 1 and 5,000 datapoints per request. Requests over 500 datapoints are automatically chunked.

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request POST \
           --url https://api.orq.ai/v2/datasets/DATASET_ID/datapoints \
           --header 'accept: application/json' \
           --header 'authorization: Bearer ORQ_API_KEY' \
           --header 'content-type: application/json' \
           --data '[
        {
          "inputs": {"country": "France"},
          "messages": [
            {"role": "user", "content": "Capital of {{country}}?"},
            {"role": "assistant", "content": "Paris"}
          ],
          "expected_output": "Paris"
        },
        {
          "inputs": {"country": "Germany"},
          "messages": [
            {"role": "user", "content": "Capital of {{country}}?"},
            {"role": "assistant", "content": "Berlin"}
          ],
          "expected_output": "Berlin"
        }
      ]'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          res = orq.datasets.create_datapoint(
              dataset_id="DATASET_ID",
              request_body=[
                  {
                      "inputs": {"country": "France"},
                      "messages": [
                          {"role": "user", "content": "Capital of {{country}}?"},
                          {"role": "assistant", "content": "Paris"}
                      ],
                      "expected_output": "Paris"
                  },
                  {
                      "inputs": {"country": "Germany"},
                      "messages": [
                          {"role": "user", "content": "Capital of {{country}}?"},
                          {"role": "assistant", "content": "Berlin"}
                      ],
                      "expected_output": "Berlin"
                  }
              ]
          )
          print(f"Created {len(res)} datapoints")
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({ apiKey: process.env["ORQ_API_KEY"] ?? "" });

      await orq.datasets.createDatapoint({
        datasetId: "DATASET_ID",
        requestBody: [
          {
            inputs: { country: "France" },
            messages: [
              { role: "user", content: "Capital of {{country}}?" },
              { role: "assistant", content: "Paris" }
            ],
            expectedOutput: "Paris"
          },
          {
            inputs: { country: "Germany" },
            messages: [
              { role: "user", content: "Capital of {{country}}?" },
              { role: "assistant", content: "Berlin" }
            ],
            expectedOutput: "Berlin"
          }
        ]
      });
      ```
    </CodeGroup>

    <Accordion title="Large batch example (1,000 datapoints)" icon="code">
      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          datapoints = []
          for i in range(1000):
              datapoints.append({
                  "inputs": {"number": i, "operation": "square"},
                  "messages": [
                      {"role": "user", "content": f"What is {i} squared?"},
                      {"role": "assistant", "content": f"{i} squared is {i**2}"}
                  ],
                  "expected_output": str(i**2)
              })

          res = orq.datasets.create_datapoint(
              dataset_id="DATASET_ID",
              request_body=datapoints
          )
          print(f"Created {len(res)} datapoints")
      ```
    </Accordion>

    <Tip>See the full [Create Datapoints API reference](/reference/datasets/create-a-datapoint).</Tip>
  </Tab>

  <Tab title="MCP" icon="https://mintcdn.com/orqai/i7ZhKI7LFRfXU7ox/images/logos/mcp.svg?fit=max&auto=format&n=i7ZhKI7LFRfXU7ox&q=85&s=cef7916eb5fe1f6bb97541398d3f7639" width="16" height="16" data-path="images/logos/mcp.svg">
    **Add datapoints to an existing dataset:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Import this JSON array as datapoints into the "Support Training Data" dataset
    ```

    The assistant uses `create_datapoints` to add entries in batches (max 100 per call).

    ***

    **Update a datapoint:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Update the expected output of datapoint ID "abc123" in the "user-queries" dataset to "New expected answer"
    ```

    The assistant uses `update_datapoint` with the datapoint ID and updated fields.

    ***

    **Clean up a dataset:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Delete all datapoints in the "staging-tests" dataset that have an empty expected_output field
    ```

    The assistant uses `list_datapoints` to retrieve all entries, filters for empty `expected_output`, then uses `delete_datapoints` to remove them in batches.
  </Tab>
</Tabs>

### Create Image Datasets

<Tabs>
  <Tab title="AI Studio" icon="https://mintcdn.com/orqai/My16MDKJXrKALEHC/images/logos/ai-studio-round.svg?fit=max&auto=format&n=My16MDKJXrKALEHC&q=85&s=ac04dd509320d58ab9701cb6d6137733" width="100" height="100" data-path="images/logos/ai-studio-round.svg">
    Start by [creating a dataset](#create-a-dataset), then add messages with images.

    When editing a message cell:

    1. Click **Add image** in the message editor.

    <Frame caption="Click the Add image button to include images in your messages.">
      <img src="https://mintcdn.com/orqai/UEF-O8ISq_K3Qbdc/images/studio-add-image-button.png?fit=max&auto=format&n=UEF-O8ISq_K3Qbdc&q=85&s=86af146bb4d0a2e988bcc62ecb653229" alt="User message input box with an Add image button in the bottom-right corner." width="614" height="122" data-path="images/studio-add-image-button.png" />
    </Frame>

    2. Choose how to provide the image:
       * **Upload locally**: Select a file from your computer.
       * **Enter URL**: Paste an image URL directly.

    <Frame caption="Enter an image URL or upload a local image file.">
      <img src="https://mintcdn.com/orqai/UEF-O8ISq_K3Qbdc/images/studio-image-url-input.png?fit=max&auto=format&n=UEF-O8ISq_K3Qbdc&q=85&s=5e13b4d60dd39e68e03774cbe6d84b6d" alt="URL input field for entering an image URL, with a Select image button to browse locally." width="609" height="120" data-path="images/studio-image-url-input.png" />
    </Frame>

    <Frame caption="Complete workflow: Adding images to dataset messages.">
      <img src="https://mintcdn.com/orqai/To3XzWzRTtsV_zsh/images/add-image-dataset.gif?s=2e4dbd94e1c7196094e7fcbb96662366" alt="Animated walkthrough of adding an image to a dataset message by URL or local file upload." width="598" height="414" data-path="images/add-image-dataset.gif" />
    </Frame>

    **Supported formats:** JPEG, PNG, GIF, WebP.
  </Tab>

  <Tab title="API & SDK" icon="code">
    Images must be encoded as base64 data URLs before adding to the dataset.

    <Steps>
      <Step title="Create a Dataset">
        <CodeGroup>
          ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
          curl -X POST https://api.orq.ai/v2/datasets \
            -H "Authorization: Bearer $ORQ_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "display_name": "Image Analysis Dataset",
              "path": "Default"
            }'
          ```

          ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
          response = orq.datasets.create(
              request={"display_name": "Image Analysis Dataset", "path": "Default"}
          )
          dataset_id = response.id
          ```

          ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
          const dataset = await orq.datasets.create({
            displayName: "Image Analysis Dataset",
            path: "Default",
          });
          const datasetId = dataset.id;
          ```
        </CodeGroup>
      </Step>

      <Step title="Convert Images to Base64">
        <CodeGroup>
          ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
          import base64

          def image_to_base64(image_path):
              with open(image_path, "rb") as f:
                  encoded = base64.b64encode(f.read()).decode("utf-8")
              ext = image_path.lower().split(".")[-1]
              mime_types = {"png": "image/png", "gif": "image/gif", "webp": "image/webp",
                            "jpg": "image/jpeg", "jpeg": "image/jpeg"}
              mime_type = mime_types.get(ext, "image/jpeg")
              return f"data:{mime_type};base64,{encoded}"
          ```

          ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
          import fs from "fs";
          import path from "path";

          function imageToBase64(imagePath: string): string {
            const encoded = fs.readFileSync(imagePath).toString("base64");
            const ext = path.extname(imagePath).toLowerCase();
            const mimeTypes: Record<string, string> = {
              ".png": "image/png", ".gif": "image/gif", ".webp": "image/webp",
              ".jpg": "image/jpeg", ".jpeg": "image/jpeg",
            };
            return `data:${mimeTypes[ext] || "image/jpeg"};base64,${encoded}`;
          }
          ```
        </CodeGroup>
      </Step>

      <Step title="Add Images to the Dataset">
        <CodeGroup>
          ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
          DATASET_ID="DATASET_ID"
          IMAGE_DATA=$(base64 < "/path/to/image.jpg" | tr -d '\n')

          curl -X POST "https://api.orq.ai/v2/datasets/$DATASET_ID/datapoints" \
            -H "Authorization: Bearer $ORQ_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{
              "messages": [{
                "role": "user",
                "content": [
                  {"type": "text", "text": "Describe what you see in this image"},
                  {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,'$IMAGE_DATA'", "detail": "auto"}}
                ]
              }]
            }'
          ```

          ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
          orq.datasets.create_datapoint(
              dataset_id=dataset_id,
              request_body=[{
                  "messages": [{
                      "role": "user",
                      "content": [
                          {"type": "text", "text": "Describe what you see in this image"},
                          {"type": "image_url", "image_url": {"url": image_to_base64("/path/to/image.jpg"), "detail": "auto"}}
                      ]
                  }]
              }]
          )
          ```

          ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
          await orq.datasets.createDatapoint({
            datasetId,
            requestBody: [{
              messages: [{
                role: "user",
                content: [
                  { type: "text", text: "Describe what you see in this image" },
                  { type: "image_url", imageUrl: { url: imageToBase64("/path/to/image.jpg"), detail: "auto" } }
                ]
              }]
            }]
          });
          ```
        </CodeGroup>
      </Step>
    </Steps>

    **Detail parameter:**

    | Value                | Behaviour                                   |
    | -------------------- | ------------------------------------------- |
    | `auto` (recommended) | Automatically optimises based on image size |
    | `low`                | Faster processing, lower token usage        |
    | `high`               | More detailed analysis, higher token usage  |

    **Supported formats:**

    | Format | MIME Type    | Extension       |
    | ------ | ------------ | --------------- |
    | JPEG   | `image/jpeg` | `.jpg`, `.jpeg` |
    | PNG    | `image/png`  | `.png`          |
    | GIF    | `image/gif`  | `.gif`          |
    | WebP   | `image/webp` | `.webp`         |

    **Common errors:**

    | Error              | Cause                   | Solution                                     |
    | ------------------ | ----------------------- | -------------------------------------------- |
    | Invalid API key    | Authentication failed   | Check your API key in the workspace settings |
    | File not found     | Image path is incorrect | Verify the path and file permissions         |
    | Unsupported format | Format not supported    | Convert to JPEG, PNG, GIF, or WebP           |
    | Payload too large  | Image file is too large | Compress or resize before upload             |
  </Tab>
</Tabs>

### Create Curated Datasets

Curated datasets are human-evaluated input and output sets: a prompt paired with a verified expected output. They are used for fine-tuning and as a gold-standard reference in Experiments.

Within any module, open the **Logs** tab and select a log entry. The **Feedback** panel appears on the right.

To add a correction, click **Add correction** below the assistant response:

<Frame caption="The Add correction button is below the assistant response.">
  <img src="https://mintcdn.com/orqai/x_6IXnot9ETOc_0g/images/docs/12dc1bf-8bdb4f9-iScreen_Shoter_-_Google_Chrome_-_240712114908.jpg?fit=max&auto=format&n=x_6IXnot9ETOc_0g&q=85&s=74509ec20d6f11fbb921cd8eb054ee0a" alt="Assistant response box with an Add correction button highlighted in red below it." width="1824" height="606" data-path="images/docs/12dc1bf-8bdb4f9-iScreen_Shoter_-_Google_Chrome_-_240712114908.jpg" />
</Frame>

Edit the response in the **Correction** message that opens, then click **Save**.

<Frame caption="The original and corrected responses appear side by side. The correction is shown in green.">
  <img src="https://mintcdn.com/orqai/x_6IXnot9ETOc_0g/images/docs/696d0fe-iScreen_Shoter_-_Google_Chrome_-_240715135648.jpg?fit=max&auto=format&n=x_6IXnot9ETOc_0g&q=85&s=4bc0d14bf27af264fbb26d7d091c5fa8" alt="Original assistant response shown in purple above a Correction box in green, with the corrected text entered and a Save button." width="2216" height="883" data-path="images/docs/696d0fe-iScreen_Shoter_-_Google_Chrome_-_240715135648.jpg" />
</Frame>

Click the **Add to Dataset** icon at the top-right of the response to save the corrected entry to a dataset:

<Frame caption="Choose to replace the inputs used during generation (recommended).">
  <img src="https://mintcdn.com/orqai/E8L3R46ivX7g9-QI/images/docs/afd843f-iScreen_Shoter_-_Preview_-_240715153806.jpg?fit=max&auto=format&n=E8L3R46ivX7g9-QI&q=85&s=0fbc1eab3ebe2cd8469828e5902deb2d" alt="Log view showing an Add to dataset dropdown with curated dataset selected, a Replace Inputs toggle, and an Add to dataset button." width="5112" height="2333" data-path="images/docs/afd843f-iScreen_Shoter_-_Preview_-_240715153806.jpg" />
</Frame>

<Info>
  Import a curated dataset into an [Experiment](/docs/experiments/build), attach an [Evaluator](/docs/evaluators/overview), and see which model or prompt scores best against the curated reference outputs.
</Info>

## List and Retrieve Datasets

<Tabs>
  <Tab title="API & SDK" icon="code">
    **List datasets:**

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request GET \
           --url https://api.orq.ai/v2/datasets \
           --header 'accept: application/json' \
           --header 'authorization: Bearer ORQ_API_KEY'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      from orq_ai_sdk import Orq
      import os

      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          res = orq.datasets.list(limit=10)
          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      import { Orq } from "@orq-ai/node";

      const orq = new Orq({ apiKey: process.env["ORQ_API_KEY"] ?? "" });
      const result = await orq.datasets.list({});
      console.log(result);
      ```
    </CodeGroup>

    **Retrieve a dataset by ID:**

    <CodeGroup>
      ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
      curl --request GET \
           --url https://api.orq.ai/v2/datasets/DATASET_ID \
           --header 'accept: application/json' \
           --header 'authorization: Bearer ORQ_API_KEY'
      ```

      ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
      with Orq(api_key=os.getenv("ORQ_API_KEY", "")) as orq:
          res = orq.datasets.retrieve(dataset_id="DATASET_ID")
          print(res)
      ```

      ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
      const result = await orq.datasets.retrieve({ datasetId: "DATASET_ID" });
      console.log(result);
      ```
    </CodeGroup>

    <Tip>See the [List Datasets](/reference/datasets/list-datasets) and [Retrieve a Dataset](/reference/datasets/retrieve-a-dataset) API references.</Tip>
  </Tab>

  <Tab title="MCP" icon="https://mintcdn.com/orqai/i7ZhKI7LFRfXU7ox/images/logos/mcp.svg?fit=max&auto=format&n=i7ZhKI7LFRfXU7ox&q=85&s=cef7916eb5fe1f6bb97541398d3f7639" width="16" height="16" data-path="images/logos/mcp.svg">
    **List datasets in a project:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    List all datasets in my workspace
    ```

    The assistant uses `search_entities` with `type: "dataset"`.

    ***

    **Find a specific dataset:**

    ```prompt wrap theme={"theme":{"light":"github-light","dark":"github-dark"}}
    Find the "user-queries" dataset and show me its datapoints
    ```

    The assistant uses `search_entities` to locate the dataset, then `list_datapoints` to retrieve its entries.
  </Tab>
</Tabs>
