Admin API
12 admin-only endpoints for platform operations and publishing: KPI dashboards, user support lookups, manual plan grants, profile search index maintenance, and admin blog publishing/import workflows.
Admin Access
All admin endpoints require a bearer JWT for a user with is_admin.
These are high-trust operational surfaces. The dashboard and CLI both use the same backend service truth, so you should automate them through /v1/admin/* instead of dashboard HTML routes.
Admin Operations
6Return the admin KPI workspace snapshot.
Response
| Field | Type | Required | Description |
|---|---|---|---|
| window_days | integer |
Yes | Normalized KPI lookback window* |
| users | object |
Yes | User and plan metrics* |
| billing | object |
Yes | Billing and conversion metrics* |
Search support users with entitlement and billing filters.
Response
| Field | Type | Required | Description |
|---|---|---|---|
| items | array |
Yes | Support search rows* |
| result_count | integer |
Yes | Returned row count* |
| filters | object |
Yes | Applied query filters* |
Return one support drill-down view.
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| username | string |
Yes | Target username* |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| user | object |
Yes | Core user summary* |
| subscriptions | array |
Yes | Historical subscription rows* |
| manual_grants | array |
Yes | Manual entitlement history* |
| timeline | array |
Yes | Operational events timeline* |
Grant manual Pro access to one user.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| username | string |
Yes | Target username* |
| reason | string |
Yes | Audit reason* |
| expires_on | date |
No | Optional YYYY-MM-DD expiry |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| grant_id | uuid |
Yes | Created grant ID* |
| message | string |
Yes | Operator-safe summary* |
Revoke one active manual grant.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| grant_id | uuid |
Yes | Grant to revoke* |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| grant_id | uuid |
Yes | Revoked grant ID* |
| revoked_at | datetime |
Yes | Revocation timestamp* |
| message | string |
Yes | Operator-safe summary* |
Re-embed selected or all user profiles in-process.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| usernames | array |
No | Optional target usernames |
| drop_existing | boolean |
No | Delete current embeddings before rebuilding |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| users | array |
Yes | Per-user result rows* |
| success | integer |
Yes | Successful rebuild count* |
| failed | integer |
Yes | Failed rebuild count* |
| total_docs | integer |
Yes | Re-embedded document total* |
Admin Blog Publishing
6List admin blog posts with optional status, search, and tag filters.
Response
| Field | Type | Required | Description |
|---|---|---|---|
| items | array |
Yes | Admin blog summary rows* |
| title | string |
Yes | Human-readable post title* |
| status | string |
Yes | Draft or published state* |
Return one full admin-visible blog post.
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| post_id | integer |
Yes | Target blog post ID* |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| content_md | string |
Yes | Canonical markdown source* |
| featured_image_url | string |
No | Optional hero image URL |
| meta_description | string |
No | Optional SEO description |
Create one admin blog post from canonical markdown content.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| title | string |
Yes | Blog post title* |
| summary | string |
Yes | Card and sharing summary* |
| content_md | string |
Yes | Canonical markdown content* |
| status | string |
No | Draft or published |
| tags | string |
No | Comma-separated tags |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer |
Yes | Created post ID* |
| slug | string |
Yes | Unique public slug* |
| reading_time_minutes | integer |
Yes | Rendered reading-time estimate* |
Update one admin blog post and preserve shared slug/publish behavior.
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| post_id | integer |
Yes | Target blog post ID* |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| title | string |
Yes | Blog post title* |
| summary | string |
Yes | Card and sharing summary* |
| content_md | string |
Yes | Canonical markdown content* |
| status | string |
No | Draft or published |
| featured_image_url | string |
No | Optional hero image URL |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| slug | string |
Yes | Updated unique public slug* |
| updated_at | datetime |
Yes | Last mutation timestamp* |
| published_at | datetime |
No | First publish timestamp |
Delete one admin blog post.
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| post_id | integer |
Yes | Target blog post ID* |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| ok | boolean |
Yes | Deletion success flag* |
| id | integer |
Yes | Deleted post ID* |
| slug | string |
Yes | Deleted public slug* |
Batch import blog posts from one shared structured payload.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| items | array |
Yes | List of blog post objects using the same create contract* |
| items[].title | string |
Yes | Blog post title* |
| items[].summary | string |
Yes | Blog post summary* |
| items[].content_md | string |
Yes | Canonical markdown content* |
Response
| Field | Type | Required | Description |
|---|---|---|---|
| created_count | integer |
Yes | Number of created posts* |
| items | array |
Yes | Created blog post detail payloads* |