---
title: Ground Truth
description: The Ground Truth API lets you create, list, and retrieve ground truth.
---

# Ground Truth

The Ground Truth API lets you create, list, and retrieve ground truth.

> **Auto-generated** from the public OpenAPI spec — this page never
> drifts from the running API. Base URL `https://api.arcnm.io`. Authenticate with
> the `X-API-Key` header (see [Authentication](../authentication.md)).

## List Golden Datasets

`GET /api/v1/parts/ground-truth/datasets`

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `name` | query | string | no |  |
| `status` | query | string | no |  |
| `limit` | query | integer | no | Maximum number of results to return. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/parts/ground-truth/datasets \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/ground-truth/datasets",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/datasets", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `count` | integer |  |
| `data` | GoldenDatasetPublic[] |  |

**Example response**

```json
{
  "count": 0,
  "data": [
    {
      "card": {},
      "created_at": "2026-06-01T12:00:00Z",
      "created_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "description": "string",
      "frozen_at": "2026-06-01T12:00:00Z",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "item_count": 0,
      "modality_counts": {},
      "name": "string",
      "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "split_strategy": "string",
      "status": "string",
      "version": 0
    }
  ]
}
```

## Create Golden Dataset

`POST /api/v1/parts/ground-truth/datasets`

**Request body** (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `description` | string | no |  |
| `name` | string | yes |  |
| `split_strategy` | string | no |  |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X POST https://api.arcnm.io/api/v1/parts/ground-truth/datasets \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "string"
  }'
```

```python title="Python"
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/ground-truth/datasets",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "string"
    },
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/datasets", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "string"
  }),
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `201` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `409` | `conflict` | A conflicting change, or an `Idempotency-Key` reused with a different body. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `201`

| Field | Type | Description |
| --- | --- | --- |
| `card` | object |  |
| `created_at` | string |  |
| `created_by_user_id` | string |  |
| `description` | string |  |
| `frozen_at` | string |  |
| `id` | string |  |
| `item_count` | integer |  |
| `modality_counts` | object |  |
| `name` | string |  |
| `org_id` | string |  |
| `split_strategy` | string |  |
| `status` | string |  |
| `version` | integer |  |

**Example response**

```json
{
  "card": {},
  "created_at": "2026-06-01T12:00:00Z",
  "created_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "description": "string",
  "frozen_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "item_count": 0,
  "modality_counts": {},
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "split_strategy": "string",
  "status": "string",
  "version": 0
}
```

## Get Golden Dataset

`GET /api/v1/parts/ground-truth/datasets/{dataset_id}`

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `dataset_id` | path | string | yes | Identifier of the dataset. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id} \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `404` | `not_found` | A referenced resource doesn't exist or isn't visible to your organisation. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `card` | object |  |
| `created_at` | string |  |
| `created_by_user_id` | string |  |
| `description` | string |  |
| `frozen_at` | string |  |
| `id` | string |  |
| `item_count` | integer |  |
| `modality_counts` | object |  |
| `name` | string |  |
| `org_id` | string |  |
| `split_strategy` | string |  |
| `status` | string |  |
| `version` | integer |  |

**Example response**

```json
{
  "card": {},
  "created_at": "2026-06-01T12:00:00Z",
  "created_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "description": "string",
  "frozen_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "item_count": 0,
  "modality_counts": {},
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "split_strategy": "string",
  "status": "string",
  "version": 0
}
```

## Export Golden Dataset

`GET /api/v1/parts/ground-truth/datasets/{dataset_id}/export`

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `dataset_id` | path | string | yes | Identifier of the dataset. |
| `format` | query | string | no | json | jsonl (records) | croissant (JSON-LD manifest) | coco (2D drawing-bbox slice). |
| `split` | query | string | no | Optional train/val/test/holdout filter on the records. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/export \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/export",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/export", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `404` | `not_found` | A referenced resource doesn't exist or isn't visible to your organisation. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `counts` | object |  |
| `dataset` | object |  |
| `modalities` | object |  |
| `parquet_available` | boolean |  |
| `schema_version` | string |  |
| `total` | integer |  |

**Example response**

```json
{
  "counts": {},
  "dataset": {},
  "modalities": {},
  "parquet_available": true,
  "schema_version": "string",
  "total": 0
}
```

## Freeze Golden Dataset

`POST /api/v1/parts/ground-truth/datasets/{dataset_id}/freeze`

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `dataset_id` | path | string | yes | Identifier of the dataset. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X POST https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/freeze \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/freeze",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/freeze", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `404` | `not_found` | A referenced resource doesn't exist or isn't visible to your organisation. |
| `409` | `conflict` | A conflicting change, or an `Idempotency-Key` reused with a different body. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `card` | object |  |
| `created_at` | string |  |
| `created_by_user_id` | string |  |
| `description` | string |  |
| `frozen_at` | string |  |
| `id` | string |  |
| `item_count` | integer |  |
| `modality_counts` | object |  |
| `name` | string |  |
| `org_id` | string |  |
| `split_strategy` | string |  |
| `status` | string |  |
| `version` | integer |  |

