Python Ghost API Example: How I'm Using It to Automate My Blog (The Simple Way)
Look, I'm not a developer. I drive Uber during the day and futz around with code at night, mostly by Googling "how do I make this thing work." But here's the thing — when you're trying to build affiliate sites fast, automating your publishing workflow saves you hours every week. That's why I started messing with the Ghost API in Python.
If you've never touched Ghost's API before, don't panic. It's actually one of the friendlier APIs I've worked with. And if I can figure it out with one eye and a 2 AM coffee, you can too.
What the Ghost API Actually Does (And Why You Might Need It)
Ghost is a content management system — basically a cleaner, faster alternative to WordPress if you want to publish blog posts and newsletters. The API lets you do programmatically what you'd normally do by clicking around in the dashboard: create posts, update them, delete them, fetch your published content.
For me, the real value is automating bulk content operations. I'm publishing research roundups, pulling data from multiple sources, and tagging posts for my affiliate niches. Doing that manually 3 times a week? That's time I'm not sleeping, and sleep is scarce.
The Ghost API works with authentication tokens. You'll need an Admin API key from your Ghost site, and then you can make requests to endpoints like /posts, /tags, and /authors. Python makes this dead simple with the requests library.
Your First Python Ghost API Example
Here's the skeleton I use. Nothing fancy — just enough to fetch your published posts:
import requests
import json
GHOST_URL = "https://yoursite.ghost.io"
ADMIN_API_KEY = "your_admin_api_key_here"
def get_posts():
url = f"{GHOST_URL}/ghost/api/v3/admin/posts/"
headers = {
"Authorization": f"Ghost {ADMIN_API_KEY}"r> }
response = requests.get(url, headers=headers)
if response.status_code == 200:
posts = response.json()["posts"]
return posts
else:
print(f"Error: {response.status_code}")
return None
if __name__ == "__main__":
posts = get_posts()
for post in posts:
print(f"Title: {post['title']} | Status: {post['status']}")
That's it. Run this, and you'll get back a list of all your posts with their metadata. It's boring, but it works.
Creating Posts Programmatically (The Reason I Actually Use This)
Fetching data is fine, but creating posts is where the time savings happen. Here's how I'm automating post creation for my research roundup posts:
def create_post(title, html_content, tags=None):
url = f"{GHOST_URL}/ghost/api/v3/admin/posts/"
headers = {
"Authorization": f"Ghost {ADMIN_API_KEY}",
"Content-Type": "application/json" }
payload = {
"posts": [
{
"title": title,
"html": html_content,
"status": "draft",
"tags": tags or []
}
]
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code == 201:
return response.json()["posts"][0]
else:
print(f"Failed: {response.status_code} - {response.text}")
return None
Notice I'm setting "status": "draft". That's intentional — I never auto-publish. I create drafts, review them, tweak them, then publish manually. That's the line between "useful automation" and "garbage posts that tank your SEO."
The Real Talk: When to Use This (And When Not To)
The Ghost API is genuinely useful if you're:
- Bulk-updating post metadata (tags, featured images, etc.)
- Creating templated content (research roundups, link roundups)
- Pulling your published posts into a database for analysis
- Building a custom publishing workflow
It's not useful if you're hoping to automate the actual writing part. That's on you. I still write every post myself — the API just saves me from clicking "Create Post" fifty times a week.
The real money comes from content quality, not publishing speed. The API is just a lever that saves time so I can focus on writing better stuff.
Where to Go From Here
Ghost's official docs are solid — hit up ghost.org/docs/api and you'll find the full endpoint reference. The authentication is the trickiest part, and once you've got that working, everything else is just standard REST API stuff.
Start with fetching your posts. Get comfortable with the response format. Then mess around with creating drafts. Don't jump straight into automated publishing unless you're 100% sure you know what you're doing.
I'm still learning this myself. But so far, it's cut my administrative overhead in half. At my pace, that's 5–10 hours a week I can spend on actual content or running passengers. And right now, that matters.
Watch the real numbers at jims.one — I'm not pretending this is easy.