Implementation Updated 2026-05-14

Validation

How to run a PDTF transaction through a validator, decode the errors, and validate verified-claims envelopes. The package wraps Ajv with the right keyword configuration so you don't have to assemble it yourself.

getValidator()

const { getValidator } = require('@pdtf/schemas');

const validate = getValidator(
  'https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json',
  ['baspi5', 'nts2']
);

const ok = validate(transaction);
if (!ok) {
  console.error(validate.errors);
}

Returns an Ajv-compiled validator. The Ajv instance is shared across calls and configured with:

Decoding errors

Ajv error format. Each entry has instancePath, schemaPath, keyword, params, message.

// Example error from a missing required field
{
  instancePath: '/propertyPack/priceInformation',
  schemaPath:   '#/properties/propertyPack/required',
  keyword:      'required',
  params:       { missingProperty: 'price' },
  message:      "must have required property 'price'"
}

Useful patterns:

You seeLikely causeFix
must have required property 'X' Overlay made it required; base didn't Add it, or drop the overlay if it doesn't apply
must match exactly one schema in oneOf Discriminator field has no match, or matches more than one branch Check the value of the discriminator (usually role, yesNo, capacity etc.)
must be equal to one of the allowed values Enum violation Look up the enum in the merged schema; case sensitivity matters
strict mode: unknown keyword: "X" You configured Ajv strictly Use getValidator rather than rolling your own Ajv instance

validateVerifiedClaims()

PDTF transactions can be expressed as Verified Claims (W3C VC Data Model 2.0 envelopes). The package exports a dedicated validator for that case:

const { validateVerifiedClaims } = require('@pdtf/schemas');

const errors = validateVerifiedClaims(
  verifiedClaimsData,
  'https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json',
  ['baspi5']
);

if (errors.length === 0) {
  console.log('All claims valid');
}

Each claim inside the VC envelope is validated against the merged PDTF transaction schema at the path the claim describes (using its credentialSubject path). Returns an array of error objects; empty array means all claims passed.

See Verified claims for the envelope shape.

Validating a sub-path

For a producer who only emits one part of the transaction (e.g. just the BASPI section), you don't need the whole base schema. getValidator accepts a JSON Pointer path:

const { getValidator } = require('@pdtf/schemas');

const validate = getValidator(
  BASE_ID,
  ['baspi5'],
  '/properties/propertyPack/properties/priceInformation'
);

The validator now only checks the priceInformation sub-tree against the merged schema.

Performance