Vim gives you buffer, window, cursor and range, plus eval and command. The eval/command stuff is a "shim", insofar as you have to wrap them yourself if you want more programmatic access; like you'd have to do `def getcwd(): vim.eval('getcwd()')` But for a lot of what you want to do, you're messing with buffer/window/cursor. I wouldn't call it a full-featured scripting API, and certainly Neovim's is better, but your posts suggested all the scripting API was was just an entry point to ex commands. There's a lot more than that, to the extent that it covers most of what you want to do.
Python example:
Ref: https://geoff.greer.fm/2015/01/15/why-neovim-is-better-than-...