This blog used to run on WordPress. It now runs on Ghost, and I migrated it almost entirely through APIs. No clicking through import wizards. Here's how, and the sharp edges.
Exporting from WordPress
The cleanest path is the official @tryghost/migrate tool, which reads the WordPress REST API and produces a Ghost-importable bundle (posts, pages, tags, authors, and downloaded images):
migrate wp-api --url https://example.com --pages trueFirst gotcha: the tool needs Node 22+ (it uses the built-in node:sqlite module). Node 20 throws ERR_UNKNOWN_BUILTIN_MODULE.
Importing into Ghost
Second gotcha: don't feed the zip to Ghost's importer. Extract the ghost-import.json and POST that to /ghost/api/admin/db/. The zip silently imports nothing. Images get copied into Ghost's content folder separately.
The 2FA wall
Ghost 5 emails a verification code on admin sign-in. With no SMTP configured yet, the session endpoint just returns 500. If you're automating against a fresh install, disable staffDeviceVerification until mail is wired up.
The rest, editing posts and pages, is all ?source=html on the Admin API, which converts your HTML into Ghost's native format. Past the gotchas, Ghost is a pleasant thing to script against.