
## Create custom metadata

URL: https://docs.atlan.com/product/capabilities/build-apps/sdks/python/custom-metadata/how-tos/create-custom-metadata

> Define custom metadata structures in Atlan using the Python SDK's builder pattern — group business attributes on any asset type, and note the ~1000 tenant-wide property limit.

# CustomMetadataDef: create custom metadata type definitions

Use `CustomMetadataDef` in the Atlan Python SDK to programmatically define and create custom metadata structures with typed attributes.

Like other objects in the SDK that you can create, custom metadata implements the builder pattern. This allows you to progressively build-up the structure you want to create.

:::warning[There are limits to the number of custom metadata properties you can create]
Atlan currently preserves details of custom metadata in its audit log. This allows Atlan to retain an audit trail of actions users took on custom metadata on each asset, even if the custom metadata definition itself is deleted.

However, this also places an upper limit on the number of custom metadata properties you can (structurally) define in Atlan. Even if you delete the custom metadata definitions, any that you have previously defined will still take up "space" within this limit.

> *More details — see full content on the documentation site.*

:::

## Build minimal object needed

For example, to create a custom metadata structure to capture RACI assignments:

### Java

```java showLineNumbers title="Build custom metadata definition for creation"
CustomMetadataDef customMetadataDef = CustomMetadataDef.creator("RACI") // (1)
 .attributeDef( // (2)
 AttributeDef.of(client, "Responsible", // (3)
 AtlanCustomAttributePrimitiveType.USERS, // (4)
 null, // (5)
 false)) // (6)
 .attributeDef(AttributeDef.of(client, "Accountable", AtlanCustomAttributePrimitiveType.USERS, false))
 .attributeDef(AttributeDef.of(client, "Consulted", AtlanCustomAttributePrimitiveType.GROUPS, true))
 .attributeDef(AttributeDef.of(client, "Informed", AtlanCustomAttributePrimitiveType.GROUPS, true))
 .options(CustomMetadataOptions.withImage("https://example.com/logo.png", true)) // (7)
 .options(CustomMetadataOptions.withEmoji("👪")) // (8)
 .options(CustomMetadataOptions.withIcon(AtlanIcon.ROCKET_LAUNCH, AtlanTagColor.RED)) // (9)
 .build(); // (10)
```

