Skip to content
Proposed specification for review. We are seeking feedback on key architectural choices in the industry consultation.

Retrieve Credentials

Once a property transaction is underway, the resulting Verifiable Credentials (VCs) do not live in a central database. They reside in the digital wallets or encrypted data hubs of the participating parties (like a conveyancer’s CMS or a data hub like LMS).

To access this data, consumers must know:

  1. Where to ask (Discovered via the Transaction’s DID Document)
  2. How to authenticate (Using the relationship credential that ties you to the transaction, such as Representation or TransactionRole)
  3. What protocol to use (OID4VP for systems, MCP for agents)

Every property transaction has a Decentralised Identifier (e.g., did:web:platform.example.com:transactions:abc123).

Before requesting credentials, you must resolve this DID to find the correct data hub.

import { DidResolver } from '@pdtf/core';
const resolver = new DidResolver();
const didDocument = await resolver.resolve('did:web:platform.example.com:transactions:abc123');

The DID document contains a service array declaring where requests should be sent:

{
"id": "did:web:platform.example.com:transactions:abc123",
"service": [
{
"id": "#oid4vp",
"type": "OID4VP",
"serviceEndpoint": "https://platform.example.com/api/v1/transactions/abc123/present"
},
{
"id": "#mcp",
"type": "ModelContextProtocol",
"serviceEndpoint": "wss://platform.example.com/mcp/v2/transactions/abc123"
}
]
}

You now know the exact URLs for both system-to-system (OID4VP) and agentic (MCP) access.


2. Discovery Mechanism — Public vs Authenticated Data

Section titled “2. Discovery Mechanism — Public vs Authenticated Data”

Not all property data requires authentication. PDTF distinguishes between public property data and transaction-specific data, and they have different access patterns.

Public property information — such as EPC certificates, HM Land Registry title summaries, and local authority planning data — can be queried from a platform’s public API or MCP endpoint using only the Property URN (e.g., urn:pdtf:uprn:100023336956).

No Representation or TransactionRole credential is needed. The data is already public record, and the VCs wrapping it serve to prove provenance and issuer trust, not to restrict access.

Terminal window
# Query public credentials for a property
curl https://platform.example.com/api/v1/properties/urn:pdtf:uprn:100023336956/credentials

The response contains signed VCs from authorised adapters — EPC data signed by the EPC adapter, title register summaries signed by the HMLR adapter, and so on. A consumer can verify these credentials using VcValidator to confirm they are genuine and unrevoked, without needing any relationship to the transaction.

Discovery starts with a Property URN. In England and Wales this is typically a UPRN (Unique Property Reference Number). If you don’t have the UPRN, platforms may offer a search endpoint:

Terminal window
# Address-based property lookup
curl "https://platform.example.com/api/v1/properties/search?postcode=SW1A+2AA"

This returns matching Property URNs, which you can then use to fetch public credentials.

Transaction-specific data: requires graph traversal with auth

Section titled “Transaction-specific data: requires graph traversal with auth”

Transaction data — status, agreed price, conditions, chain position, legal pack documents — is not public. Accessing it requires:

  1. A valid Representation, TransactionRole or Offer credential proving your relationship to the transaction
  2. The Transaction DID (not just the Property URN)
  3. Authentication via OID4VP or MCP as described in sections 3 and 4 below

The platform traverses the entity graph to verify that the requesting party has a legitimate role before returning any transaction-scoped credentials.

Data typeIdentifier neededAuth requiredExample
Public property dataProperty URNNoneEPC, title summary, flood risk
Transaction-specific dataTransaction DIDRepresentation, TransactionRole or Offer VCPrice, status, legal pack

This separation means read-only consumers (property portals, market analysts, valuation tools) can access public property intelligence without being party to any transaction, while sensitive transaction data remains protected by the entity graph’s access control model.


Traditional data consumers (like a lender’s automated underwriting system) use the OpenID for Verifiable Presentations (OID4VP) protocol.

In PDTF 2.0, authorisation is based entirely on the entity graph. You cannot access a transaction unless you hold a capability token (such as a Representation or TransactionRole credential) that proves you have the right to see it.

You send a POST request to the discovered OID4VP endpoint. The payload contains a W3C Presentation Exchange definition detailing what you need, along with the Verifiable Presentation proving your right to access it.

Terminal window
curl -X POST https://platform.example.com/api/v1/transactions/abc123/present \
-H "Content-Type: application/json" \
-d '{
"presentation_definition": {
"id": "lender_request_1",
"input_descriptors": [
{
"id": "property_data",
"constraints": {
"fields": [
{ "path": ["$.type"], "filter": { "contains": "PropertyCredential" } },
{ "path": ["$.type"], "filter": { "contains": "TitleCredential" } }
]
}
}
]
},
"vp_token": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiablePresentation"],
"verifiableCredential": [
{ "... TransactionRole VC ..." }
],
"proof": { "... Your signature over the request ..." }
}
}'

The platform validates your TransactionRole, traverses the transaction graph, and returns the requested credentials bundled into a Verifiable Presentation.

{
"vp_token": {
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiablePresentation"],
"verifiableCredential": [
{
"type": ["VerifiableCredential", "PropertyCredential"],
"credentialSubject": { "id": "urn:pdtf:uprn:123", "..." : "..." }
},
{
"type": ["VerifiableCredential", "TitleCredential"],
"credentialSubject": { "id": "urn:pdtf:titleNumber:ABC", "..." : "..." }
}
]
}
}

AI Agents (like a conveyancer’s copilot) access the exact same data using the Model Context Protocol (MCP). The authorisation logic is identical, but the transport and interface are designed for LLMs rather than traditional APIs.

The agent connects to the WebSocket endpoint discovered in the DID Document. During the MCP handshake, the agent authenticates by signing a challenge using the firm’s did:key or did:web private key.

Once connected, the agent asks for the data using the get_credentials tool.

{
"jsonrpc": "2.0",
"id": "req_1",
"method": "tools/call",
"params": {
"name": "get_credentials",
"arguments": {
"id": "did:web:platform.example.com:transactions:abc123"
}
}
}

The MCP server intercepts this tool call. It knows the identity of the connected agent (e.g., did:web:smithandco.law). It traverses the transaction graph to see if smithandco.law holds a valid Representation credential for the seller. Because the graph proves the relationship, access is granted.

The server returns the credentials directly into the LLM’s context window.

{
"jsonrpc": "2.0",
"id": "req_1",
"result": {
"content": [
{
"type": "text",
"text": "{\"type\": [\"PropertyCredential\"], \"credentialSubject\": {\"address\": \"10 Downing Street\"}}"
}
]
}
}

From there, the agent can use the @pdtf/core state assembly tools to resolve the raw credentials into a flat, readable v4 entity state or v3 JSON object to continue its reasoning.