Dictionary
Use these endpoints to manage the attributes in a project's Dictionary, their namespaces, and the cache profiles that control how attribute values are cached.
All requests require the X-Project-Id header. Read access requires the Project viewer role and changes require the Project editor role. Read Permissions for details.
My workspace stages POST, PUT, PATCH, and DELETE requests, which return 202. They are validated and applied when the workspace is promoted.
Attributes
| Method | Path | Description |
|---|---|---|
GET | /api/dictionary/attributes | List the active attributes. |
GET | /api/dictionary/attributes/{fqn} | Get an active attribute by its fully qualified name. |
GET | /api/dictionary/attributes/id/{uid} | Get an attribute version by ID, including older versions. |
POST | /api/dictionary/attributes | Create an attribute. |
PATCH | /api/dictionary/attributes/{fqn} | Update an attribute. |
DELETE | /api/dictionary/attributes/{fqn} | Delete an attribute. |
GET | /api/dictionary/attributes/export | Export the attributes as a JSON file. |
POST | /api/dictionary/attributes/import | Import attributes from a JSON file. |
List attributes
GET /api/dictionary/attributes returns an array. You can narrow the list with the optional query parameters namespace, category, and type, which must match exactly. The list is not paginated.
Every attribute in a response is wrapped in an attribute object:
{
"attribute": {
"id": "0f7b5bd2-9d5f-45f0-a9b9-8c8d0f4a6a11",
"fqn": "resource.department",
"namespace": "resource",
"name": "department",
"description": "The department that owns the resource",
"category": "resourceCat",
"type": "string",
"readOnly": false,
"xacmlId": "resource.department",
"cacheProfile": { "name": "Default", "timeToLive": 0, "maxItems": 0 },
"createdAt": "2026-10-13T08:15:30Z",
"createdBy": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}
}
Create an attribute
curl -X POST "https://<authorization-hub-url>/api/dictionary/attributes" \
-H "Authorization: Bearer <access_token>" \
-H "X-Project-Id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"namespace": "resource",
"name": "department",
"type": "string",
"category": "resourceCat",
"description": "The department that owns the resource",
"cacheProfile": "Default"
}'
| Field | Required | Description |
|---|---|---|
namespace | Yes | Up to 255 characters. One or more segments separated by single dots. Letters, digits, and underscores only, starting with a letter or underscore. |
name | Yes | Up to 255 characters. Letters, digits, and underscores only, starting with a letter or underscore. |
type | Yes | The data type, such as string, integer, boolean, date, time, or dateTime. Same character rules as name. |
category | No | The attribute category, for example subjectCat, resourceCat, actionCat, or environmentCat. Same character rules as name. |
description | No | A description. |
xacmlId | No | The XACML identifier. Defaults to the fully qualified name. |
cacheProfile | No | The name of a cache profile. Defaults to Default. |
Namespaces, names, categories, and types cannot be reserved words. The reserved words are checked for each segment of a namespace.
The response is 201 with the attribute, and a Location header with its address. The Location value is relative to the Hub service, so it does not include the /api prefix.
Update an attribute
An update uses the application/merge-patch+json content type. Send only the fields to change. Fields you omit are kept, and description and category can be cleared by sending null.
curl -X PATCH "https://<authorization-hub-url>/api/dictionary/attributes/resource.department" \
-H "Authorization: Bearer <access_token>" \
-H "X-Project-Id: <project-id>" \
-H "Content-Type: application/merge-patch+json" \
-d '{"description": "Owning department"}'
An effective update creates a new version of the attribute with a new id and retires the previous one. Sending an update that changes nothing returns the existing attribute. An update that only changes the cacheProfile does not create a new version: the existing attribute keeps its id and is mapped to the new cache profile.
If xacmlId is not part of an update, it is reset to the attribute's fully qualified name. Include the xacmlId of attributes with a custom value in every update.
Delete an attribute
Deleting an attribute returns 204. The attribute is retired rather than removed, and its name can be reused. The three built-in environment attributes (Attributes.currentTime, Attributes.currentDate, and Attributes.currentDateTime) are read-only and cannot be updated or deleted.
Attribute errors
| Status | errorCode | Cause |
|---|---|---|
400 | INVALID_REQUEST | A field is missing or invalid. |
400 | INVALID_FQN | The fully qualified name has no namespace, which means that it does not contain a dot. |
400 | READ_ONLY_ATTRIBUTE_CANNOT_BE_EDITED, READ_ONLY_ATTRIBUTE_CANNOT_BE_DELETED | The attribute is read-only. |
404 | ATTRIBUTE_NOT_FOUND | The attribute does not exist. |
404 | CACHE_PROFILE_NAME_DOES_NOT_EXIST | The cache profile does not exist. |
409 | DUPLICATE_ATTRIBUTE | An attribute with this fully qualified name already exists. |
Export and import
GET /api/dictionary/attributes/export returns all active attributes, including the read-only ones, together with the cache profiles they use. The response is a JSON file, and its name is in the Content-Disposition header (attributes_<timestamp>.json).
{
"attributes": [
{
"id": "0f7b5bd2-9d5f-45f0-a9b9-8c8d0f4a6a11",
"namespace": "resource",
"name": "department",
"description": "The department that owns the resource",
"category": "resourceCat",
"type": "string",
"xacmlId": "resource.department",
"readOnly": false,
"cacheProfile": { "name": "Default" }
}
],
"cacheProfiles": [
{ "name": "Default", "timeToLive": 0, "maxItems": 0 }
]
}
POST /api/dictionary/attributes/import takes a multipart/form-data request with the file in a part named file:
curl -X POST "https://<authorization-hub-url>/api/dictionary/attributes/import" \
-H "Authorization: Bearer <access_token>" \
-H "X-Project-Id: <project-id>" \
-F "file=@attributes.json;type=application/json"
- The file must be in the export format. Unknown properties are rejected, and so are files that are not JSON, files with an empty (
null) entry, and cache profiles without aname. The message names the position of the entry. - Attributes are matched by fully qualified name. The
idin the file is never reused, andreadOnlyis ignored: imported attributes are always editable. - Cache profiles that already exist in the project are not changed. Missing ones are created.
The import returns 202 and stages the changes in your workspace. The body has the draftId, a summary (total, created, edited, and failed), and the items that were staged. Promote the workspace to apply them.
Import errors are IMPORT_SCHEMA_INVALID (the file does not match the expected format), IMPORT_MALFORMED_JSON, and IMPORT_UNSUPPORTED_FORMAT. Problems with the attributes themselves are reported when you promote the workspace. Read Import and export for the behavior in the interface.
Namespaces
| Method | Path | Description |
|---|---|---|
GET | /api/namespaces | List the namespaces used by the project's active attributes. |
The response is an array of strings, sorted alphabetically.
Cache profiles
| Method | Path | Description |
|---|---|---|
GET | /api/cache-profiles | List the cache profiles. |
GET | /api/cache-profiles/{name} | Get a cache profile by name. |
POST | /api/cache-profiles | Create a cache profile. |
PUT | /api/cache-profiles/{name} | Replace a cache profile. |
DELETE | /api/cache-profiles/{name} | Delete a cache profile. |
GET /api/cache-profiles accepts the optional query parameters name (matches profiles whose name contains the value, ignoring case), timeToLive, and maxItems (exact matches).
A cache profile has the following fields:
| Field | Required | Description |
|---|---|---|
name | Yes | The profile name. Names are unique, ignoring case. |
timeToLive | Yes | How long values are cached, in seconds. 0 or more. |
maxItems | Yes | The maximum number of cached values. 0 or more. |
{ "name": "Hourly", "timeToLive": 3600, "maxItems": 1000 }
- The profile named
Defaultcannot be renamed or deleted. - Deleting a profile moves the attributes that use it to the
Defaultprofile.
| Status | errorCode | Cause |
|---|---|---|
404 | CACHE_PROFILE_NAME_DOES_NOT_EXIST | The profile does not exist. |
409 | DUPLICATE_CACHE_PROFILE | A profile with this name already exists. |
409 | DEFAULT_CACHE_PROFILE_CANNOT_EDIT_NAME, DEFAULT_CACHE_PROFILE_CANNOT_DELETE | The Default profile cannot be renamed or deleted. |