1. When creating the custom metadata structure, you must provide a name (`RACI` in this example).
2. You can then add as many attributes to that structure as you want.
3. Each attribute must have a name. Because this operation may need to retrieve information from Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
4. Each attribute must have a type.
5. If the type is `AtlanCustomAttributePrimitiveType.OPTIONS` then you must also specify the enumeration that defines the valid values for this attribute (in this example the type isn't an enumeration, so this is `null` and could even be left out as in the subsequent lines).
6. You must also specify whether the attribute allows multiple values to be captured on it (`true`) or only a single value (`false`).
7. You can also provide a custom logo for the custom metadata by providing a URL to an image. The second argument controls whether this custom metadata is editable via the UI—for `false` it's editable via the UI, while for `true` the custom metadata will only be editable via APIs (including via SDK).
8. Or you can use an emoji as the custom icon for the custom metadata.
9. Or you can use a built-in icon for the custom metadata. The second argument controls the color to use for the icon.
10. As with all other builder patterns, you must `build()` the object you've defined.

### Python

```python showLineNumbers title="Build custom metadata definition for creation"
from pyatlan.model.typedef import AttributeDef, CustomMetadataDef
from pyatlan.model.enums import AtlanCustomAttributePrimitiveType
from pyatlan.client.atlan import AtlanClient

cm_def = CustomMetadataDef.create(display_name="RACI") # (1)
cm_def.attribute_defs = [ # (2)
 AttributeDef.create(
 client=client, # (3)
 display_name="Responsible", # (4)
 attribute_type=AtlanCustomAttributePrimitiveType.USERS, # (5)
 options_name=None, # (6)
 multi_valued=False, # (7)
 ),
 AttributeDef.create(
 client=client,
 display_name="Accountable",
 attribute_type=AtlanCustomAttributePrimitiveType.USERS,
 ),
 AttributeDef.create(
 client=client,
 display_name="Consulted",
 attribute_type=AtlanCustomAttributePrimitiveType.GROUPS,
 multi_valued=True,
 ),
 AttributeDef.create(
 client=client,
 display_name="Informed",
 attribute_type=AtlanCustomAttributePrimitiveType.GROUPS,
 multi_valued=True,
 ),
]
cm_def.options = CustomMetadataDef.Options.with_logo_from_url( # (8)
 url="https://example.com/logo.png", locked=True
)
cm_def.options = CustomMetadataDef.Options.with_logo_as_emoji( # (9)
 emoji="👪", locked=False
)
```

1. When creating the custom metadata structure, you must provide a name (`RACI` in this example).
2. You can then add as many attributes to that structure as you want.
3. You must provide a client instance.
4. Each attribute must have a name.
5. Each attribute must have a type.
6. If the type is `AtlanCustomAttributePrimitiveType.OPTIONS` then you must also specify the enumeration that defines the valid values for this attribute (in this example none are enumerations, so this is the default value for the argument: `None`).
7. You can also specify whether the attribute allows multiple values to be captured on it (`True`) or only a single value (`False`) (the default).
8. You can also provide a custom logo for the custom metadata by providing a URL to an image. The second argument controls whether this custom metadata is editable via the UI—for `locked=False` it's editable via the UI, while for `locked=True` the custom metadata will only be editable via APIs (including via SDK).
9. Or you can use an emoji as the custom icon for the custom metadata.

### Kotlin

```kotlin showLineNumbers title="Build custom metadata definition for creation"
val customMetadataDef = CustomMetadataDef.creator("RACI") // (1)
 .attributeDef( // (2)
 AttributeDef.of(client, "Responsible", // (3)
 AtlanCustomAttributePrimitiveType.USERS, // (4)
 null, // (5)
 false)) // (6)
 .attributeDef(AttributeDef.of("Accountable", AtlanCustomAttributePrimitiveType.USERS, false))
 .attributeDef(AttributeDef.of("Consulted", AtlanCustomAttributePrimitiveType.GROUPS, true))
 .attributeDef(AttributeDef.of("Informed", AtlanCustomAttributePrimitiveType.GROUPS, true))
 .options(CustomMetadataOptions.withImage("https://example.com/logo.png", true)) // (7)
 .options(CustomMetadataOptions.withEmoji("👪")) // (8)
 .options(CustomMetadataOptions.withIcon(AtlanIcon.ROCKET_LAUNCH, AtlanTagColor.RED)) // (9)
 .build() // (10)
```

1. When creating the custom metadata structure, you must provide a name (`RACI` in this example).
2. You can then add as many attributes to that structure as you want.
3. Each attribute must have a name. Because this operation may need to retrieve information from Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.
4. Each attribute must have a type.
5. If the type is `AtlanCustomAttributePrimitiveType.OPTIONS` then you must also specify the enumeration that defines the valid values for this attribute (in this example the type isn't an enumeration, so this is `null` and could even be left out as in the subsequent lines).
6. You must also specify whether the attribute allows multiple values to be captured on it (`true`) or only a single value (`false`).
7. You can also provide a custom logo for the custom metadata by providing a URL to an image. The second argument controls whether this custom metadata is editable via the UI—for `false` it's editable via the UI, while for `true` the custom metadata will only be editable via APIs (including via SDK).
8. Or you can use an emoji as the custom icon for the custom metadata.
9. Or you can use a built-in icon for the custom metadata. The second argument controls the color to use for the icon.
10. As with all other builder patterns, you must `build()` the object you've defined.

### Raw REST API

```json showLineNumbers title="POST /api/meta/types/typedefs"
{
 "businessMetadataDefs": [ // (1),
 "isNew": true // (9)
 },
 {
 "name": "",
 "displayName": "Accountable",
 "description": "",
 "typeName": "string",
 "isOptional": true,
 "cardinality": "SINGLE",
 "valuesMinCount": 0,
 "valuesMaxCount": 1,
 "isUnique": false,
 "isIndexable": true,
 "includeInNotification": false,
 "options": {
 "applicableEntityTypes": "[\"Asset\"]",
 "customApplicableEntityTypes": "[\"S3Object\",\"LookerLook\",\"TableauSite\",\"SnowflakeStream\",\"ModeCollection\",\"LookerDashboard\",\"PowerBIWorkspace\",\"Collection\",\"AtlasGlossaryCategory\",\"TableauFlow\",\"LookerView\",\"TableauProject\",\"LookerExplore\",\"ModeReport\",\"PowerBIColumn\",\"Query\",\"ColumnProcess\",\"SalesforceDashboard\",\"SalesforceObject\",\"BIProcess\",\"DbtModelColumn\",\"S3Bucket\",\"SigmaDataElement\",\"DataStudioAsset\",\"DbtProcess\",\"DbtModel\",\"PowerBIDataset\",\"Column\",\"DbtMetric\",\"TableauDashboard\",\"SigmaDataset\",\"LookerQuery\",\"APISpec\",\"MetabaseDashboard\",\"Process\",\"PowerBIDashboard\",\"APIPath\",\"ModeChart\",\"PowerBIDataflow\",\"SalesforceField\",\"GCSObject\",\"SalesforceReport\",\"View\",\"Folder\",\"TableauMetric\",\"MaterialisedView\",\"PresetDashboard\",\"PowerBIDatasource\",\"ModeWorkspace\",\"SigmaPage\",\"LookerField\",\"SigmaWorkbook\",\"PowerBIMeasure\",\"TableauWorkbook\",\"LookerModel\",\"MetabaseCollection\",\"ModeQuery\",\"GCSBucket\",\"LookerTile\",\"Table\",\"PowerBITile\",\"PowerBIPage\",\"SalesforceOrganization\",\"PresetWorkspace\",\"TableauDatasource\",\"PresetDataset\",\"TableauCalculatedField\",\"LookerFolder\",\"TableauWorksheet\",\"MetabaseQuestion\",\"AtlasBusiness Graph\",\"PresetChart\",\"PowerBITable\",\"LookerProject\",\"SnowflakePipe\",\"PowerBIReport\",\"SigmaDatasetColumn\",\"TableauDatasourceField\",\"TablePartition\",\"AtlasGlossaryTerm\",\"SigmaDataElementField\",\"Schema\",\"Database\",\"DbtColumnProcess\"]",
 "allowSearch": false,
 "maxStrLength": "100000000",
 "allowFiltering": true,
 "multiValueSelect": false,
 "showInOverview": false,
 "primitiveType": "users",
 "isEnum": false,
 "customType": "users"
 },
 "isNew": true
 },
 {
 "name": "",
 "displayName": "Consulted",
 "description": "",
 "typeName": "array<string>",
 "isOptional": true,
 "cardinality": "SINGLE",
 "valuesMinCount": 0,
 "valuesMaxCount": 1,
 "isUnique": false,
 "isIndexable": true,
 "includeInNotification": false,
 "options": {
 "applicableEntityTypes": "[\"Asset\"]",
 "customApplicableEntityTypes": "[\"S3Object\",\"LookerLook\",\"TableauSite\",\"SnowflakeStream\",\"ModeCollection\",\"LookerDashboard\",\"PowerBIWorkspace\",\"Collection\",\"AtlasGlossaryCategory\",\"TableauFlow\",\"LookerView\",\"TableauProject\",\"LookerExplore\",\"ModeReport\",\"PowerBIColumn\",\"Query\",\"ColumnProcess\",\"SalesforceDashboard\",\"SalesforceObject\",\"BIProcess\",\"DbtModelColumn\",\"S3Bucket\",\"SigmaDataElement\",\"DataStudioAsset\",\"DbtProcess\",\"DbtModel\",\"PowerBIDataset\",\"Column\",\"DbtMetric\",\"TableauDashboard\",\"SigmaDataset\",\"LookerQuery\",\"APISpec\",\"MetabaseDashboard\",\"Process\",\"PowerBIDashboard\",\"APIPath\",\"ModeChart\",\"PowerBIDataflow\",\"SalesforceField\",\"GCSObject\",\"SalesforceReport\",\"View\",\"Folder\",\"TableauMetric\",\"MaterialisedView\",\"PresetDashboard\",\"PowerBIDatasource\",\"ModeWorkspace\",\"SigmaPage\",\"LookerField\",\"SigmaWorkbook\",\"PowerBIMeasure\",\"TableauWorkbook\",\"LookerModel\",\"MetabaseCollection\",\"ModeQuery\",\"GCSBucket\",\"LookerTile\",\"Table\",\"PowerBITile\",\"PowerBIPage\",\"SalesforceOrganization\",\"PresetWorkspace\",\"TableauDatasource\",\"PresetDataset\",\"TableauCalculatedField\",\"LookerFolder\",\"TableauWorksheet\",\"MetabaseQuestion\",\"AtlasBusiness Graph\",\"PresetChart\",\"PowerBITable\",\"LookerProject\",\"SnowflakePipe\",\"PowerBIReport\",\"SigmaDatasetColumn\",\"TableauDatasourceField\",\"TablePartition\",\"AtlasGlossaryTerm\",\"SigmaDataElementField\",\"Schema\",\"Database\",\"DbtColumnProcess\"]",
 "allowSearch": false,
 "maxStrLength": "100000000",
 "allowFiltering": true,
 "multiValueSelect": true,
 "showInOverview": false,
 "primitiveType": "groups",
 "isEnum": false,
 "customType": "groups"
 },
 "isNew": true
 },
 {
 "name": "",
 "displayName": "Informed",
 "description": "",
 "typeName": "array<string>",
 "isOptional": true,
 "cardinality": "SINGLE",
 "valuesMinCount": 0,
 "valuesMaxCount": 1,
 "isUnique": false,
 "isIndexable": true,
 "includeInNotification": false,
 "options": {
 "applicableEntityTypes": "[\"Asset\"]",
 "customApplicableEntityTypes": "[\"S3Object\",\"LookerLook\",\"TableauSite\",\"SnowflakeStream\",\"ModeCollection\",\"LookerDashboard\",\"PowerBIWorkspace\",\"Collection\",\"AtlasGlossaryCategory\",\"TableauFlow\",\"LookerView\",\"TableauProject\",\"LookerExplore\",\"ModeReport\",\"PowerBIColumn\",\"Query\",\"ColumnProcess\",\"SalesforceDashboard\",\"SalesforceObject\",\"BIProcess\",\"DbtModelColumn\",\"S3Bucket\",\"SigmaDataElement\",\"DataStudioAsset\",\"DbtProcess\",\"DbtModel\",\"PowerBIDataset\",\"Column\",\"DbtMetric\",\"TableauDashboard\",\"SigmaDataset\",\"LookerQuery\",\"APISpec\",\"MetabaseDashboard\",\"Process\",\"PowerBIDashboard\",\"APIPath\",\"ModeChart\",\"PowerBIDataflow\",\"SalesforceField\",\"GCSObject\",\"SalesforceReport\",\"View\",\"Folder\",\"TableauMetric\",\"MaterialisedView\",\"PresetDashboard\",\"PowerBIDatasource\",\"ModeWorkspace\",\"SigmaPage\",\"LookerField\",\"SigmaWorkbook\",\"PowerBIMeasure\",\"TableauWorkbook\",\"LookerModel\",\"MetabaseCollection\",\"ModeQuery\",\"GCSBucket\",\"LookerTile\",\"Table\",\"PowerBITile\",\"PowerBIPage\",\"SalesforceOrganization\",\"PresetWorkspace\",\"TableauDatasource\",\"PresetDataset\",\"TableauCalculatedField\",\"LookerFolder\",\"TableauWorksheet\",\"MetabaseQuestion\",\"AtlasBusiness Graph\",\"PresetChart\",\"PowerBITable\",\"LookerProject\",\"SnowflakePipe\",\"PowerBIReport\",\"SigmaDatasetColumn\",\"TableauDatasourceField\",\"TablePartition\",\"AtlasGlossaryTerm\",\"SigmaDataElementField\",\"Schema\",\"Database\",\"DbtColumnProcess\"]",
 "allowSearch": false,
 "maxStrLength": "100000000",
 "allowFiltering": true,
 "multiValueSelect": true,
 "showInOverview": false,
 "primitiveType": "groups",
 "isEnum": false,
 "customType": "groups"
 },
 "isNew": true
 }
 ],
 "displayName": "RACI", // (10)
 "options": { // (11)
 "logoType": "emoji",
 "emoji": "👪"
 }
 }
 ]
}
```

1. All custom metadata structural definitions must be specified within the `businessMetadataDefs` array.
2. Each structural definition must be defined with a category set to `BUSINESS_METADATA`.
3. Whatever name you provide for the structural definition will be replaced by a hashed-string generated name by the back-end.
4. Within the structural definition, you need to define each attribute inside the `attributeDefs` array.
5. You should leave the `name` of the attribute as an empty string. This will be generated by the back-end.
6. Instead, provide the name for the attribute (as it should appear in the UI) to the `displayName`.
7. There are various properties of each attribute that define how the attribute is validated and will behave in the UI. You can use the `multiValueSelect` to specify whether to allow multiple values for this attribute on a single asset (in this example multiple values will be allowed).
8. One of the properties that must be specified is the type of the custom attribute. In this example, we use an Atlan-specific custom type to capture users.
9. For each attribute that's to be newly created and added to the structure, set the `isNew` to `true`.
10. Specify the name of the custom metadata structure, as it should appear in the UI, to the `displayName`.
11. Finally, set options on the custom metadata structure to control its appearance—specifically the icon that should be used in the UI.

## Create custom metadata from object

Now that the object is built, this `customMetadataDef` object will have the required information for Atlan to create it.
You can then actually create the custom metadata definition in Atlan by calling the `create()` method on the object itself:

### Java

```java title="Create the custom metadata definition"
CustomMetadataDef response = customMetadataDef.create(client); // (1)
```

1. The `create()` operation will actually create the custom metadata definition within Atlan, including all the attributes that were defined as part of it. Because this operation will persist the structure in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.

### Python

```python title="Create the custom metadata definition"
from pyatlan.client.atlan import AtlanClient

client = AtlanClient()
response = client.typedef.create(cm_def) # (1)
```

1. The `typedef.create()` operation will actually create the custom metadata definition within Atlan, including all the attributes that were defined as part of it.

### Kotlin

```kotlin title="Create the custom metadata definition"
val response = customMetadataDef.create(client) // (1)
```

1. The `create()` operation will actually create the custom metadata definition within Atlan, including all the attributes that were defined as part of it. Because this operation will persist the structure in Atlan, you must [provide it an `AtlanClient`](https://docs.atlan.com/llms/platform/python/set-up-sdk/llms.txt) through which to connect to the tenant.

### Raw REST API

:::tip[Creation implicit in step above]
The actual creation of the custom metadata structure is implicit in the example above.
:::
Now that the custom metadata structure has been created, you can [set its values per asset](https://docs.atlan.com/llms/platform/python/add-custom-metadata/llms.txt).

## Limit applicability of attribute

You can also limit the assets the custom metadata applies to in Atlan. Anywhere you create an attribute definition, you can:

### Java

```java title="Limit applicability of an attribute"
AttributeDef responsible = AttributeDef.of(client, "Responsible", // (1)
 AtlanCustomAttributePrimitiveType.USERS,
 false);
responsible = responsible.toBuilder() // (2)
 .options(responsible.getOptions().toBuilder() // (3)
 .clearApplicableConnections() // (4)
 .clearApplicableAssetTypes()
 .clearApplicableGlossaries()
 .clearApplicableGlossaryTypes()
 .applicableConnection("default/snowflake/1234567890") // (5)
 .applicableAssetType(Database.TYPE_NAME) // (6)
 .applicableBusiness Graph(Business Graph.findByName("Example").getQualifiedName()) // (7)
 .applicableGlossaryType(GlossaryTerm.TYPE_NAME) // (8)
 .build()) // (9)
 .build(); // (10)
```

1. We still recommend creating the attribute using the `Attribute.of()` factory method. This ensures all required settings are configured based on the type of the attribute.
2. You can then clone the attribute into a mutable form using `toBuilder()`.
3. Set the `options` on this clone to change its applicability. You can use the `toBuilder()` on the options themselves to get a mutable clone of the options that have already been setup by the `AttributeDef.of()` factory method.
4. By default, the `AttributeDef.of()` method will make sure a custom metadata attribute applies to all assets. To limit its applicability, you need to remove these "grants" by clearing out:

- Connections the custom metadata attribute applies to (by default, all assets in all connections that existed when the attribute was created will be capable of using this custom metadata attribute).
 - Asset types the custom metadata attribute applies to (by default, all asset types will be capable of using this custom metadata attribute).
 - Glossaries the custom metadata attribute applies to (by default, all objects in a glossary that existed when the attribute was created will be capable of using this custom metadata attribute).
 - Business Graph asset types the custom metadata applies to (by default, glossaries, terms and categories are capable of using this custom metadata attribute).

5. You can chain any number of `applicableConnection()` calls to specify the `qualiedName`s of connections. The custom metadata attribute will only be available to assets within these connections.

 :::tip[To use all connections]
To select all connections, instead chain `.applicableConnections(Connection.getAllQualifiedNames())`.
 :::
6. You can chain any number of `applicableAssetType()` calls to specify the types of assets for the custom metadata attribute. The custom metadata attribute will only be available to assets of these types, within the connections specified in the line above.

:::tip[To use all asset types]
To select all asset types, instead chain `.applicableAssetTypes(AttributeDefOptions.ALL_ASSET_TYPES)`.
 :::
7. You can chain any number of `applicableBusiness Graph()` calls to specify the `qualifiedName`s of glossaries. The custom metadata attribute is only available to assets within these glossaries.

 :::tip[To use all glossaries]
To select all glossaries, instead chain `.applicableGlossaries(Business Graph.getAllQualifiedNames())`.
 :::
8. You can chain any number of `applicableGlossaryType()` calls to specify the types of glossary assets for the custom metadata attribute. The custom metadata attribute will only be available to glossary assets of these types, within the glossaries specified in the line above.

 :::tip[To use all glossary asset types]
To select all glossary asset types, instead use `.applicableGlossaryTypes(AttributeDefOptions.ALL_GLOSSARY_TYPES)`.
 :::
9. You then need to build all of these options.
10. And finally you need to build the changes back into the attribute definition. You can then use the attribute definition (`responsible` in this example) as you would any other attribute definition, for example passing it to the chained `.attributeDef()` as part of `CustomMetadataDef.creator()` shown earlier.

### Python

:::warning[Coming soon]
:::

### Kotlin

```java title="Limit applicability of an attribute"
var responsible = AttributeDef.of(client, "Responsible", // (1)
 AtlanCustomAttributePrimitiveType.USERS,
 false)
responsible = responsible.toBuilder() // (2)
 .options(responsible.options.toBuilder() // (3)
 .clearApplicableConnections() // (4)
 .clearApplicableAssetTypes()
 .clearApplicableGlossaries()
 .clearApplicableGlossaryTypes()
 .applicableConnection("default/snowflake/1234567890") // (5)
 .applicableAssetType(Database.TYPE_NAME) // (6)
 .applicableBusiness Graph(Business Graph.findByName("Example").qualifiedName) // (7)
 .applicableGlossaryType(GlossaryTerm.TYPE_NAME) // (8)
 .build()) // (9)
 .build() // (10)
```

1. We still recommend creating the attribute using the `Attribute.of()` factory method. This ensures all required settings are configured based on the type of the attribute.
2. You can then clone the attribute into a mutable form using `toBuilder()`.
3. Set the `options` on this clone to change its applicability. You can use the `toBuilder()` on the options themselves to get a mutable clone of the options that have already been setup by the `AttributeDef.of()` factory method.
4. By default, the `AttributeDef.of()` method will make sure a custom metadata attribute applies to all assets. To limit its applicability, you need to remove these "grants" by clearing out:

- Connections the custom metadata attribute applies to (by default, all assets in all connections that existed when the attribute was created will be capable of using this custom metadata attribute).
 - Asset types the custom metadata attribute applies to (by default, all asset types will be capable of using this custom metadata attribute).
 - Glossaries the custom metadata attribute applies to (by default, all objects in a glossary that existed when the attribute was created will be capable of using this custom metadata attribute).
 - Business Graph asset types the custom metadata applies to (by default, glossaries, terms and categories are capable of using this custom metadata attribute).

5. You can chain any number of `applicableConnection()` calls to specify the `qualiedName`s of connections. The custom metadata attribute will only be available to assets within these connections.

 :::tip[To use all connections]
To select all connections, instead chain `.applicableConnections(Connection.getAllQualifiedNames())`.
 :::
6. You can chain any number of `applicableAssetType()` calls to specify the types of assets for the custom metadata attribute. The custom metadata attribute will only be available to assets of these types, within the connections specified in the line above.

:::tip[To use all asset types]
To select all asset types, instead chain `.applicableAssetTypes(AttributeDefOptions.ALL_ASSET_TYPES)`.
 :::
7. You can chain any number of `applicableBusiness Graph()` calls to specify the `qualifiedName`s of glossaries. The custom metadata attribute is only available to assets within these glossaries.

 :::tip[To use all glossaries]
To select all glossaries, instead chain `.applicableGlossaries(Business Graph.getAllQualifiedNames())`.
 :::
8. You can chain any number of `applicableGlossaryType()` calls to specify the types of glossary assets for the custom metadata attribute. The custom metadata attribute will only be available to glossary assets of these types, within the glossaries specified in the line above.

 :::tip[To use all glossary asset types]
To select all glossary asset types, instead use `.applicableGlossaryTypes(AttributeDefOptions.ALL_GLOSSARY_TYPES)`.
 :::
9. You then need to build all of these options.
10. And finally you need to build the changes back into the attribute definition. You can then use the attribute definition (`responsible` in this example) as you would any other attribute definition, for example passing it to the chained `.attributeDef()` as part of `CustomMetadataDef.creator()` shown earlier.

### Raw REST API

:::warning[Coming soon]
:::
:::tip[Applicability is combined across connections and glossaries]
If you specify both connections (and asset types) and glossaries (and glossary types), then the custom metadata attribute will be available across both data assets in those connections and glossary objects in those glossaries. In other words, these options are **not** mutually exclusive, but are combined.
:::

---
