> ## 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.

# Add a Validation Test to a Dataset Pair

> Requires the GV.APIContributor application role, or a higher role (Owner > Contributor > Reader).

API · Dataset Pairs

POST `/api/v1/dataset-pairs/{datasetPairUuid}/validation-tests`

Requires the GV.APIContributor application role, or a higher role (Owner > Contributor > Reader).

Operation ID · create\_validation\_test

## Request example

```bash theme={null}
curl --request POST \
  --url 'https://api.generalvalidation.com/api/v1/dataset-pairs/88888888-8888-4888-8888-888888888888/validation-tests' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <access-token>' \
  --header 'Idempotency-Key: <unique-idempotency-key>' \
  --header 'Content-Type: application/json' \
  --data '{
  "comment": "Allow one cent of aggregate rounding variance.",
  "functionCode": "SUM",
  "operator": "=",
  "sourceField": "amount",
  "targetField": "amount",
  "threshold": "0.01"
}'
```

## Authentication and access

* **Required role:** GV.APIContributor
* **Data classification:** metadata
* **Side effects:** configurationWrite

Use an authentication scheme declared below. Ordinary workloads use application tokens; signed-in users use delegated tokens and Organization membership. Activation and invitation acceptance require a person, and execution callbacks require their registered identity.

* Microsoft Entra delegated user token
* Microsoft Entra application token

## Parameters

### datasetPairUuid

path Required

Opaque Dataset Pair UUID.

`string (uuid)`

Opaque Dataset Pair UUID.

### Idempotency-Key

header Required

Required caller-chosen retry identity. Use 1-128 visible ASCII characters and reuse it only for an exact retry of this request.

`string`

minimum length: 1 · maximum length: 128

## Request body

Required

### application/json

`V1RowCountTest | V1AggregateFieldTest | V1SetTest | V1ValueTest`

Any of

**Option 1: V1RowCountTest**

**Schema V1RowCountTest**

`object`

Properties

`comment`

`string`

* **Default:** `""`

maximum length: 2000

`definitionVersion`

`integer`

* **Constant:** `1`
* **Default:** `1`

`functionCode`— Required

`string`

* **Constant:** `"COUNT_ROWS"`

`operator`

**Schema V1ComparisonOperator**

`string`

* **Allowed values:** `"="`,`"<>"`,`"<"`,`"<="`,`">"`,`">="`
* **Default:** `"="`

`threshold`

`string`

Exact non-negative decimal encoded as a JSON string, with at most 26 integer digits and 12 fractional digits.

* **Default:** `"0"`

pattern: ^(?:0|\[1-9]\[0-9]\{0,25})(?:.\[0-9]\{1,12})?\$

Schema example

```
"0"
```

```
"0.01"
```

```
"100.000000000001"
```

Additional properties are not allowed.

**Option 2: V1AggregateFieldTest**

**Schema V1AggregateFieldTest**

`object`

Properties

`comment`

`string`

* **Default:** `""`

maximum length: 2000

`definitionVersion`

`integer`

* **Constant:** `1`
* **Default:** `1`

`functionCode`— Required

`string`

* **Allowed values:** `"COUNT"`,`"COUNT_DISTINCT"`,`"MIN"`,`"MAX"`,`"AVG"`,`"SUM"`

`operator`

**Schema V1ComparisonOperator**

`string`

* **Allowed values:** `"="`,`"<>"`,`"<"`,`"<="`,`">"`,`">="`
* **Default:** `"="`

`sourceField`— Required

`string`

minimum length: 1 · maximum length: 1024

`sourceObservationScope`

`V1RootObservationScope | V1CollectionObservationScope`

One of

Selected by `kind`.

**Option 1: V1RootObservationScope**

**Schema V1RootObservationScope**

`object`

Properties

`kind`

`string`

* **Constant:** `"root"`
* **Default:** `"root"`

Additional properties are not allowed.

**Option 2: V1CollectionObservationScope**

**Schema V1CollectionObservationScope**

`object`

Properties

