Benji wrote a pretty funny article exposing one of the main problems with bad APIs: trying to enable every single scenario at the wrong level of abstraction.
In other words, when your APIs get too complex, think whether you are not trying to enable scenarios for which assembly level programming would be much better suited. And if that’s the case, do your users a favor and leave these scenarios to the assembler.
Note: this post has been updated. I mistakenly thought Joel Spolsky wrote the original article.