Admin API Reference
All admin endpoints require Authorization: Bearer <API_KEY>. See RBAC for role requirements.
All request bodies are validated using Pydantic schemas. Invalid input returns HTTP 400 with validation details.
Base URL: http://localhost:8000
Owner Profile
GET /api/admin/owner
Returns the owner profile or {} if not configured.
PUT /api/admin/owner
Create or update the owner profile.
{
"display_name": "string",
"slug": "string",
"email": "string",
"avatar_url": "string",
"bio": "string",
"tagline": "string",
"social_links": [{"platform": "string", "url": "string"}],
"theme_config": {"primary_color": "string", ...}
}
All fields are optional on update (partial updates supported).
Bot Config
GET /api/admin/bot
Returns the bot configuration or {} if not configured.
PUT /api/admin/bot
Create or update bot configuration.
{
"system_prompt": "string",
"greeting_message": "string",
"model_provider": "anthropic | openai | google-gla",
"model_name": "string",
"temperature": 0.7,
"enabled_tools": ["links", "products", "events", "booking", "newsletter", "faq", "portfolio"],
"quick_actions": [{"label": "string", "action": "string"}]
}
Links
| Method | Path | Description |
|---|---|---|
GET | /api/admin/links | List all links |
POST | /api/admin/links | Create link → 201 |
PUT | /api/admin/links/{id} | Update link |
DELETE | /api/admin/links/{id} | Delete link |
Create/Update body:
{
"title": "string",
"url": "string",
"icon": "string",
"description": "string",
"sort_order": 0,
"is_active": true
}
Products
| Method | Path | Description |
|---|---|---|
GET | /api/admin/products | List all products |
POST | /api/admin/products | Create product → 201 |
PUT | /api/admin/products/{id} | Update product |
DELETE | /api/admin/products/{id} | Delete product |
Create/Update body:
{
"title": "string",
"description": "string",
"price_cents": 0,
"currency": "USD",
"product_type": "course | book | digital",
"external_url": "string",
"image_url": "string",
"is_active": true
}
Events
| Method | Path | Description |
|---|---|---|
GET | /api/admin/events | List all events |
POST | /api/admin/events | Create event → 201 |
PUT | /api/admin/events/{id} | Update event |
DELETE | /api/admin/events/{id} | Delete event |
Create/Update body:
{
"title": "string",
"description": "string",
"start_time": "ISO 8601 datetime",
"end_time": "ISO 8601 datetime",
"timezone": "string",
"max_attendees": 0,
"is_active": true
}
Booking Slots
| Method | Path | Description |
|---|---|---|
GET | /api/admin/bookings/slots | List all slots |
POST | /api/admin/bookings/slots | Create slot → 201 |
PUT | /api/admin/bookings/slots/{id} | Update slot |
DELETE | /api/admin/bookings/slots/{id} | Delete slot |
Create/Update body:
{
"day_of_week": 1,
"start_time": "HH:MM:SS",
"end_time": "HH:MM:SS",
"duration_minutes": 30,
"is_active": true
}
day_of_week: 0 = Monday, 6 = Sunday.
FAQ
| Method | Path | Description |
|---|---|---|
GET | /api/admin/faq | List all entries |
POST | /api/admin/faq | Create entry → 201 |
PUT | /api/admin/faq/{id} | Update entry |
DELETE | /api/admin/faq/{id} | Delete entry |
Create/Update body:
{
"question": "string",
"answer": "string",
"category": "string",
"sort_order": 0,
"is_active": true
}
Portfolio
| Method | Path | Description |
|---|---|---|
GET | /api/admin/portfolio | List all items |
POST | /api/admin/portfolio | Create item → 201 |
PUT | /api/admin/portfolio/{id} | Update item |
DELETE | /api/admin/portfolio/{id} | Delete item |
Create/Update body:
{
"title": "string",
"description": "string",
"image_url": "string",
"link_url": "string",
"category": "string",
"sort_order": 0,
"is_active": true
}
Integrations
| Method | Path | Description |
|---|---|---|
GET | /api/admin/integrations | List all (credentials masked) |
POST | /api/admin/integrations | Create integration → 201 |
PUT | /api/admin/integrations/{id} | Update integration |
DELETE | /api/admin/integrations/{id} | Delete integration |
Create/Update body:
{
"provider": "google | gumroad | leanpub",
"credentials": "string",
"scopes": ["string"],
"is_active": true
}
GET responses include has_credentials: true/false instead of the raw credentials.
Public Endpoints
GET /api/bio
Returns the public bio page data (no auth required):
{
"owner": { "display_name": "...", "bio": "...", ... },
"links": [{ "title": "...", "url": "..." }],
"bot": { "greeting_message": "...", "quick_actions": [...] }
}
GET /health
{"status": "ok"}
Webhooks
| Method | Path | Description |
|---|---|---|
POST | /api/webhooks/gumroad | Gumroad purchase notification |
POST | /api/webhooks/leanpub | Leanpub purchase notification |
When CHATINBIO_GUMROAD_WEBHOOK_SECRET or CHATINBIO_LEANPUB_WEBHOOK_SECRET is configured, requests must include a valid HMAC-SHA256 signature in the x-gumroad-signature or x-leanpub-signature header. Unsigned/invalid requests return HTTP 401.
Error Responses
| Status | Meaning |
|---|---|
400 | Validation error — invalid request body (Pydantic) |
401 | Missing or invalid API key / webhook signature |
403 | Insufficient permissions for the requested action |
404 | Resource not found |
Error response format:
{"detail": "Human-readable error message", "status_code": 404}
Validation errors (400) include field-level details:
{
"status_code": 400,
"detail": "Validation failed",
"extra": [{"key": "title", "message": "Field required"}]
}