Sigh.. 😕 I truly believe we have made a disservice to our Revit users when we named UniqueId the way we did, for it seems to keep on being misunderstood in spite of many of us trying to shed more light into the problems with identifying model elements. I'll try again to straighten up some of the confusion, and my hope is that I'll make it better, not worse.
Erik, I think you may actually be on the point in your very first sentence:
ElementId was a stable way of finding elements in a document, then I learned that UniqueId was the proper way.
The most important part of the sentence is the "a" in "a document", since the purpose of both kinds of IDs is to identify elements in a single model, not in a bunch of models. In other words: none of the IDs can uniquely identify elements across unrelated documents in spite of the name it was given to the UniqueID class. Universal uniqueness of identifiers is simply something that cannot be done. If one takes an existing file and makes a copy of it, no one would probably expect elements change their Ids in that copied file.
So, with that "universal uniqueness" hopefully out of our way, we have only two aspect to discuss:
Regular Ids (integers) can identify elements in a model uniquely as long as the model is not work-shared. It is because Revit does not change the Ids after they were issued, and it also always increments the Ids before assigning them to new elements. That means Ids are never reused. If an element is deleted, its Id will not be used for anything else.
In a work-shared environment, regular Ids cannot be stable, understandably. I'll demonstrate it in an example:
Consider two users, UA, and UB. One creates an empty central file. Then both users create their respective local files from it. Now, say UA creates a wall. It will be assigned Id = 1005 (for example). If UB also creates one wall it will also be given Id = 1005, since both users started off with the same file and Revit increments element Ids linearly. Let's continue: UA saves to central, thus her wall gets there first with its original Id (1005). If UB then syncs, first the wall from the other user will be brought in with it's original Id. Revit will notice that the same Id already exist locally. Since all elements must have unique Ids within a file, something's got to give; Revit takes the UB's wall and assigns it a new Id, say 1006 and uploads that wall to the central file. After UA gets the latest too, both users and the central file as well will have two walls with Ids 1005 and 1006, respectively.
I hope that makes sense. Let's go on with the second one.
Unique Ids (strings) can identify elements uniquely even in a work-shared file. What this basically means is that, unlike regular Ids which may collide when two local versions are merged together and thus one (or more) of the Ids must be re-issued (as I illustrated in the aforementioned example), Unique Ids do not collide, therefore they do not have to be reissued; they merge with no problem.
What that means in practice I'll again try to demonstrate on an example:
An external application creates a new Beam element in a local file. It takes and stores its unique Id - say is "ABCD-1234" (a string!!). Then the user goes on making more changes while his co-workers make even more changes in their local files. At some point they all sync with the central file. If, after that point in time the external application operating on the first user's computer asks for an element to be fetched by providing its UniqueId = "ABCD-1234", the application will obtain the very same Beam element, providing it still exists.
I think this should be the end of the story. Please note that I used the sample "ABCD-1234" value of an unique Ids on purpose, because I believe it is for the best if users do not try to understand what the parts of an unique Id are and how can one try to decipher it. Please keep in mind that it was not meant to be deciphered. No matter what Revit does internally with a unique Id, it has one and only purpose to Revit programmers (both internal and external, in fact) - it identifies an element in a work-shared model. Once you have an element's unique Id, you can use it to locate the element within the model.
One more note before I stop typing, mainly to address Erik's last question. Neither regular element Ids nor Unique Ids can safely identify elements across multiple unrelated documents. If there is someone who requires such a universal identification system for organizing elements in whatever models, that person/company would have to create some kind of a controlled database. I presume it would not be particularly an easy task.
Post Scriptum: A post too long? That's what holidays are for! 🙂
Arnošt Löbel