**Example response**

```json
{
  "card": {},
  "created_at": "2026-06-01T12:00:00Z",
  "created_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "description": "string",
  "frozen_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "item_count": 0,
  "modality_counts": {},
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "split_strategy": "string",
  "status": "string",
  "version": 0
}
```

## Add Golden Dataset Items

`POST /api/v1/parts/ground-truth/datasets/{dataset_id}/items`

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `dataset_id` | path | string | yes | Identifier of the dataset. |

**Request body** (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `label_ids` | string[] | yes |  |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X POST https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/items \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label_ids": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  }'
```

```python title="Python"
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/items",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "label_ids": [
            "3fa85f64-5717-4562-b3fc-2c963f66afa6"
        ]
    },
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/datasets/{dataset_id}/items", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "label_ids": [
      "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    ]
  }),
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `404` | `not_found` | A referenced resource doesn't exist or isn't visible to your organisation. |
| `409` | `conflict` | A conflicting change, or an `Idempotency-Key` reused with a different body. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `card` | object |  |
| `created_at` | string |  |
| `created_by_user_id` | string |  |
| `description` | string |  |
| `frozen_at` | string |  |
| `id` | string |  |
| `item_count` | integer |  |
| `modality_counts` | object |  |
| `name` | string |  |
| `org_id` | string |  |
| `split_strategy` | string |  |
| `status` | string |  |
| `version` | integer |  |

**Example response**

```json
{
  "card": {},
  "created_at": "2026-06-01T12:00:00Z",
  "created_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "description": "string",
  "frozen_at": "2026-06-01T12:00:00Z",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "item_count": 0,
  "modality_counts": {},
  "name": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "split_strategy": "string",
  "status": "string",
  "version": 0
}
```

## List Labels

`GET /api/v1/parts/ground-truth/labels`

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `part_revision_id` | query | string | no | Identifier of the part revision. |
| `calculation_id` | query | string | no | Identifier of the calculation. |
| `target_kind` | query | string | no |  |
| `origin` | query | string | no |  |
| `since` | query | string | no | ISO-8601; return labels created at or after this instant. |
| `limit` | query | integer | no | Maximum number of results to return. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/parts/ground-truth/labels \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/ground-truth/labels",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/labels", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `count` | integer |  |
| `data` | GroundTruthLabelPublic[] |  |

**Example response**

```json
{
  "count": 0,
  "data": [
    {
      "apply_to_part": true,
      "calculation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "corrected_value": null,
      "created_at": "2026-06-01T12:00:00Z",
      "detail_kind": "string",
      "dfm_issue_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "drawing_bbox": [
        0
      ],
      "extractor_versions": {},
      "face_uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "feature_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "field_name": "string",
      "field_path": "string",
      "guideline_version": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "labeled_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "notes": "string",
      "ontology_version": "string",
      "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "origin": "analyst",
      "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "pmi_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "predicted_confidence": 0,
      "predicted_value": null,
      "rule_findings": [
        "string"
      ],
      "source_extraction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "supersedes_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "target_kind": "string",
      "verdict": "string",
      "weight": 1
    }
  ]
}
```

## Create Label

`POST /api/v1/parts/ground-truth/labels`

**Request body** (`application/json`)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `apply_to_part` | boolean | no |  |
| `calculation_id` | string | no |  |
| `corrected_value` | object | no |  |
| `detail_kind` | string | no |  |
| `dfm_issue_id` | string | no |  |
| `drawing_bbox` | number[] | no |  |
| `extractor_versions` | object | no |  |
| `face_uuid` | string | no |  |
| `feature_id` | string | no |  |
| `field_name` | string | no |  |
| `field_path` | string | no |  |
| `guideline_version` | string | no |  |
| `notes` | string | no |  |
| `ontology_version` | string | no |  |
| `origin` | string | no |  |
| `part_revision_id` | string | yes |  |
| `pmi_id` | string | no |  |
| `predicted_confidence` | number | no |  |
| `predicted_value` | object | no |  |
| `rule_findings` | string[] | no |  |
| `source_extraction_id` | string | no |  |
| `supersedes_id` | string | no |  |
| `target_kind` | string | yes |  |
| `verdict` | string | yes |  |
| `weight` | number | no |  |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X POST https://api.arcnm.io/api/v1/parts/ground-truth/labels \
  -H "X-API-Key: $ARCNM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "target_kind": "string",
    "verdict": "string"
  }'
```

```python title="Python"
import requests

