Structured contract surfaces
API surfaces for public profiles and owner workflow.
Explore exposes two clear contract surfaces: a public profile API for published content and grounded follow-up, and an owner workflow surface for inspect, draft, preview, and apply.
The explore CLI and agent API follow the same owner workflow. Start here when you want the endpoints and contract details behind that split.
What lives here
- Public profile reads
/profiles/:slug/api/v1/*- Owner workflow API
/api/agent/v1/*- Owner CLI
explore
Example tenant API base: /profiles/johnny/api/v1
Public-safe surface
Read published profile content and grounded chat
Use the tenant-scoped public API when you want published profile content, case studies, writing, experiences, or grounded chat against a public profile slug. These reads are the public-safe side of the contract.
Owner-only surface
Inspect account state and run the draft workflow
Use the agent API when you need structured account inspection, onboarding/readiness signals, Notion sync state, and the explicit draft workflow that powers CLI-first and agent-operable changes. Public-safe reads stay keyless; owner-only reads and mutations begin where a signed-in session or account token starts.
API v1
Base path: /profiles/:slug/api/v1
Related agent-friendly surfaces
These routes sit alongside the tenant-scoped public API and should be kept in sync with product behavior when onboarding or readiness semantics change:
- Public agent manifest:
GET /.well-known/agent.json - Human-readable agent guide:
GET /agents - Authenticated agent context for the current signed-in account:
GET /api/agent/context - Versioned inspect-first agent API:
GET /api/agent/v1/*
Unlike the tenant-scoped public API below, the authenticated agent context is session-scoped to the current owner account and is not addressed by public profile slug.
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
- The tenant-scoped public API under
/profiles/:slug/api/v1is public and does not requireX-API-Key. - Invalid or missing key responses below apply to authenticated agent endpoints, not the tenant-scoped public content/chat routes.
- Authenticated agent endpoints return
401with:
{
"error": {
"code": "unauthorized",
"message": "Unauthorized"
}
}
Error Contract
Error responses use:
{
"error": {
"code": "<machine_code>",
"message": "<human_message>",
"details": {}
}
}
Agent API v1 commonly returns these machine-readable codes:
api_key_missinginvalid_api_keyowner_context_requiredaccount_scope_requiredforbidden_account_scopemissing_parameteraccount_not_founddraft_not_foundresource_not_founddraft_archived
Missing required agent parameters return 400 with:
{
"error": {
"code": "missing_parameter",
"message": "Missing required parameter",
"details": {
"parameter": "draft[attributes]"
}
}
}
Endpoints
GET /profiles/:slug/api/v1/content/profile
Returns the published profile summary for that account.
When an avatar is published, avatar_url is an Explore-served Active Storage path backed by durable storage rather than a temporary external file URL.
Response:
{
"data": {
"name": "Bravo Studio",
"tagline": "Design systems and shipping support",
"bio": "Bravo Studio is another customer account fixture.",
"location": "Remote",
"avatar_url": "/rails/active_storage/blobs/proxy/:signed_id/bravo.png"
}
}
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.error_tracking_statuson the ops endpoints reports the configured provider, readiness, API-key presence, and runtime environment for internal checks.
Explore agent API v1
Base path: /api/agent/v1
This is a separate inspect-first surface for humans and coding agents. It is read-heavy by default, with explicit owner-only document apply and draft operations.
Authentication model
Public-safe endpoints:
GET /api/agent/v1/profile?slug=:slugGET /api/agent/v1/content?slug=:slug
Owner-only endpoints:
GET /api/agent/v1/onboarding/statusGET /api/agent/v1/manifest/next_actionsGET /api/agent/v1/publish/previewGET /api/agent/v1/profile/documentPUT /api/agent/v1/profile/documentGET /api/agent/v1/draftsGET /api/agent/v1/drafts/:idPOST /api/agent/v1/drafts/:id/applyGET /api/agent/v1/drafts/:id/apply_previewPATCH /api/agent/v1/drafts/:idPOST /api/agent/v1/drafts/:id/archivePOST /api/agent/v1/content/propose_update
Owner-only endpoints use either:
- the current signed-in session account, or
- an account-scoped owner token passed as
X-API-Key, optionally plusaccount=<slug>oraccount_id=<id>scope when the client wants to be explicit
When slug is provided, the public-safe inspect endpoints above do not require an API key. Owner-only endpoints still require the current signed-in session or an account token.
Account tokens are scoped to a single Explore account and should be created from that account's signed-in workspace. Most CLI users should use explore login and browser approval first; the token value is mainly for advanced, scripted, or non-interactive owner access.
Response envelope
{
"status": "ok",
"resource": "profile.inspect",
"generated_at": "2026-03-26T11:00:00Z",
"account_id": 1,
"account_slug": "acme-careers",
"context": {
"mode": "owner"
}
}
Endpoints
#### GET /api/agent/v1/profile
Returns public profile data, completeness, weak spots, and next safe actions.
- Public mode: pass
slug=:slugto inspect a published profile withoutX-API-Key. - Owner mode: omit
slugand use the current signed-in session, or pass an account token asX-API-Keyplus optionalaccount/account_id.
#### PATCH /api/agent/v1/drafts/:id
Updates an existing open draft without publishing it.
Request:
{
"draft": {
"title": "Refined project draft",
"summary": "Sharper framing for the same idea.",
"attributes": {
"summary": "Sharper framing for the same idea."
}
}
}
Archived drafts are read-only and return:
{
"error": {
"code": "draft_archived",
"message": "Archived drafts are read-only."
}
}
#### GET /api/agent/v1/content
Returns a structured content inventory for projects, posts, experiences, testimonials, and public profile sections.
- Public mode: pass
slug=:slugto inspect published content withoutX-API-Key. - Owner mode: omit
slugand use the current signed-in session, or pass an account token asX-API-Keyplus optionalaccount/account_id.
#### GET /api/agent/v1/onboarding/status
Returns the current onboarding/setup step, blockers, guidance, and useful internal/public URLs.
#### GET /api/agent/v1/manifest/next_actions
Returns the explicit next safe action and the currently allowed action set for the account.
#### GET /api/agent/v1/profile/document
Returns the canonical Explore profile document for the owner account as structured JSON. The CLI renders this into YAML for local editing.
#### PUT /api/agent/v1/profile/document
Validates and applies a profile document back into the canonical Explore account records. Invalid documents return 422 with path-specific errors under error.details.errors.
#### GET /api/agent/v1/publish/preview
Returns a safe share-readiness preview and explainable publish impact. It never publishes content.
#### POST /api/agent/v1/content/propose_update
Records an audit-friendly content proposal event. V1 stores the proposal for review and does not mutate or publish live content.
#### POST /api/agent/v1/content/create_draft
Creates a first-class draft artifact for future content. Drafts are owner-only, never published automatically, and can appear in owner-facing content.list / profile.inspect responses.
#### GET /api/agent/v1/drafts
Lists owner-only drafts with stable metadata and allowed next actions.
#### GET /api/agent/v1/drafts/:id
Returns one owner-only draft for review.
#### POST /api/agent/v1/drafts/:id/apply
Applies a reviewed draft into Explore data and archives the draft.
- Profile drafts update live account public profile fields.
- Project, post, and experience drafts create new account-backed records.
- This action is audited and does not perform broader publish orchestration.
#### GET /api/agent/v1/drafts/:id/apply_preview
Returns a read-only preview of what the draft would change if a future apply step were introduced.
- Profile drafts compare against the current live profile fields.
- Project, post, and experience drafts currently preview creation of a new item because V1 drafts do not yet carry a target record id.
#### POST /api/agent/v1/drafts/:id/archive
Marks one owner-only draft as archived so it no longer appears in open-draft pathways.