Hello, jeremy.tammik.
The method I've been using involves creating shared parameters and storing data using IUpdater.
The workflow is as follows:
- When the application is launched, collect current user's name.
- Subscribing to DocumentOpened, DocumentCreated, FamilyLoadingIntoDocument, and ElementTypeDuplicating events, check for the existence of a shared parameter with a specific GUID and name. If parameter doesn't exist, create parameter and binds it.
- subscribe Element.GetChangeTypeElementAddition to use IUpdater for adding the user's name to the Creator.
- subscribe Element.GetChangeTypeGeometry to use IUpdater for adding the user's name to the Modifyer.
The following image is the result of my work.

I have some questions regarding the suggested extensible storage approach:
Will the data stored in extensible storage be displayed to end-users in a manner similar to shared parameters, as shown in the image?
- Can data updates be achieved with extensible storage by subscribing to events like Element.GetChangeTypeAny(), similar to how it's done with IUpdater? Or should I subscribe to application.ControlledApplication.DocumentChanged with Transaction?
- I need to apply extensible storage to all elements in a Revit document. Is this possible?
I've only been working with the Revit API for about a week, so my knowledge is still limited. Please advise.