Skip to content

Import and Export Tests

Manage test definitions in bulk through the API — calibrate thresholds across an entire test suite, promote test definitions between environments, or seed a new test suite from a prepared file.

The export endpoint produces a JSON file containing test definitions from a test suite. You can edit the file and import it back — into the same test suite or a different one — with fine-grained control over what gets created, what gets updated, and what stays untouched.

Use cases

  • Bulk calibration — export a test suite, adjust thresholds or parameters in the file, and re-import to the same test suite. Only the fields you include in the file are updated.
  • Promotion — export from a source environment and import to a target environment. Use create_and_lock to protect promoted auto-generated test definitions from being overwritten by future test generation runs.
  • Bulk insert or update — prepare test definitions in a file and import them to create or update test definitions in a test suite.

Export test definitions

GET /api/v1/test-suites/{test_suite_id}/test-definition-export

Optional query parameters narrow the export:

Parameter Values Default Description
origin manual, auto, both both Filter by how the definition was created
table_name string (none) Filter by table name
test_type string (none) Filter by test type code

The response is a JSON document with metadata about the source test suite and an array of test definitions:

{
  "version": 1,
  "source": {
    "project_code": "my_project",
    "test_suite": "my_suite",
    "exported_at": "2026-04-14T10:00:00Z",
    ...
  },
  "definitions": [
    {
      "test_type": "Alpha_Trunc",
      "table_name": "orders",
      "column_name": "customer_email",
      "threshold_value": "0.05",
      "severity": "Warning",
      ...
    },
    ...
  ]
}

The source block is informational — it records where the file came from but is not applied during import. Each test definition includes the test type, target table and column, and test parameters.

Tip

The export is compact: fields that match their default values are omitted. When you import the file, omitted fields are left unchanged on existing definitions.

Import test definitions

POST /api/v1/test-suites/{test_suite_id}/test-definition-import

The request body combines an import configuration with the exported file:

{
  "config": {
    "mode": "preview",
    "on_match": "overwrite_unlocked",
    "on_new": "create",
    "on_absence": "do_nothing"
  },
  "payload": {
    "version": 1,
    "source": { ... },
    "definitions": [ ... ]
  }
}

Mode

Controls whether changes are applied or previewed.

Value Behavior
preview Dry run — returns what would happen without making changes
apply Applies all valid actions and returns the results. Invalid items are skipped and reported in the response
apply_strict Applies only if every definition is valid. Returns an error if any would be skipped — no changes are made

Both preview and apply_strict are safe ways to verify an import before committing changes. Use preview to inspect the planned actions interactively, or apply_strict in automated pipelines where you want all-or-nothing semantics.

On match

What to do when a test definition in the file matches an existing one in the target test suite.

Value Behavior
overwrite_all Replace the target definition, even if it is locked
overwrite_unlocked Replace the target definition only if it is not locked. Locked definitions are skipped
skip Keep the target definition unchanged

On new

What to do when a test definition in the file has no match in the target test suite.

Value Behavior
create Create a new definition, preserving the lock state from the file
create_and_lock Create a new definition and lock auto-generated definitions to protect them from future test generation runs
skip Do not create the definition

On absence

What to do with test definitions in the target test suite that have no match in the file.

Value Behavior
do_nothing Leave unmatched target definitions untouched
delete_all Delete unmatched target definitions, even if locked
delete_unlocked Delete unmatched target definitions only if not locked

How matching works

Matching is automatic and determined by how each test definition was created:

Origin Matched by Rationale
Auto-generated Test type + table name + column name Each combination is unique within a test suite for auto-generated test definitions
Manual external_id Manual test definitions can share the same test type and column, so they use a unique identifier instead

The external_id identifies manual test definitions for matching. It is assigned automatically when you first export a manual test definition. When preparing a file from scratch, you must set external_id yourself (any UUID) to give each test definition a durable identity.

Manual test definitions without an external_id are always skipped, regardless of on_new. Without an identity, they cannot be matched against existing targets or safely created — any later re-import would produce duplicates.

You do not configure the matching strategy — it is determined automatically based on the origin of each test definition in the file.

Common configurations

Use case on_match on_new on_absence
Upsert overwrite_unlocked create do_nothing
Promotion overwrite_unlocked create_and_lock do_nothing
Bulk calibration overwrite_unlocked skip do_nothing
Insert only skip create do_nothing
Clone or sync a test suite overwrite_all create delete_all

Understanding the response

A successful import returns a summary and an itemized breakdown of what was (or would be) done:

{
  "summary": {
    "created": 5,
    "updated": 12,
    "skipped": 3,
    "deleted": 0
  },
  "items": [
    {
      "action": "update",
      "reason": "matched",
      "tds": [
        { "idx": 0, "target_id": "uuid-1" },
        { "idx": 3, "target_id": "uuid-2" }
      ]
    },
    {
      "action": "skip",
      "reason": "locked",
      "tds": [
        { "idx": 7, "target_id": "uuid-3" }
      ]
    }
  ]
}

The summary gives a quick count of each action. The items array groups test definitions by action and reason, so you can see exactly what happened and why.

Each entry in tds includes:

  • idx — the position of the test definition in the file's definitions array. Use this to trace back to the original entry. For deletions (target-only test definitions), idx is null.
  • target_id — the ID of the target test definition. For new test definitions in preview mode, target_id is null because the test definition has not been created yet.

Action and reason reference

Action Reason Description
create no_match Test definition in the file has no match in the target test suite
update matched Test definition matched an existing target
skip policy Match found, but on_match is set to skip
skip locked Match found, but the target is locked and on_match is overwrite_unlocked
skip no_match No match found, but on_new is set to skip
skip invalid_test_type The test definition references a test type that does not exist
skip invalid_table The test definition references a table that has not been profiled
skip missing_external_id Manual test definition has no external_id (required for matching)
delete absent Target test definition has no match in the file

Strict mode errors

When mode is apply_strict and any test definitions would be skipped, the import fails with a 400 response. The error body includes the full import response so you can inspect which test definitions caused the failure:

{
  "errors": [
    {
      "code": "strict_validation_failed",
      "message": "3 test definition(s) would be skipped"
    }
  ],
  "import_result": {
    "summary": { ... },
    "items": [ ... ]
  }
}

No changes are applied when strict mode fails.

Field handling

Only fields explicitly present in the JSON file are written during an import. If you remove a field from a test definition in the file, the target test definition keeps its existing value for that field. This allows you to control exactly what changes by editing the file before importing.

The test definition's origin type (auto-generated or manual) is preserved across export and import cycles. The schema name is not included in the file — it comes from the target test suite's table group.