I personally think most API documentation is lame and either leaves critical behavior qualities unspecified, or don't comment when standard assumptions may be broken. One example is not documenting object lifespans. Another example is that you'd normally expect setting a property and then immediately getting that property would round-trip. In other words, the value you set is the value you get back. But there are cases where this isn't true, and they should be called out.

    Document properties that don't round-trip, and explain why they don't round-trip.

Imagine you have a class with that has some read/write property. Eg, C# code like this:
    class Foo {
        public T MyProp { get { ... }; set {...}; }

So if you use it like:
    void DoStuff(Foo f , T val) {        
        f.MyProp = val;
        Debug.Assert(f.MyProp == val);      

Then, you'd expect that assert never fires. This is very straightforward, especially considering that:
1) the property and value are the same type, so there isn't any type coercion. It's not like there's a float-to-int truncation issue.
2) no other members are called on f, so it's not like another operation is changing MyProp from underneath us.
3) we're doing the 'set' first, and then the 'get'. This is significant because calling the 'set' first forces the property into a known state and thus avoids the case where 'get' would catch the property in an undefined state.

Why are round-trippable properties important?
It's the intuitive expectation and not doing so will confuse your library users and cause subtle bugs (I give a real example below). After all, fields round-trip, and it's reasonable to expect properties to have the same semantics as fields. Consider that FXCop has a rule to change public fields to public properties.

Imagine you have a text property. Should this:
    int Test1(Foo f , T val) {        
        int x = Calculate(val);
        f.MyProp = val;
        return x;             

and this:
    int Test2(Foo f , T val) {        
        f.MyProp = val;
        int x = Calculate(f.MyProp);
        return x;             

really return two different values? It's reasonable to expect  that Test1 and Test2 would behave the same way.

Round-tripping properties also allow you to build stronger invariants and add stronger asserts. For example, suppose you have a Text property that round-trips.  You may write an Append() function like so:
    void Append(Foo f, string textToAppend) {
        int lenStart = f.Text.Length;
        f.Text += textToAppend;
        Debug.Assert(fText.Length = lenStart + textToAppend.Length); // <-- only valid if Text property round trips.

If Text didn't round-trip, you couldn't add the assert.

Why might a property not round-trip?
The getter and setter are arbitrary functions and so in general, can do anything they please. Languages like C# can't force the getters and setters to live up to any semantics. Imagine a property like:
    public T MyEvilProp { set { /*nop*/; } get { return new T(); }}
that is clearly not round-trippable! This sort of behavior is just evil and should be avoided.

The only legitimate reason I've found for not round-tripping is when a property round-trips to the same "logical" value, but represented in a different physical way. For eg,  perhaps you have a string property representing XML. The object internally stores the XML in some document structure that doesn't track whitespace. Thus setting and getting the xml via a string will be different because the getter will have all the whitespace stripped out.

What's a real example?
I recently hit this with the TextBoxBase.Text property. That lets you get or set the text contents of a TextBox or RichTextBox. However, empirically, when you set the text, it strips out all the '\r' characters. (I don't know what other filtering it may do on things like non-printable characters). This becomes very important with RichTextBox, because it has formatting commands that take character offsets. Suppose you wanted to write a helper function like:
    InsertText(Color c, string text, int characterIndex)
which injects a string 'text' into the RichTextBox at the given character index and marks it the given color C. To colorize with RichTextBox, you need to call something like:
    box.Select(offset, length);
    box.SelectionColor= c;
Where Select() will mark a region starting at the given character offset and of the given length of characters, and then SelectionColor will set the color for the given selected range.  Intuitively, the length parameter to Select() would be text.Length, but you can't use that because the input string may get filtered and doesn't round-trip. If text contains a '\r', that gets stripped out, and so now text.Length would be 1 too large.