Custom Properties in OpenMetadata allow extending any entity with organization-specific metadata fields without modifying the core schema. This enables tailoring OpenMetadata to unique business needs while maintaining compatibility with the standard schema.
Custom Properties provide:
- Schema Extension: Add custom fields to any entity type
- Type Safety: Define data types and validation rules
- No Code Changes: Extend entities without modifying OpenMetadata code
- API Support: Access custom properties through standard APIs
- UI Integration: Custom fields appear in the OpenMetadata UI
- Migration Safe: Survive platform upgrades
- Multi-tenancy: Different properties for different teams/domains
OpenMetadata entities support an extension field that stores custom properties:
{
"id": "table-uuid",
"name": "customers",
"description": "Customer master table",
"extension": {
"dataClassification": "Internal",
"costCenter": "CC-12345",
"retentionYears": 7,
"complianceApproved": true,
"applicationOwner": "CustomerApp",
"customTags": ["critical", "pii", "financial"]
}
}Custom properties are defined through the Type system:
{
"name": "dataClassification",
"propertyType": {
"id": "classification-type-id",
"type": "enum",
"name": "DataClassification"
},
"description": "Data classification level",
"customPropertyConfig": {
"config": {
"values": ["Public", "Internal", "Confidential", "Restricted"]
}
}
}{
"name": "applicationOwner",
"propertyType": {
"type": "string"
},
"description": "Name of the owning application"
}{
"name": "retentionYears",
"propertyType": {
"type": "integer"
},
"description": "Data retention period in years"
}{
"name": "monthlyCost",
"propertyType": {
"type": "number"
},
"description": "Monthly cost in dollars"
}{
"name": "complianceApproved",
"propertyType": {
"type": "boolean"
},
"description": "Whether compliance team approved"
}{
"name": "certificationDate",
"propertyType": {
"type": "dateTime"
},
"description": "Date of last security certification"
}{
"name": "dataClassification",
"propertyType": {
"type": "enum",
"config": {
"values": ["Public", "Internal", "Confidential", "Restricted"]
}
},
"description": "Data sensitivity classification"
}{
"name": "relatedTable",
"propertyType": {
"type": "entityReference",
"config": {
"entityType": "table"
}
},
"description": "Reference to related table"
}{
"name": "supportedRegions",
"propertyType": {
"type": "array",
"config": {
"arrayItemType": "string"
}
},
"description": "List of supported geographic regions"
}{
"name": "technicalNotes",
"propertyType": {
"type": "markdown"
},
"description": "Detailed technical documentation"
}=== "JSON Schema"
```json
{
"$id": "https://open-metadata.org/schema/type/customProperty.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CustomProperty",
"description": "Custom property definition for extending entities.",
"type": "object",
"definitions": {
"propertyType": {
"description": "Type of custom property",
"type": "object",
"properties": {
"id": {
"$ref": "./basic.json#/definitions/uuid"
},
"type": {
"type": "string",
"enum": [
"string",
"integer",
"number",
"boolean",
"date",
"dateTime",
"time",
"duration",
"email",
"uri",
"enum",
"entityReference",
"entityReferenceList",
"markdown",
"array"
]
},
"name": {
"type": "string"
},
"description": {
"type": "string"
}
},
"required": ["type"]
},
"customPropertyConfig": {
"description": "Configuration for the custom property",
"type": "object",
"properties": {
"config": {
"type": "object",
"properties": {
"values": {
"description": "Allowed values for enum type",
"type": "array",
"items": {
"type": "string"
}
},
"entityType": {
"description": "Entity type for entityReference",
"type": "string"
},
"multiSelect": {
"description": "Allow multiple selections for enum",
"type": "boolean"
},
"arrayItemType": {
"description": "Type of items in array",
"type": "string"
}
}
}
}
}
},
"properties": {
"name": {
"description": "Name of the custom property",
"type": "string",
"pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
},
"description": {
"description": "Description of the custom property",
"type": "string"
},
"propertyType": {
"$ref": "#/definitions/propertyType"
},
"customPropertyConfig": {
"$ref": "#/definitions/customPropertyConfig"
}
},
"required": ["name", "propertyType"],
"additionalProperties": false
}
```
=== "RDF (Turtle)"
```turtle
@prefix om: <https://open-metadata.org/schema/> .
@prefix om-custom: <https://open-metadata.org/schema/type/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
# Custom Property Class
om-custom:CustomProperty a owl:Class ;
rdfs:label "Custom Property" ;
rdfs:comment "Custom property definition for extending entities" ;
rdfs:isDefinedBy om: .
# Properties
om-custom:propertyName a owl:DatatypeProperty ;
rdfs:label "property name" ;
rdfs:comment "Name of the custom property" ;
rdfs:domain om-custom:CustomProperty ;
rdfs:range xsd:string .
om-custom:propertyType a owl:DatatypeProperty ;
rdfs:label "property type" ;
rdfs:comment "Data type of the property" ;
rdfs:domain om-custom:CustomProperty ;
rdfs:range xsd:string .
om-custom:hasExtension a owl:ObjectProperty ;
rdfs:label "has extension" ;
rdfs:comment "Custom property extension" ;
rdfs:range om-custom:CustomProperty .
```
=== "JSON-LD Context"
```json
{
"@context": {
"@vocab": "https://open-metadata.org/schema/type/",
"om": "https://open-metadata.org/schema/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"CustomProperty": {
"@id": "om:CustomProperty",
"@type": "@id"
},
"name": {
"@id": "om:propertyName",
"@type": "xsd:string"
},
"propertyType": {
"@id": "om:propertyType",
"@type": "xsd:string"
},
"extension": {
"@id": "om:hasExtension",
"@type": "@id"
}
}
}
```
Add business-specific fields:
{
"name": "customers",
"extension": {
"businessOwner": "Sales Department",
"costCenter": "CC-SALES-001",
"projectCode": "PROJ-2024-001",
"budgetCategory": "Operations"
}
}Track regulatory requirements:
{
"name": "customer_data",
"extension": {
"dataClassification": "Confidential",
"gdprApplicable": true,
"hipaaCompliant": false,
"retentionYears": 7,
"complianceApprovalDate": "2024-01-15",
"lastAuditDate": "2024-01-10",
"nextAuditDue": "2024-07-10"
}
}Add technical details:
{
"name": "sales_data",
"extension": {
"storageClass": "STANDARD",
"compressionType": "SNAPPY",
"partitionStrategy": "DATE",
"replicationFactor": 3,
"backupEnabled": true,
"encryptionAlgorithm": "AES-256"
}
}Track data costs:
{
"name": "analytics_warehouse",
"extension": {
"monthlyCost": 15000.50,
"costCenter": "CC-12345",
"costAllocationTag": "analytics-team",
"storageGB": 50000,
"queryCreditsMonthly": 10000
}
}Link to applications:
{
"name": "orders",
"extension": {
"applicationName": "E-Commerce Platform",
"applicationVersion": "2.5.1",
"deploymentEnvironment": "Production",
"serviceLevel": "Tier-1",
"oncallTeam": "Platform Engineering"
}
}POST /api/v1/metadata/types/{entityType}/customProperties
Content-Type: application/json
{
"name": "dataClassification",
"description": "Data classification level",
"propertyType": {
"type": "enum",
"config": {
"values": ["Public", "Internal", "Confidential", "Restricted"]
}
}
}- Navigate to Settings → Custom Properties
- Select entity type (Table, Dashboard, etc.)
- Click "Add Custom Property"
- Define name, type, and configuration
- Save and apply to entities
PATCH /api/v1/tables/{id}
Content-Type: application/json-patch+json
[
{
"op": "add",
"path": "/extension/dataClassification",
"value": "Confidential"
}
]GET /api/v1/search/query?q=extension.dataClassification:ConfidentialUse advanced search to filter by custom properties:
extension.costCenter:"CC-12345"
extension.complianceApproved:true
extension.retentionYears:>5
Follow camelCase convention: dataClassification not data_classification
Document what each property means and when to use it
Prefer enums over free text for standardized values
Use custom properties for organization-specific needs only
Define who can create and modify custom properties
Maintain documentation of custom property definitions
Use appropriate types and validation rules
Limit the number of custom properties (< 20 per entity type)
{
"dataClassification": "enum",
"regulatoryFramework": "array<string>",
"retentionPeriod": "integer",
"privacyImpactAssessment": "boolean",
"lastAuditDate": "date"
}{
"costCenter": "string",
"monthlyCost": "number",
"budgetOwner": "string",
"chargeback": "boolean"
}{
"applicationName": "string",
"applicationOwner": "string",
"serviceLevel": "enum",
"supportTeam": "string"
}{
"qualityScore": "number",
"lastValidationDate": "date",
"validationStatus": "enum",
"knownIssues": "markdown"
}All entity pages support custom properties through the extension field. When documenting entities, reference custom properties:
## Custom Properties
This entity supports custom properties through the `extension` field.
Common custom properties include:
- **Data Classification**: Sensitivity level
- **Cost Center**: Billing allocation
- **Retention Period**: Data retention requirements
- **Application Owner**: Owning application/team
See [Custom Properties](../metadata-specifications/custom-properties.md)
for details on defining and using custom properties.GET /api/v1/metadata/types/{entityType}POST /api/v1/metadata/types/{entityType}/customPropertiesPUT /api/v1/metadata/types/{entityType}/customProperties/{propertyName}DELETE /api/v1/metadata/types/{entityType}/customProperties/{propertyName}