API
Web docs for the current API contract.
Example tenant API base: /profiles/johnny-butler/api/v1
API v1
Base path: /profiles/:slug/api/v1
This API mirrors the multitenant public profile app. Each request is scoped to a published profile slug.
Example base path:
/profiles/bravo-studio/api/v1
Authentication
- If the API v1 key is absent from Rails credentials, v1 endpoints are open.
- If the API v1 key is present in Rails credentials, send header
X-API-Key: <value>. - Invalid or missing key returns
401with:
{
"error": {
"code": "unauthorized",
"message": "Unauthorized"
}
}
Error Contract
Error responses use:
{
"error": {
"code": "<machine_code>",
"message": "<human_message>"
}
}
Malformed chat payloads return 400 with:
{
"error": {
"code": "invalid_request",
"message": "Invalid request payload"
}
}
Unknown profile slugs return the normal Rails 404.
Endpoints
GET /profiles/:slug/api/v1/content/profile
Returns the published profile summary for that account.
Response:
{
"data": {
"name": "Bravo Studio",
"tagline": "Design systems and shipping support",
"bio": "Bravo Studio is another customer account fixture.",
"location": "Remote"
}
}
GET /profiles/:slug/api/v1/content/case_studies
Returns published case studies for that account.
Response:
{
"data": [
{
"title": "Platform modernization program",
"summary": "Introduced release guardrails; improved delivery visibility; reduced ops overhead.",
"outcome": "Reduced release risk for customer-facing changes.",
"slug": "platform-modernization-program"
}
]
}
GET /profiles/:slug/api/v1/content/posts
Returns published writing posts for that account.
Response:
{
"data": [
{
"title": "Shipping practical software in small slices",
"summary": "Notes on release discipline and pragmatic delivery.",
"date": "2026-03-01",
"slug": "shipping-practical-software-in-small-slices"
}
]
}
GET /profiles/:slug/api/v1/content/experiences
Returns published experience entries for that account.
Response:
{
"data": [
{
"company": "Bravo Studio",
"role": "Head of Engineering",
"location": "London",
"start_date": "2022",
"end_date": "",
"current": true,
"summary": "Scaled product delivery; led platform quality; managed release flow."
}
]
}
POST /profiles/:slug/api/v1/chat/messages
Accepts a chat question and returns a grounded answer plus sources for that profile.
Request:
{
"message": {
"question": "What work has Bravo Studio done?"
}
}
Response:
{
"data": {
"question": "What work has Bravo Studio done?",
"answer": "Recent work includes platform modernization and self-serve operations rollout.",
"error_code": null,
"sources": [
{
"label": "Work",
"path": "/profiles/bravo-studio/work",
"href": "/profiles/bravo-studio/work"
}
]
}
}
Unsupported questions must return:
answer:"Not in the provided material."sources:[]- optional
error_codefor provider/runtime issues such asopenai_rate_limited,openai_auth_failed,openai_timeout, oropenai_request_failed
Notes
- Versioning still follows
/api/v1. - The API is now tenant-scoped by profile slug so it matches the public Explore experience.
- Contracts are enforced by request tests in
test/requests/api/v1. - Operational status remains outside this tenant surface at
GET /api/content/status. chat_statuson the ops endpoints still reports backend/readiness/key-present/model for runtime checks.