I’m reading the ActivityPub spec here and it seems pretty fit for client-to-server communications. Yeah, it might be somewhat bulkier than your typical rest api, but it’s more universal, which begs the question: why do mastodon and lemmy both decided to implement custom (and incompatible) APIs for their clients to talk to the servers? Wouldn’t it be more straightforward if e.g. my voyager app talked ActivityPub to lemmy.world which then talked ActivityPub to lemmy.ml or something.
What am I missing?
You’re not wrong, Lemmy’s API is rather crudely documented. It’s not 1.0 yet and they have plenty of funding related milestones to hit before the end of the year, so they have good reason not to invest too much time, but the Lemmy API certainly needs some docs.
Alternatives on the Fediverse (Mastodon/Calckey/Akkoma/etc.) all have much better API docs. Lemmy and Kbin are relatively unfinished and unfortunately that comes with all the downsides.
However, Lemmy has an SDK available (that you may need to generate). The ActivityPub C2S API has gems like:
“How do I log in” and “how do I upload an image” isn’t specified by the C2S API at all. All you have is suggestions. That makes the entire protocol kind of useless to implement in its current state. You can pick a backend implementation you like and write your application for that, but that does come at the cost of breaking all other clients.
There are a few C2S implementations. You can use Pleroma and forks or Fedbox together with a client like Andstatus if you want to use C2S. The main design of AndStatus is oriented around Twitter/Mastodon more than anything, but it does allow reading threaded comments (like on Lemmy).