Assets
Understanding Assets in the sovity EDC Connector
Assets
An Asset is a fundamental concept in the EDC representing a digital resource that can be shared through the data space. Assets contain metadata describing the resource and a Data Source specifying where and how to access the actual data.
Asset Structure
The sovity EDC API uses a type-safe UiAsset structure that simplifies asset management compared to the raw EDC JSON-LD format.
Core Fields
| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier for the asset |
dataSource | Yes | Configuration for accessing the actual data |
title | No | Human-readable title |
description | No | Detailed description (supports Markdown) |
version | No | Version identifier |
language | No | Language code as IDS URI (see Language Codes) |
keywords | No | Array of keywords for discoverability |
mediaType | No | MIME type of the data |
Metadata Fields
| Field | Description |
|---|---|
publisherHomepage | URL to the publisher's website |
licenseUrl | URL to the license terms |
landingPageUrl | URL to external documentation or landing page for the asset |
dataCategory | Category classification |
dataSubcategory | Subcategory classification |
dataModel | Data model or schema identifier |
sovereignLegalName | Legal owner of the data (if different from publisher) |
Geographic and Temporal Fields
| Field | Description |
|---|---|
geoLocation | Geographic location description |
geoReferenceMethod | Method used for geo-referencing |
nutsLocations | NUTS region codes (EU administrative divisions) |
temporalCoverageFrom | Start date of data coverage |
temporalCoverageToInclusive | End date of data coverage (inclusive) |
transportMode | Transport mode (for mobility data) |
Custom Properties
| Field | Description |
|---|---|
customJsonAsString | Custom properties as JSON string |
customJsonLdAsString | Custom properties as JSON-LD string |
privateCustomJsonAsString | Private custom properties (not visible to consumers) |
privateCustomJsonLdAsString | Private custom properties as JSON-LD |
DRK-Specific Fields (Datenraum Kultur)
These fields are specific to the Datenraum Kultur (Cultural Data Space) and help categorize assets by cultural domain.
DRK Asset Type
The drkAssetType field categorizes the asset by its cultural domain. If not specified, it defaults to GENERAL.
| Asset Type | Description | Conditional Fields |
|---|---|---|
GENERAL | General purpose data asset (default) | None |
MUSEUM | Museum-related data (collections, artworks, metadata) | drkMuseumName |
THEATRE_PLAN | Theatre schedule and performance data | drkTheatreName, drkTheatreStreetaddress, drkTheatrePostalCode, drkTheatreLocality, drkTheatreCountry |
MUSICSCHOOL | Music school and education data | drkMusicSchoolName |
Conditional DRK Fields
Depending on the drkAssetType, you can provide additional metadata:
For MUSEUM assets:
| Field | Description |
|---|---|
drkMuseumName | Name of the museum providing the data |
For THEATRE_PLAN assets:
| Field | Description |
|---|---|
drkTheatreName | Name of the theatre |
drkTheatreStreetaddress | Street address of the theatre |
drkTheatrePostalCode | Postal code |
drkTheatreLocality | City or locality |
drkTheatreCountry | Country |
For MUSICSCHOOL assets:
| Field | Description |
|---|---|
drkMusicSchoolName | Name of the music school |
Language Codes
The language field uses IDS (International Data Spaces) language code URIs. Common codes include:
| Language | IDS URI |
|---|---|
| German | https://w3id.org/idsa/code/DE |
| English | https://w3id.org/idsa/code/EN |
For a complete list of language codes, see the IDS Information Model Language Codes.
Data Source Types
The dataSource field defines how the actual data is accessed. Three types are supported:
HTTP_DATA
For assets served via HTTP/HTTPS endpoints:
const httpDataSource = {
type: 'HTTP_DATA',
httpData: {
baseUrl: 'https://api.example.com/data/v1',
method: 'GET', // GET, POST, PUT, PATCH, DELETE, OPTIONS
// Optional: Query parameters
queryString: 'format=json&limit=100',
// Optional: Authentication
authHeaderName: 'Authorization',
authHeaderValue: {
secretName: 'my-api-key', // Reference to vault secret
// OR
rawValue: 'Bearer token123' // Inline value (less secure)
},
// Optional: Additional headers
headers: {
'Accept': 'application/json',
'X-Custom-Header': 'value'
},
// Optional: Parameterization (allows consumer to customize requests)
enableMethodParameterization: false,
enablePathParameterization: true,
enableQueryParameterization: true,
enableBodyParameterization: false
}
};Parameterization Options
| Option | Description |
|---|---|
enableMethodParameterization | Consumer can specify HTTP method |
enablePathParameterization | Consumer can append to the path |
enableQueryParameterization | Consumer can add query parameters |
enableBodyParameterization | Consumer can provide request body (POST/PUT/PATCH only) |
ON_REQUEST
For assets that require manual data provision (no automated data source):
const onRequestDataSource = {
type: 'ON_REQUEST',
onRequest: {
contactEmail: 'data-requests@museum.example.com',
contactPreferredEmailSubject: 'Data Request: Museum Collection API Access'
}
};Use this when:
- Data requires manual approval or preparation
- Data is provided through offline channels
- You want to collect interest before setting up automated access
CUSTOM
For custom data address types not covered by HTTP_DATA or ON_REQUEST:
const customDataSource = {
type: 'CUSTOM',
customProperties: {
'type': 'AmazonS3',
'bucketName': 'my-data-bucket',
'region': 'eu-central-1',
'objectName': 'datasets/collection.json'
}
};Creating an Asset
Using the Asset Endpoint
Endpoint: POST /wrapper/ui/pages/asset-page/assets
cURL Example
curl -X POST "https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page/assets" \
-H "Content-Type: application/json" \
-H "X-Api-Key: your-api-key" \
-d '{
"id": "museum-collection-2024",
"title": "Museum Digital Collection",
"description": "Digitized artworks from the museum collection including metadata and high-resolution images.",
"version": "1.0",
"language": "en",
"keywords": ["museum", "art", "digital", "collection"],
"mediaType": "application/json",
"dataCategory": "Cultural Heritage",
"dataSubcategory": "Museum Collections",
"licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
"dataSource": {
"type": "HTTP_DATA",
"httpData": {
"baseUrl": "https://api.museum.example.com/collection/v1",
"method": "GET",
"authHeaderName": "X-API-Key",
"authHeaderValue": {
"secretName": "museum-api-key"
},
"enablePathParameterization": true,
"enableQueryParameterization": true
}
}
}'TypeScript Example
interface UiAssetCreateRequest {
id: string;
title?: string;
description?: string;
version?: string;
language?: string;
keywords?: string[];
mediaType?: string;
dataCategory?: string;
dataSubcategory?: string;
licenseUrl?: string;
publisherHomepage?: string;
landingPageUrl?: string;
dataSource: {
type: 'HTTP_DATA' | 'ON_REQUEST' | 'CUSTOM';
httpData?: {
baseUrl: string;
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';
queryString?: string;
authHeaderName?: string;
authHeaderValue?: { secretName?: string; rawValue?: string };
headers?: Record<string, string>;
enableMethodParameterization?: boolean;
enablePathParameterization?: boolean;
enableQueryParameterization?: boolean;
enableBodyParameterization?: boolean;
};
onRequest?: {
contactEmail: string;
contactPreferredEmailSubject: string;
};
customProperties?: Record<string, string>;
};
}
const asset: UiAssetCreateRequest = {
id: 'museum-collection-2024',
title: 'Museum Digital Collection',
description: 'Digitized artworks from the museum collection.',
version: '1.0',
language: 'en',
keywords: ['museum', 'art', 'digital', 'collection'],
mediaType: 'application/json',
dataCategory: 'Cultural Heritage',
dataSource: {
type: 'HTTP_DATA',
httpData: {
baseUrl: 'https://api.museum.example.com/collection/v1',
method: 'GET',
authHeaderName: 'X-API-Key',
authHeaderValue: { secretName: 'museum-api-key' },
enablePathParameterization: true,
enableQueryParameterization: true,
},
},
};
const response = await fetch(
'https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page/assets',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'your-api-key',
},
body: JSON.stringify(asset),
}
);
const result = await response.json();
console.log('Created asset:', result.id);Response
{
"id": "museum-collection-2024",
"lastUpdatedDate": "2024-01-15T10:30:00Z"
}Quick Data Offer Creation
For a streamlined workflow, use the Create Data Offer endpoint to create an asset, policy, and contract definition in a single call.
Endpoint: POST /wrapper/ui/pages/create-data-offer
This endpoint uses a flat structure where all asset fields are at the root level, not nested inside an asset object.
Publish Types
| Type | Description |
|---|---|
DONT_PUBLISH | Only create the asset, no policy or contract definition |
PUBLISH_UNRESTRICTED | Create asset with an always-true policy (public access) |
PUBLISH_RESTRICTED | Create asset with a custom policy expression |
All publish types are optional. If not specified, only the asset is created.
cURL Example (Museum Asset)
curl -X POST "https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/create-data-offer" \
-H "Content-Type: application/json" \
-H "X-Api-Key: your-api-key" \
-d '{
"id": "museum-collection-2024",
"title": "Museum Digital Collection 2024",
"description": "Digitized artworks from our permanent collection",
"language": "https://w3id.org/idsa/code/DE",
"version": "1.0",
"keywords": ["museum", "art", "digital-collection"],
"mediaType": "application/json",
"publisherHomepage": "https://museum.example.com",
"licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
"landingPageUrl": "https://museum.example.com/api-docs",
"drkAssetType": "MUSEUM",
"drkMuseumName": "Hamburger Kunsthalle",
"dataSource": {
"type": "HTTP_DATA",
"httpData": {
"method": "GET",
"baseUrl": "https://api.museum.example.com/collection",
"queryString": "",
"authHeaderValue": {},
"headers": {},
"enableMethodParameterization": false,
"enablePathParameterization": false,
"enableQueryParameterization": false,
"enableBodyParameterization": false
}
},
"publishType": "PUBLISH_UNRESTRICTED"
}'TypeScript Example (Theatre Asset)
type DrkAssetType = 'GENERAL' | 'MUSEUM' | 'THEATRE_PLAN' | 'MUSICSCHOOL';
interface DataOfferCreateRequest {
// Required
id: string;
dataSource: UiDataSource;
// Optional metadata
title?: string;
description?: string;
language?: string; // IDS URI
version?: string;
keywords?: string[];
mediaType?: string;
publisherHomepage?: string;
licenseUrl?: string;
landingPageUrl?: string;
// DRK-specific (all optional, default drkAssetType = 'GENERAL')
drkAssetType?: DrkAssetType;
drkMuseumName?: string | null;
drkTheatreName?: string | null;
drkTheatreStreetaddress?: string | null;
drkTheatrePostalCode?: string | null;
drkTheatreLocality?: string | null;
drkTheatreCountry?: string | null;
drkMusicSchoolName?: string | null;
// Policy (optional)
publishType?: 'DONT_PUBLISH' | 'PUBLISH_UNRESTRICTED' | 'PUBLISH_RESTRICTED';
policyExpression?: UiPolicyExpression;
}
const theatreDataOffer: DataOfferCreateRequest = {
id: 'theatre-schedule-2024',
title: 'Theatre Performance Schedule 2024',
description: 'Machine-readable theatre schedule data',
language: 'https://w3id.org/idsa/code/DE',
version: '1.0',
keywords: ['theatre', 'schedule', 'performances'],
mediaType: 'application/json',
landingPageUrl: 'https://theatre.example.com/api-docs',
drkAssetType: 'THEATRE_PLAN',
drkTheatreName: 'Deutsches Schauspielhaus',
drkTheatreStreetaddress: 'Kirchenallee 39',
drkTheatrePostalCode: '20099',
drkTheatreLocality: 'Hamburg',
drkTheatreCountry: 'Germany',
dataSource: {
type: 'HTTP_DATA',
httpData: {
method: 'GET',
baseUrl: 'https://api.theatre.example.com/schedule',
enableQueryParameterization: true,
},
},
publishType: 'PUBLISH_UNRESTRICTED',
};
const response = await fetch(
'https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/create-data-offer',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'your-api-key',
},
body: JSON.stringify(theatreDataOffer),
}
);
const result = await response.json();
console.log('Created data offer:', result.id);Music School Example
const musicSchoolDataOffer: DataOfferCreateRequest = {
id: 'music-lessons-catalog-2024',
title: 'Music Lessons Catalog',
description: 'Available music lessons and instructors',
language: 'https://w3id.org/idsa/code/DE',
version: '1.0',
keywords: ['music', 'education', 'lessons'],
mediaType: 'application/json',
drkAssetType: 'MUSICSCHOOL',
drkMusicSchoolName: 'Hamburger Konservatorium',
dataSource: {
type: 'HTTP_DATA',
httpData: {
method: 'GET',
baseUrl: 'https://api.musicschool.example.com/catalog',
},
},
publishType: 'PUBLISH_RESTRICTED',
policyExpression: {
type: 'CONSTRAINT',
constraint: {
left: 'purpose',
operator: 'EQ',
right: { type: 'STRING', value: 'education' },
},
},
};Listing Assets
Endpoint: GET /wrapper/ui/pages/asset-page
cURL Example
curl -X GET "https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page" \
-H "X-Api-Key: your-api-key"TypeScript Example
interface AssetPage {
assets: UiAsset[];
}
interface UiAsset {
assetId: string;
title: string;
description?: string;
dataSourceAvailability: 'LIVE' | 'ON_REQUEST';
creatorOrganizationName: string;
isOwnConnector: boolean;
// ... additional fields
}
const response = await fetch(
'https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page',
{
headers: { 'X-Api-Key': 'your-api-key' },
}
);
const assetPage: AssetPage = await response.json();
console.log(`Found ${assetPage.assets.length} assets`);
// Filter your own assets
const myAssets = assetPage.assets.filter(a => a.isOwnConnector);Editing an Asset
Endpoint: PUT /wrapper/ui/pages/asset-page/assets/{assetId}
cURL Example
curl -X PUT "https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page/assets/museum-collection-2024" \
-H "Content-Type: application/json" \
-H "X-Api-Key: your-api-key" \
-d '{
"title": "Museum Digital Collection - Updated",
"description": "Updated description with new information",
"version": "1.1",
"keywords": ["museum", "art", "digital", "collection", "updated"]
}'TypeScript Example
interface UiAssetEditRequest {
title?: string;
description?: string;
version?: string;
keywords?: string[];
// ... other editable fields
dataSourceOverrideOrNull?: UiDataSource; // Optional: update data source
}
const update: UiAssetEditRequest = {
title: 'Museum Digital Collection - Updated',
description: 'Updated description with new information',
version: '1.1',
};
await fetch(
'https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page/assets/museum-collection-2024',
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-Api-Key': 'your-api-key',
},
body: JSON.stringify(update),
}
);Deleting an Asset
Endpoint: DELETE /wrapper/ui/pages/asset-page/assets/{assetId}
cURL Example
curl -X DELETE "https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/asset-page/assets/museum-collection-2024" \
-H "X-Api-Key: your-api-key"Assets referenced by active Contract Agreements cannot be deleted. You must terminate or wait for all related agreements to expire first.
Validating Asset IDs
Before creating an asset, you can check if an ID is already taken:
Endpoint: GET /wrapper/ui/pages/data-offer-page/validate-asset-id/{assetId}
interface IdAvailabilityResponse {
id: string;
available: boolean;
}
const response = await fetch(
'https://api.your-connector-instance.prod.truzztbox.eu/api/management/wrapper/ui/pages/data-offer-page/validate-asset-id/my-new-asset',
{ headers: { 'X-Api-Key': 'your-api-key' } }
);
const result: IdAvailabilityResponse = await response.json();
if (result.available) {
console.log('ID is available, proceed with creation');
} else {
console.log('ID already taken, choose a different one');
}Asset Lifecycle
- Create: Define the asset with metadata and data source
- Validate: Optionally check ID availability before creation
- Link: Create a Contract Definition to make the asset discoverable
- Discover: Asset appears in the federated catalog for consumers
- Negotiate: Consumers negotiate for access through contract offers
- Transfer: Data is transferred under the agreed policy terms
- Update: Modify asset metadata as needed
- Delete: Remove when no longer needed
Best Practices
- Use meaningful IDs: Choose descriptive, URL-safe identifiers
- Complete metadata: Provide comprehensive descriptions for discoverability
- Use vault secrets: Store authentication credentials securely using
secretNameinstead ofrawValue - Enable appropriate parameterization: Only enable the parameterization options consumers actually need
- Version your assets: Use semantic versioning in the
versionfield - Add keywords: Help consumers find your assets through search