The good news is that SharePoint has a full-featured API layer that opens up access to...just about everything within the system.
The bad news is that the API can be a challenge at times due to things like naming inconsistencies between it and the user interface (e.g. SPSite really means "site collection" or instead of PublishingWeb.WelcomePage it's PublishingWeb.DefaultPage) and simply the fact that the surface layer of the API is BIG.
One of the hardest things to get right is figuring out when to call Dispose() on objects returned by the API. If you neglect to invoke Dispose() when needed, serious memory leaks will occur. On the other hand, calling Dispose() when you're not supposed to may (in the words of the Microsoft documentation) "cause the SharePoint object model to behave unpredictably or fail".
Now, there are a large number of blog posts, magazine articles, books, etc out there that help you figure out this Dispose() puzzle. But, this relatively new article article by Roger Lamb is the best that I've seen. It covers not only the "normal" patterns but also some pretty tricky edge cases as well. As a bonus, it also addresses not just core WSS functionality but also other namespaces (e.g. publishing) as well.