I Build A Thing

Reference

API docs

Auth

Every endpoint requires a Bearer token.

Authorization: Bearer <your_api_key>
Base URL: https://blog.ibuildathing.com

Endpoints

GET /api/posts

List posts. Optional filters: ?author=chinat|xisen, ?published=true|false, ?limit=N. Returns { count, posts }.

GET /api/posts?slug=<slug> or GET /api/posts/<slug>

Fetch one post. 404 if missing.

POST /api/posts

Create or upsert. Required: slug, title, author, session_date, content_md. Optional: excerpt, published. Same slug posted twice updates in place.

PATCH /api/posts/<slug> or PUT /api/posts/<slug>

Partial update. Only fields you pass are changed.

DELETE /api/posts/<slug>

Delete by slug. 404 if already gone.

Schema

type Author = 'chinat' | 'xisen';

type Post = {
  id: string;             // uuid
  slug: string;           // url-safe, unique
  title: string;
  author: Author;
  session_date: string;   // YYYY-MM-DD (mastermind session)
  content_md: string;     // markdown body
  excerpt: string | null;
  published: boolean;
  created_at: string;
  updated_at: string;
};

Quickstart

# list all posts
curl -H "Authorization: Bearer $API_KEY" \
  https://blog.ibuildathing.com/api/posts

# create a draft
curl -X POST -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "slug": "2026-04-19-xisen-pulse-security",
    "title": "What Pulse leaks when it works",
    "author": "xisen",
    "session_date": "2026-04-19",
    "content_md": "# body\n\n...",
    "excerpt": "One-liner hook.",
    "published": false
  }' \
  https://blog.ibuildathing.com/api/posts

# publish later
curl -X PATCH -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"published": true}' \
  https://blog.ibuildathing.com/api/posts/2026-04-19-xisen-pulse-security

# delete
curl -X DELETE -H "Authorization: Bearer $API_KEY" \
  https://blog.ibuildathing.com/api/posts/2026-04-19-xisen-pulse-security

Errors

  • 401 — missing Authorization header
  • 403 — invalid API key
  • 400 — invalid JSON, missing required fields, bad author
  • 404 — post not found

Notes

  • Slug convention: YYYY-MM-DD-<author>-<short-kebab>.
  • published: false hides from / but stays readable by slug in the admin UI.
  • CRUD is idempotent where possible: POST with an existing slug updates; PATCH with unchanged fields no-ops.
  • Repo: cyu60/blog-ibuildathing
  • Integration tests: scripts/test-api.sh (20 assertions, green on prod).