---
title: "vxData SDK + schema model"
description: "Resource/payload model, SDK 2.1.0 surface, tree navigation gotcha, and local dev loop for apps/vxdata-api consumers."
image: "https://docs.virdx.dev/img/virdx-social-card.png"
---

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

# vxData SDK + schema model

Reference for consuming the vxData API. Both `vxdata-sdk` and `vxdata-schemas`
are at `2.1.0` (mono `packages/vxdata-sdk`, `packages/vxdata-schemas`).

## Resource / payload model

vxData's canonical unit is a **Resource**: metadata container with lineage.
Typed domain data lives in **payload** rows, linked via `resource_versions`.

Relationships are primarily a single-parent tree via `parent_identifier`.
Provenance is separate via `derived_from`. Query lineage is denormalized into
`datasource_id`, `patient_id`, `study_id`.

Payload types (defined in `packages/vxdata-schemas/src/vxdata/schemas/payloads.py`):

- Raw/source: `GenericFile`, `DICOMFile`
- Core integration: `DataSource`, `Patient`, `PatientStatus`, `ImagingStudy`,
  `DICOMSeries`, `Volume`, `Measurement`
- Assessments/maps: `PIQUALAssessment`, `PIRADSAssessment`,
  `PIRADSLesionAssessment`, `VoxelMap`, `HistoMap`
- Pathology: `PathologySpecimen`, `PathologyAssessment`, `BiopsyCoreLocation`
- Histopathology imaging: `HistoScan` (zarr-backed tissue scan), `HistoMap`
  (zarr-backed parameter/segmentation map; covers former `DomainRepresentation`),
  `DiffsimScan`, `DiffsimVolume` (diffusion-sim outputs; kept separate from
  `Volume` until sim params stabilize)
- Annotation/support: `AnnotationSession`, `AnnotationSessionFile`,
  `AnnotationChange`, `ImageLevelAnnotation`, `FileBlob`, `FileGroup`,
  `VxAnnotateCaseRecord`
- Benchmarking: `BenchmarkingResult`, `ModelBenchmark`, `TrainingBenchmark`,
  `PseudoLabel`
- Other: `ResourceComment`, `Treatment`, `Artefact`

Full list (36 types as of 2026-08-06) is in `payloads.py`.

## SDK surface (2.1.0)

Construct a client:

```python
from vxdata.sdk import Client

vxd = Client(base_url=...)  # explicit arg > API_URL env > default
```

No `.virdx.config`, no S3 credentials — blob transfer goes through
`vxd.storage` via presigned URLs.

Typed namespaces (e.g., `vxd.volumes`, `vxd.patients`):

```python
df = vxd.volumes.query().filter(F.b_value > 0).collect()  # Polars DataFrame
models = vxd.volumes.query().filter(...).collect_as_pydantic()  # list[VolumeResponse]
```

Generic CRUD:

```python
vxd.resources.retrieve(id_or_list)  # single or batch
vxd.resources.create(...)           # auto-chunks at 500/call; each chunk is
vxd.resources.update(...)           # a separate all-or-nothing transaction
vxd.resources.delete(...)
```

Schemas are flat (no nested `.payload`):

```python
from vxdata.schemas.response import VolumeResponse, PatientResponse
from vxdata.schemas.create import VolumeCreate
from vxdata.schemas.update import VolumeUpdate
```

Payload fields are directly on the model, plus a `payload_type` discriminator.

SDK modules (in `packages/vxdata-sdk/src/vxdata/sdk/`): `client.py`,
`config.py`, `exceptions.py`, `filters.py`, `query_builder.py`, `requests.py`,
`transport.py`, `utils.py`, plus `_typed_namespaces.py` (internal).

## Tree navigation gotcha

**The old `/children` and `/resources/get` endpoints are gone.**

To get children: read each resource's `child_identifiers`, then hydrate with
`vxd.resources.retrieve(child_ids)`.

**`query()` does NOT populate `child_identifiers`.** Only the read path
(`retrieve`) does. Roots are datasources (no parent): query their IDs, then
`retrieve` to hydrate.

Example consumer implementing tree traversal: `mono/packages/vxdata-explorer`
(the `dora` command — a Miller-column terminal CLI for browsing the resource
tree).

## Local dev loop (apps/vxdata-api)

From `mono/apps/vxdata-api/`, run `just`:

- `just deploy` — start MinIO + Postgres + API (uvicorn) via process-compose
- `just inject-mock` — inject mock data on demand (runs `scripts/seed_db.py`)
- `just cleanup` — stop the stack and wipe `deployments/dev/.runtime`

**There is no auto-seed.** The `SEED_MOCK`/`RUN_SEED` env flags were removed
(mono PR #99, 2026-06-17). Seeding is always explicit via `just inject-mock`.

Stack listens on `:12300` (API), `:12305` (MinIO console). Every request needs
`Authorization: Bearer <token>`; the API refuses to start without a principal
config. `just deploy` seeds `deployments/dev/principals.json` from
`principals.example.json` — read the dev token names from there (or from
`apps/vxdata-api/AGENTS.md`) rather than from this page, and export the one you
want as `VXDATA_TOKEN`.

## Related docs

- Migration from pre-1.0 SDK: `mono/apps/vxdata-api/docs/reference/migration-june-2026.md`
- Database structure (still uses old table names `resource_patients`,
  `payload_measurements` as of 2026-07-30):
  `mono/apps/vxdata-api/docs/explainers/database-structure.md`

---

_Known drift (2026-08-06): `PIRADSLesionAssessment.reference_mask_id` comment
still mentions `BinaryMask`; should be `VoxelMap`
(`packages/vxdata-schemas/src/vxdata/schemas/payloads.py` line 249)._

Source: https://docs.virdx.dev/knowledge/wiki/workstreams/infrastructure/sops/vxdata-sdk-and-schema-model/index.mdx