`collectionPath`— Required

`string`

minimum length: 1 · maximum length: 1024

`kind`— Required

`string`

* **Constant:** `"collection"`

Additional properties are not allowed.

`targetField`— Required

`string`

minimum length: 1 · maximum length: 1024

`targetObservationScope`

`V1RootObservationScope | V1CollectionObservationScope`

One of

Selected by `kind`.

**Option 1: V1RootObservationScope**

**Schema V1RootObservationScope**

`object`

Properties

`kind`

`string`

* **Constant:** `"root"`
* **Default:** `"root"`

Additional properties are not allowed.

**Option 2: V1CollectionObservationScope**

**Schema V1CollectionObservationScope**

`object`

Properties

`collectionPath`— Required

`string`

minimum length: 1 · maximum length: 1024

`kind`— Required

`string`

* **Constant:** `"collection"`

Additional properties are not allowed.

`threshold`

`string`

Exact non-negative decimal encoded as a JSON string, with at most 26 integer digits and 12 fractional digits.

* **Default:** `"0"`

pattern: ^(?:0|\[1-9]\[0-9]\{0,25})(?:.\[0-9]\{1,12})?\$

Schema example

```
"0"
```

```
"0.01"
```

```
"100.000000000001"
```

Additional properties are not allowed.

**Option 3: V1SetTest**

**Schema V1SetTest**

`object`

Properties

`comment`

`string`

* **Default:** `""`

maximum length: 2000

`comparisonOptions`

**Schema V1SetComparisonOptions**

`object`

All of

**Constraint 1: unknown**

`unknown`

**Conditional constraints**

```
{
  "if": {
    "properties": {
      "nullsEqual": {
        "const": false
      }
    },
    "required": [
      "nullsEqual"
    ]
  },
  "then": {
    "properties": {
      "setNullsAsMember": {
        "const": true
      }
    },
    "required": [
      "setNullsAsMember"
    ]
  }
}
```

Properties

`caseInsensitive`

`boolean`

* **Default:** `false`

`nullsEqual`

`boolean`

* **Default:** `true`

`setNullsAsMember`

`boolean`

* **Default:** `false`

`trimTrailingSpaces`

`boolean`

* **Default:** `false`

Additional properties are not allowed.

`definitionVersion`

`integer`

* **Constant:** `1`
* **Default:** `1`

`evidenceCaptureLimit`

`integer`

* **Default:** `100`

minimum: 0 · maximum: 10000

`functionCode`— Required

`string`

* **Allowed values:** `"SET_A_IN_B"`,`"SET_B_IN_A"`,`"SET_A_EQUALS_B"`

`maxBadRecords`

`integer`

* **Default:** `0`

minimum: 0 · maximum: 2147483647

`sourceField`— Required

`string | V1FieldBinding`

Any of

**Option 1: string**

`string`

minimum length: 1 · maximum length: 1024

**Option 2: V1FieldBinding**

**Schema V1FieldBinding**

`object`

All of

**Constraint 1: unknown**

`unknown`

**Conditional constraints**

```
{
  "if": {
    "properties": {
      "format": {
        "pattern": "\\S"
      }
    },
    "required": [
      "format"
    ]
  },
  "then": {
    "properties": {
      "transform": {
        "enum": [
          "to_date",
          "to_timestamp"
        ]
      }
    },
    "required": [
      "transform"
    ]
  }
}
```

Properties

`field`— Required

`string`

minimum length: 1 · maximum length: 1024

`format`

`string`

Optional parser format accepted only for date/timestamp transforms.

* **Default:** `""`

maximum length: 64

`transform`

**Schema V1FieldTransform**

`string`

* **Allowed values:** `"none"`,`"to_string"`,`"to_long"`,`"to_decimal"`,`"to_double"`,`"to_boolean"`,`"to_date"`,`"to_timestamp"`,`"to_peer_numeric"`
* **Default:** `"none"`

Additional properties are not allowed.

`sourceObservationScope`

`V1RootObservationScope | V1CollectionObservationScope`

