Date : 2026-04-16
Depends on : ADR-0001..0005
Base: https://puccha.hxlab.io/api (same-origin for all surfaces; no CNAME alias needed).
Auth: cookie session (app) or Authorization: Bearer puccha_live_... (API) or widget JWT (Authorization: Bearer wjwt_...).
Tenant resolution (ADR-0002): subdomain OR /c/{tenant}/... path OR API key owner. Body/query tenant params rejected.
Encoding: JSON request/response, UTF-8. Streams use SSE (text/event-stream).
IDs: nanoid (doc_..., usr_..., tnt_...).
Errors: RFC 9457 Problem Details + stable code enum.
Idempotency: Idempotency-Key header on POST; server replays first response within 24h.
Rate limits: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset on every response.
Method
Path
Purpose
POST
/api/auth/signup
Self-serve tenant+user creation (Free tier only)
POST
/api/auth/signin
Email + password / magic link
GET
/api/auth/callback/{provider}
OAuth callback
GET
/api/public/tenant/{slug}
Tenant presence check (no details leaked)
Method
Path
Purpose
POST
/api/widget/session
Exchange tenant slug + origin + optional public key for short-TTL JWT
GET
/api/widget/config
Tenant branding (accent, fonts, theme) + enabled features
POST
/api/widget/events
Analytics events (no query text)
POST
/api/answer
One-shot answer (JSON) — shared with app
POST
/api/chat
Streaming chat (SSE) — shared with app
Method
Path
Role
Purpose
GET
/api/docs
Viewer+
List docs (paginated, filter by tag/collection/status)
GET
/api/docs/{id}
Viewer+ (ACL)
Get doc + chunks
POST
/api/docs
Editor+
Create doc (MD body or multipart upload)
PATCH
/api/docs/{id}
Editor+
Update doc body/metadata/ACL
DELETE
/api/docs/{id}
Editor+
Soft-delete (7d grace)
POST
/api/docs/{id}/reindex
Editor+
Force re-ingest
POST
/api/docs/batch
Editor+
Bulk import (MD zip, up to 100 files)
GET
/api/docs/{id}/status
Viewer+
Ingest status + progress
Method
Path
Purpose
POST
/api/search
Lexical+semantic hybrid search (no LLM); returns chunks
POST
/api/answer
Retrieve → rerank → single answer with citations
POST
/api/chat
Retrieve → rerank → streaming chat (multi-turn)
GET
/api/answer/{id}
Fetch a past answer (admin plane only; no conversation scrollback in v1)
Method
Path
Role
Purpose
GET
/api/tenant
Viewer+
Current tenant details
PATCH
/api/tenant
Admin+
Name, brand accent, allowed origins, settings
GET
/api/tenant/members
Admin+
List members
POST
/api/tenant/invitations
Admin+
Create invitation
POST
/api/tenant/invitations/{id}/resend
Admin+
Resend
DELETE
/api/tenant/invitations/{id}
Admin+
Revoke
POST
/api/tenant/invitations/accept
public (token)
Accept invite
PATCH
/api/tenant/members/{id}
Admin+
Change role
DELETE
/api/tenant/members/{id}
Admin+
Remove
POST
/api/tenant/owner-transfer
Owner
Transfer ownership
Method
Path
Role
Purpose
GET
/api/tenant/api-keys
Admin+
List (prefix + metadata; never the key)
POST
/api/tenant/api-keys
Admin+
Create (returns full key once)
DELETE
/api/tenant/api-keys/{id}
Admin+
Revoke
Method
Path
Purpose
GET
/api/billing/subscription
Current plan + usage
POST
/api/billing/checkout
Start Stripe Checkout session for plan upgrade
POST
/api/billing/portal
Open Stripe billing portal
POST
/api/billing/webhook
Stripe webhook (signed)
Method
Path
Role
Purpose
GET
/api/insights/gaps
Admin+
Top queries with low confidence or IDK
GET
/api/insights/usage
Admin+
Daily/weekly/monthly counters
GET
/api/insights/audit
Admin+
Audit log export (CSV or JSON)
Method
Path
Purpose
GET
/admin/tenants
Cross-tenant list
POST
/admin/tenants
Provision tenant
PATCH
/admin/tenants/{id}
Suspend / unsuspend / change plan
DELETE
/admin/tenants/{id}
Hard delete
POST
/admin/tenants/{id}/impersonate
Issue a tenant-scoped staff session (audit-logged)
GET
/admin/health
System health, queue depth, error rates
Request:
"query" : " How long does ISO 27001 certification usually take? " ,
Response (200):
"answer" : " A typical ISO 27001 certification takes 3–6 months... " ,
"url" : " https://puccha.hxlab.io/c/acme/docs/iso-27001#timeline " ,
"title" : " ISO 27001 · Timeline " ,
"updatedAt" : " 2026-04-10T08:12:00Z " ,
"snippet" : " Stage 1 audit typically occurs... "
IDK example (200):
"answer" : " I don't have documentation covering that in this knowledge base. Please contact your admin or the ISMS lead. " ,
Request:
"conversationId" : " conv_abc " ,
{ "role" : " user " , "content" : " Follow-up on that... " }
Response: SSE stream, events per AI SDK UI v5 data-stream protocol (toUIMessageStreamResponse()). Includes text deltas + a final structured data-citations event.
Request:
{ "query" : " ISO 27001 timeline " , "locale" : " en " , "topK" : 10 , "filters" : { "collection" : [ " policies " ], "tags" : [ " iso-27001 " ] } }
Response: ranked array of chunk objects (title, url, snippet, score, sourceDoc). No LLM call.
"type" : " https://puccha.hxlab.io/problems/acl-denied " ,
"title" : " Access denied " ,
"detail" : " This document is restricted to admins in your organization. " ,
"instance" : " req_abc123 " ,
Stable code values include: auth_required, auth_invalid, tenant_suspended, acl_denied, not_found, validation_failed, rate_limited, quota_exceeded, ingest_failed, llm_unavailable, idempotency_conflict, origin_not_allowed.
Implicit v1 for launch (no /v1/ prefix). Breaking changes ship under /v2/ later.
Additive changes (new fields, new endpoints) are not versioned.
Deprecated fields flagged in Deprecation + Sunset headers for ≥ 6 months before removal.
Generated from Zod schemas in packages/types via zod-to-openapi.
Published at https://puccha.hxlab.io/docs/openapi.json.
Swagger UI at https://puccha.hxlab.io/docs/api.