Base URL:
http://localhost:8002 (local worker — the only supported deployment today).
Status: Alpha. Surface area is broad but not contractually stable across releases.
Last updated: 2026-05-23.Jump to a group
Authentication
OAuth 2.1 Client Credentials grant.
poindexter setup provisions the
initial CLI client.Tasks
Create, list, approve, and reject content tasks. The lifecycle is
pending → in_progress → awaiting_approval.Posts
Public post list + search, plus authenticated update / soft-delete.
Settings
Read and update
app_settings rows over the REST surface.Overview
Reference for the REST API exposed by the Poindexter worker. All routes are under/api/* — there is no URL-based versioning.
Stability warning. The API is not yet considered stable. Route shapes change between releases, especially around task metadata. Pin to a specific commit until the first tagged release.
API Principles
- RESTful: Standard HTTP methods and status codes
- JSON: All requests/responses in JSON format
- Authentication: Bearer token in Authorization header
- Pagination: Limit/offset for list endpoints
Authentication
OAuth 2.1 Client Credentials
All protected endpoints require an OAuth-issued JWT in the Authorization header:poindexter setup provisions an initial CLI OAuth client on first
run. Mint a fresh JWT for ad-hoc curl tests with:
poindexter auth migrate-*
helper. The legacy static-Bearer fallback was removed in
Glad-Labs/poindexter#249.
Development Bypass
Whendevelopment_mode is true in app_settings, the literal
token dev-token is accepted as a Bearer credential:
development_mode=false by default — the
bypass is dormant unless an operator explicitly flips the flag.
Public Endpoints (no auth required)
GET /api/health— system healthGET /api/posts— published post listGET /api/posts/{slug}— single post by slugGET /api/categories— category listGET /api/posts/search?q=...— post search
Core Endpoints
System Health
GET /api/health
services/task_executor.py was deleted 2026-05-16 in the Prefect Stage 4 cutover; dispatch is now Prefect-native and there is no task_executor component in the health payload.)
Tasks
GET /api/tasks
List tasks (requires auth). Supports ?status=pending&limit=20&offset=0.
POST /api/tasks
Create a content task.
pending → in_progress → awaiting_approval (or rejected if QA fails).
POST /api/tasks/{task_id}/approve
Approve a task for publishing. Publishes immediately unless
publish_at is set.
POST /api/tasks/{task_id}/reject
Reject a task with feedback.
Posts
GET /api/posts
List published posts. Public (no auth).
GET /api/posts/{slug}
Get a single post by slug. Public.
GET /api/posts/search?q={query}
Search posts by title/content. Public.
Settings
GET /api/settings
List all app_settings (requires auth).
PUT /api/settings/{key}
Update a setting.
Other Endpoints
| Group | Method + Path | Auth | Purpose |
|---|---|---|---|
| Categories | GET /api/categories | public | List all content categories with post counts |
| Categories | GET /api/categories/{slug} | public | Single category metadata + posts |
| Posts | GET /api/posts | public | Paginated post list (status, category, limit, offset query) |
| Posts | GET /api/posts/{slug} | public | Single published post by slug |
| Posts | GET /api/posts/search?q=... | public | Full-text + pgvector similarity search |
| Posts | GET /api/posts/preview/{preview_token} | token | Preview a pre-publish post using a signed one-shot token |
| Posts | PATCH /api/posts/{post_id} | bearer | Update post metadata (title, tags, SEO fields) |
| Posts | DELETE /api/posts/{post_id} | bearer | Soft delete (archive) a post |
| Tags | GET /api/tags | public | List all tags with post counts |
| Memory | GET /api/memory/search?q=... | bearer | Semantic search via pgvector (top-k cosine similarity) |
| Memory | GET /api/memory/stats | bearer | Embedding counts by source_table / writer |
| Pipeline | GET /api/pipeline/events | bearer | Live event stream (recent task transitions, with pagination) |
| Pipeline | GET /api/pipeline/events/task/{task_id} | bearer | Event history for a single task |
| Analytics | GET /api/analytics/views | bearer | Page view rollups (day, post_id, geo if configured) |
| Export | POST /api/export/rebuild | bearer | Trigger static JSON + RSS rebuild to R2 / configured storage |
| Media | GET /images/generated/{filename} | public | Serve a generated image-gen / Pexels image |
| Media | GET /episodes | public | List all podcast episodes |
| Media | GET /episodes/{post_id}.mp3 | public | Stream a podcast audio episode |
| Media | GET /episodes/{post_id}.mp4 | public | Stream a podcast video episode |
| Media | POST /generate/{post_id} | bearer | Regenerate audio/video for a specific post |
| Subscribers | GET /subscribers/count | public | Total opted-in newsletter subscribers |
| Subscribers | POST /subscribe | public | Double opt-in newsletter signup (captcha recommended) |
| Subscribers | POST /unsubscribe | public | One-click unsubscribe by token |
| Feed | GET /feed.xml | public | RSS 2.0 feed of published posts |
| Webhooks | POST /alertmanager | signed | Prometheus Alertmanager webhook receiver (routes to Discord) |
| Frontend | POST /revalidate-cache | bearer | Trigger Next.js ISR cache revalidation after publish |
| Frontend | GET /preview/{preview_token} | token | Server-rendered preview HTML for vision-gate QA |
/api is the REST surface. Media routes
(/episodes/*, /images/generated/*) and the RSS feed sit at the
server root without the /api prefix to match classic web
expectations.
Webhook security
POST /alertmanager verifies the Alertmanager webhook signature
(HMAC-SHA256, shared secret in app_settings.alertmanager_webhook_secret).
Invalid signatures are rejected with 401.
Preview tokens (/api/posts/preview/{token}, /preview/{token}) are
single-purpose signed tokens issued by the worker at post creation.
They expire after 24 hours and can only be used to read — never to
modify state.
Error Responses
400 validation, 401 missing/bad token,
404 not found, 500 server error.
Related Documentation
- Local Development Setup — full setup walkthrough
- Troubleshooting — production issues and fixes