One of

Selected by `kind`.

**Option 1: V1RootObservationScope**

**Schema V1RootObservationScope**

`object`

Properties

`kind`

`string`

* **Constant:** `"root"`
* **Default:** `"root"`

Additional properties are not allowed.

**Option 2: V1CollectionObservationScope**

**Schema V1CollectionObservationScope**

`object`

Properties

`collectionPath`— Required

`string`

minimum length: 1 · maximum length: 1024

`kind`— Required

`string`

* **Constant:** `"collection"`

Additional properties are not allowed.

`targetField`— Required

`string | V1FieldBinding`

Any of

**Option 1: string**

`string`

minimum length: 1 · maximum length: 1024

**Option 2: V1FieldBinding**

**Schema V1FieldBinding**

`object`

All of

**Constraint 1: unknown**

`unknown`

**Conditional constraints**

```
{
  "if": {
    "properties": {
      "format": {
        "pattern": "\\S"
      }
    },
    "required": [
      "format"
    ]
  },
  "then": {
    "properties": {
      "transform": {
        "enum": [
          "to_date",
          "to_timestamp"
        ]
      }
    },
    "required": [
      "transform"
    ]
  }
}
```

Properties

`field`— Required

`string`

minimum length: 1 · maximum length: 1024

`format`

`string`

Optional parser format accepted only for date/timestamp transforms.

* **Default:** `""`

maximum length: 64

`transform`

**Schema V1FieldTransform**

`string`

* **Allowed values:** `"none"`,`"to_string"`,`"to_long"`,`"to_decimal"`,`"to_double"`,`"to_boolean"`,`"to_date"`,`"to_timestamp"`,`"to_peer_numeric"`
* **Default:** `"none"`

Additional properties are not allowed.

`targetObservationScope`

`V1RootObservationScope | V1CollectionObservationScope`

One of

Selected by `kind`.

**Option 1: V1RootObservationScope**

**Schema V1RootObservationScope**

`object`

Properties

`kind`

`string`

* **Constant:** `"root"`
* **Default:** `"root"`

Additional properties are not allowed.

**Option 2: V1CollectionObservationScope**

**Schema V1CollectionObservationScope**

`object`

Properties

`collectionPath`— Required

`string`

minimum length: 1 · maximum length: 1024

`kind`— Required

`string`

* **Constant:** `"collection"`

Additional properties are not allowed.

Additional properties are not allowed.

**Option 4: V1ValueTest**

**Schema V1ValueTest**

`object`

Properties

`comment`

`string`

* **Default:** `""`

maximum length: 2000

`comparisonOptions`

**Schema V1ValueComparisonOptions**

`object`

Properties

`caseInsensitive`

`boolean`

* **Default:** `false`

`nullsEqual`

`boolean`

* **Default:** `true`

`trimTrailingSpaces`

`boolean`

* **Default:** `false`

Additional properties are not allowed.

`definitionVersion`

`integer`

* **Constant:** `1`
* **Default:** `1`

`evidenceCaptureLimit`

`integer`

* **Default:** `100`

minimum: 0 · maximum: 10000

`functionCode`— Required

`string`

* **Allowed values:** `"VALUE"`,`"OUTER_VALUE"`

`maxBadRecords`

`integer`

* **Default:** `0`

minimum: 0 · maximum: 2147483647

`operator`

**Schema V1ComparisonOperator**

`string`

* **Allowed values:** `"="`,`"<>"`,`"<"`,`"<="`,`">"`,`">="`
* **Default:** `"="`

`sourceField`— Required

**Schema V1FieldBinding**

`object`

All of

**Constraint 1: unknown**

`unknown`

**Conditional constraints**

```
{
  "if": {
    "properties": {
      "format": {
        "pattern": "\\S"
      }
    },
    "required": [
      "format"
    ]
  },
  "then": {
    "properties": {
      "transform": {
        "enum": [
          "to_date",
          "to_timestamp"
        ]
      }
    },
    "required": [
      "transform"
    ]
  }
}
```

