I think a good API should allow custom IO and memory management hooks if it's applicable.
A typical example is you have your custom compressed archive format for data on disk and a third party library with a poor api wants to access data on disk and expects a path to a file where it can load its data.
This link has some good points:
http://gamearchitect.net/2008/09/19/good-middleware/