resp = requests.post(
    "https://api.arcnm.io/api/v1/parts/ground-truth/labels",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "target_kind": "string",
        "verdict": "string"
    },
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/labels", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "target_kind": "string",
    "verdict": "string"
  }),
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `201` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `409` | `conflict` | A conflicting change, or an `Idempotency-Key` reused with a different body. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `201`

| Field | Type | Description |
| --- | --- | --- |
| `apply_to_part` | boolean |  |
| `calculation_id` | string |  |
| `corrected_value` | object |  |
| `created_at` | string |  |
| `detail_kind` | string |  |
| `dfm_issue_id` | string |  |
| `drawing_bbox` | number[] |  |
| `extractor_versions` | object |  |
| `face_uuid` | string |  |
| `feature_id` | string |  |
| `field_name` | string |  |
| `field_path` | string |  |
| `guideline_version` | string |  |
| `id` | string |  |
| `labeled_by_user_id` | string |  |
| `notes` | string |  |
| `ontology_version` | string |  |
| `org_id` | string |  |
| `origin` | string |  |
| `part_revision_id` | string |  |
| `pmi_id` | string |  |
| `predicted_confidence` | number |  |
| `predicted_value` | object |  |
| `rule_findings` | string[] |  |
| `source_extraction_id` | string |  |
| `supersedes_id` | string |  |
| `target_kind` | string |  |
| `verdict` | string |  |
| `weight` | number |  |

**Example response**

```json
{
  "apply_to_part": true,
  "calculation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "corrected_value": null,
  "created_at": "2026-06-01T12:00:00Z",
  "detail_kind": "string",
  "dfm_issue_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "drawing_bbox": [
    0
  ],
  "extractor_versions": {},
  "face_uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "feature_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "field_name": "string",
  "field_path": "string",
  "guideline_version": "string",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "labeled_by_user_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "notes": "string",
  "ontology_version": "string",
  "org_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "origin": "analyst",
  "part_revision_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "pmi_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "predicted_confidence": 0,
  "predicted_value": null,
  "rule_findings": [
    "string"
  ],
  "source_extraction_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "supersedes_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "target_kind": "string",
  "verdict": "string",
  "weight": 1
}
```

## Get Label History

`GET /api/v1/parts/ground-truth/labels/{label_id}/history`

Return the append-only supersession lineage for a label (PROV-O-ish).

Walks the ``supersedes_id`` chain back from ``label_id`` toward the root,
returning each revision oldest→newest as a who/when/derived_from entry. A
label that has never been superseded yields a single-entry history (its own
creation). The walk is bounded and stops at the first missing link (a row
that was hard-deleted under ``ON DELETE SET NULL``) so it never raises.

**Parameters**

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `label_id` | path | string | yes | Identifier of the label. |

**Request**

<CodeTabs>

```bash title="cURL"
curl -X GET https://api.arcnm.io/api/v1/parts/ground-truth/labels/{label_id}/history \
  -H "X-API-Key: $ARCNM_API_KEY"
```

```python title="Python"
import requests

resp = requests.get(
    "https://api.arcnm.io/api/v1/parts/ground-truth/labels/{label_id}/history",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
resp.raise_for_status()
print(resp.json())
```

```typescript title="TypeScript"
const resp = await fetch("https://api.arcnm.io/api/v1/parts/ground-truth/labels/{label_id}/history", {
  method: "GET",
  headers: {
    "X-API-Key": process.env.ARCNM_API_KEY!,
  },
})
const data = await resp.json()
```

</CodeTabs>

**Responses**

| Status | Description |
| --- | --- |
| `200` | Successful Response |
| `422` | Validation Error |

**Errors**

Standard error responses — see the [Errors catalog](../errors.md) for the full envelope, `request_id`, and retry-safety table.

| Status | Code | When |
| --- | --- | --- |
| `401` | `invalid_api_key` | Missing, malformed, or revoked API key. |
| `403` | `insufficient_scope` | The key is valid but lacks a scope this endpoint requires. |
| `404` | `not_found` | A referenced resource doesn't exist or isn't visible to your organisation. |
| `429` | `rate_limited` | Per-key or per-org rate limit exceeded — back off with jitter and retry. |


**Response body** `200`

| Field | Type | Description |
| --- | --- | --- |
| `depth` | integer |  |
| `label_id` | string |  |
| `lineage` | LabelHistoryEntry[] |  |

**Example response**

```json
{
  "depth": 0,
  "label_id": "string",
  "lineage": [
    {
      "derived_from": "string",
      "endedAtTime": "string",
      "extractor_versions": {},
      "guideline_version": "string",
      "label_id": "string",
      "ontology_version": "string",
      "origin": "string",
      "verdict": "string",
      "wasAssociatedWith": "string"
    }
  ]
}
```