Properties

`field`— Required

`string`

minimum length: 1 · maximum length: 1024

`format`

`string`

Optional parser format accepted only for date/timestamp transforms.

* **Default:** `""`

maximum length: 64

`transform`

**Schema V1FieldTransform**

`string`

* **Allowed values:** `"none"`,`"to_string"`,`"to_long"`,`"to_decimal"`,`"to_double"`,`"to_boolean"`,`"to_date"`,`"to_timestamp"`,`"to_peer_numeric"`
* **Default:** `"none"`

Additional properties are not allowed.

`targetField`— Required

**Schema V1FieldBinding**

`object`

All of

**Constraint 1: unknown**

`unknown`

**Conditional constraints**

```
{
  "if": {
    "properties": {
      "format": {
        "pattern": "\\S"
      }
    },
    "required": [
      "format"
    ]
  },
  "then": {
    "properties": {
      "transform": {
        "enum": [
          "to_date",
          "to_timestamp"
        ]
      }
    },
    "required": [
      "transform"
    ]
  }
}
```

Properties

`field`— Required

`string`

minimum length: 1 · maximum length: 1024

`format`

`string`

Optional parser format accepted only for date/timestamp transforms.

* **Default:** `""`

maximum length: 64

`transform`

**Schema V1FieldTransform**

`string`

* **Allowed values:** `"none"`,`"to_string"`,`"to_long"`,`"to_decimal"`,`"to_double"`,`"to_boolean"`,`"to_date"`,`"to_timestamp"`,`"to_peer_numeric"`
* **Default:** `"none"`

Additional properties are not allowed.

`threshold`

`string`

Exact non-negative decimal encoded as a JSON string, with at most 26 integer digits and 12 fractional digits.

* **Default:** `"0"`

pattern: ^(?:0|\[1-9]\[0-9]\{0,25})(?:.\[0-9]\{1,12})?\$

Schema example

```
"0"
```

```
"0.01"
```

```
"100.000000000001"
```

Additional properties are not allowed.

Examples

Aggregate-field comparison · aggregateField

```
{
  "comment": "Allow one cent of aggregate rounding variance.",
  "functionCode": "SUM",
  "operator": "=",
  "sourceField": "amount",
  "targetField": "amount",
  "threshold": "0.01"
}
```

Row-count comparison · rowCount

```
{
  "comment": "Both sides should contain the same number of rows.",
  "functionCode": "COUNT_ROWS",
  "operator": "=",
  "threshold": "0"
}
```

Set containment comparison · set

```
{
  "comment": "Every source country code must exist in the target.",
  "functionCode": "SET_A_IN_B",
  "sourceField": "country_code",
  "targetField": "country_code"
}
```

Joined value comparison · value

```
{
  "comment": "Compare status for matching order keys.",
  "functionCode": "VALUE",
  "sourceField": {
    "field": "status"
  },
  "targetField": {
    "field": "status"
  }
}
```

## Responses

This guide summarizes response status codes and headers. Retrieve the deployed, authenticated OpenAPI document for the exact response body schemas and examples. The API also provides an authenticated Swagger UI; opening it in a browser does not automatically attach a bearer token.

Error responses use `application/problem+json`. The response's stable `code` and `type` map to the [error-code reference](/errors).

### 201

Validation Test created.

#### Headers

* **ETag:** `string`
* **Idempotency-Replayed:** `boolean`
* **Location:** `string`

### 401

A valid Microsoft Entra bearer token is required.

### 402

The organization entitlement does not permit this mutation.

### 403

The authenticated principal does not have the required role.

### 404

The resource does not exist in this tenant.

### 409

The operation conflicts with current resource or Azure state.

### 422

The request is syntactically valid but semantically invalid.

### 429

The bounded application request rate was exceeded.

#### Headers

* **Retry-After:** Seconds to wait before retrying. `integer`minimum: 1

### 503

A required dependency is temporarily unavailable.

#### Headers

* **Retry-After:** Seconds to wait before retrying. `integer`minimum: 1
