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

# Automate with your own tools

> Create Table Pairs and Tests, give your Environment read access, and start Runs from a script, an agent, or a Fabric pipeline.

After an Owner sets up the Environment, a script, an agent, or a Fabric
pipeline can do what a person does in the app. The General Validation API
holds your Table Pair and Test definitions and each Run's verdict and counts.
Two steps happen in Fabric with your tool's own access, because the API holds
no access to your tenant: giving the workspace identity read access to your
Tables, and starting a Run.

## Before you start

* An Owner has activated the Organization and set up the Environment in the
  app. Both happen once.
* Your tool calls the API with a workload identity that holds
  `GV.APIContributor`; see [API authentication](https://docs.generalvalidation.com/api/authentication.md). The
  [API reference](https://docs.generalvalidation.com/api/reference.md) lists every operation and its schema.
* Your tool makes the Fabric calls with an identity that has the Fabric access
  each step names: its own service principal, or the person it works for when
  an agent acts on someone's behalf. A service principal also needs your
  Fabric administrator to let service principals use Fabric APIs.

## Create Tables, a Table Pair, and Tests

Save a reference to each existing Table with `POST /api/v1/fabric/tables`,
using the workspace, Lakehouse or Warehouse, and Table that Fabric's own API
lists. Then create the Table Pair with `POST /api/v1/fabric/pairs` and add Tests
with `POST /api/v1/fabric/tests`. `GET /api/v1/fabric/catalog` lists the
[validation functions](https://docs.generalvalidation.com/validate-data/tests.md#the-12-validation-functions).

```bash theme={null}
curl --fail-with-body \
  --header "Authorization: Bearer ${gv_access_token}" \
  --header "Content-Type: application/json" \
  --data '{"name": "Orders", "workspace_id": "<workspace-id>", "lakehouse_id": "<lakehouse-id>", "path": "Tables/dbo/orders", "format": "delta"}' \
  "https://api.generalvalidation.com/api/v1/fabric/tables"
```

## Give the workspace identity read access

Saving a Table Pair in the app gives the workspace identity read access to the
pair's Tables. A pair created through the API does not get it, so give it once
per pair before the pair's first Run. Ask the API what the pair needs:

```bash theme={null}
curl --fail-with-body \
  --header "Authorization: Bearer ${gv_access_token}" \
  "https://api.generalvalidation.com/api/v1/fabric/pairs/<pair-id>/read-access"
```

```json theme={null}
{
  "identity_id": "<workspace-identity-object-id>",
  "workspaces": [
    {
      "workspace_id": "<source-workspace-id>",
      "workspace_role": "Viewer",
      "lakehouses": [
        {
          "lakehouse_id": "<lakehouse-id>",
          "data_access_role": "GeneralValidation1a2b3c4d",
          "paths": ["/Tables/dbo/orders"]
        }
      ]
    }
  ]
}
```

An empty `workspaces` list means the pair reads only your Environment and
needs nothing. Otherwise, in Fabric, with Admin or Member on each listed
workspace:

1. Add the identity as Viewer on the workspace with
   `POST https://api.fabric.microsoft.com/v1/workspaces/<workspace-id>/roleAssignments`
   and the body
   `{"principal": {"id": "<identity_id>", "type": "ServicePrincipal"}, "role": "Viewer"}`.
   A `409` response means the identity already has a role there; keep it.
2. For each Lakehouse, give the identity Read on the listed paths through a
   OneLake data access role. The app keeps them in the role named
   `data_access_role`, so add the paths there and both stay in one role.
   Fabric's `PUT .../items/<lakehouse-id>/dataAccessRoles` replaces every role
   in the Lakehouse, so read the roles first and send the others back
   unchanged with the `ETag` you read.

A Warehouse needs Viewer only. A Table that is a shortcut also needs read
access at the shortcut's target. Instead of these calls, someone who manages
the workspace can open the pair in the app and click **Give read access**.
Until the access is there, the pair's Runs end with **Could not read the
Tables**.

## Start a Run

1. Prepare the Run with `POST /api/v1/fabric/runs` and a new Run ID:
   `{"id": "<new-uuid>", "pair_id": "<pair-id>"}`. The response carries
   `payload_base64` and `report.token`. The token comes back only from the
   call that prepared the Run; treat it as a secret and keep it out of logs.
   Retry with the same Run ID only to repeat that request.

2. Read `workspace_id` and `pipeline_id` from `GET /api/v1/fabric/settings`.

3. Start the validation pipeline in Fabric with an identity that has
   Contributor, Member, or Admin on that workspace:

   ```bash theme={null}
   curl --fail-with-body --include \
     --header "Authorization: Bearer ${fabric_access_token}" \
     --header "Content-Type: application/json" \
     --data '{"executionData": {"parameters": {"mode": "run", "payload_base64": "<payload_base64>", "run_id": "<run-id>", "report_token": "<report.token>"}}}' \
     "https://api.fabric.microsoft.com/v1/workspaces/<workspace_id>/items/<pipeline_id>/jobs/instances?jobType=Pipeline"
   ```

4. Send the job ID, the last segment of the `Location` header in Fabric's
   answer, with `POST /api/v1/fabric/runs/<run-id>/submission` and the body
   `{"job_id": "<job-id>"}`. The app then shows the Run as submitted and
   links it to Fabric Monitor.

5. Read `GET /api/v1/fabric/runs/<run-id>` until `status` is `passed`,
   `failed`, or `error`, and read each Test's Result in the response.

Exact values and mismatch evidence stay in your Results Lakehouse. Open the Run
in the app and use **View details** to see them with your own Fabric access.

## Validate from a Fabric pipeline

A pipeline of yours can run a Table Pair and stop its later steps when
validation does not pass. Add two activities before the steps to protect:

1. A **Web** activity that prepares the Run. Its connection signs in as your
   workload's app registration with service principal authentication, a
   secret, and the audience `api://78d5d8af-9dd6-49dd-b06c-38c3a3c707af`
   (connection type `WebForPipeline`), with the base URL
   `https://api.generalvalidation.com`. Use method `POST`, relative URL
   `/api/v1/fabric/runs`, and the body
   `@concat('{"id":"', guid(), '","pair_id":"<pair-id>"}')`. Turn on
   **Secure output**, because the answer holds the report token.
2. An **Invoke pipeline** activity that runs the General Validation
   pipeline in your Environment's workspace and waits for it. Its connection
   uses your pipeline workspace's identity (connection type
   `FabricDataPipelines`). Set the parameters `mode` to `run`,
   `payload_base64` to `@activity('<web activity>').output.payload_base64`,
   `run_id` to `@activity('<web activity>').output.id`, and `report_token`
   to `@activity('<web activity>').output.report.token`. Turn on **Secure
   input**, and give the activity a timeout.

Your pipeline workspace's identity needs Contributor on the Environment's
workspace. Contributor there can also read the Results Lakehouse, so grant it
only to pipelines you trust with those Results. Allow a few minutes after
granting a role before the first run, while Fabric applies it.

When validation passes, the next activity runs. When it fails or errors, the
Invoke pipeline activity fails with the verdict and a link to the Run in its
message, and the activities that depend on it do not run.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.