{"openapi":"3.1.0","info":{"title":"MonCha API","version":"1.0.0","description":"Public REST API for MonCha — AI support agents with chat + voice in the languages Asia speaks. Authenticate with a scoped API token (create one in Dashboard → API): `Authorization: Bearer mgpt_…`. API access requires the Growth plan or higher."},"servers":[{"url":"/v1"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API token from Dashboard → API (mgpt_…)"}},"schemas":{"Bot":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"language":{"type":"string","example":"en-IN"},"created_at":{"type":"string","format":"date-time"}}},"KBDocument":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"source_url":{"type":"string","nullable":true},"source_type":{"type":"string","enum":["url","file","qa","snippet"]},"status":{"type":"string","enum":["queued","processing","ready","failed"]},"chunk_count":{"type":"integer"},"chatbot_id":{"type":"string","format":"uuid","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"}}}}},"paths":{"/bots":{"get":{"summary":"List bots","description":"Requires scope `bots:read`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Bot list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Bot"}}}}}}}}},"post":{"summary":"Create a bot","description":"Requires scope `bots:write`. Subject to your plan’s bot limit.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":100},"language":{"type":"string","example":"en-IN"}}}}}},"responses":{"201":{"description":"Created bot"},"402":{"description":"Plan bot limit reached"}}}},"/kb":{"get":{"summary":"List knowledge-base documents","description":"Requires scope `kb:read`. Filter with `?chatbotId=`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"chatbotId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Document list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/KBDocument"}}}}}}}}}},"/kb/ingest":{"post":{"summary":"Add knowledge (URL or raw text)","description":"Requires scope `kb:write`. Queued for crawling/embedding; poll GET /kb for status.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"url":{"type":"string","format":"uri"},"text":{"type":"string"},"chatbotId":{"type":"string","format":"uuid"}}}}}},"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"}}}}}}}}}}},"/chat":{"post":{"summary":"Chat with a bot (streaming)","description":"Requires scope `chat:invoke`. Returns a Server-Sent Events stream of OpenAI-style chunks (`data: {\"choices\":[{\"delta\":{\"content\":\"…\"}}]}`). Counts toward your monthly message quota.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","maxLength":2000},"chatbotId":{"type":"string","format":"uuid"},"sessionId":{"type":"string","description":"Stable id groups turns into one conversation"},"language":{"type":"string","example":"ja-JP","description":"Reply language. Any supported code, e.g. en-IN, ja-JP, ko-KR, zh-CN, ms-MY, id-ID, th-TH, vi-VN, fil-PH, ar-AE, hi-IN, ta-IN, sw-KE, ha-NG, yo-NG. Omit to use the bot’s default; the bot still matches the language the user writes in."}}}}}},"responses":{"200":{"description":"SSE stream","content":{"text/event-stream":{}}}}}},"/conversations":{"get":{"summary":"List conversations","description":"Requires scope `conversations:read`. Supports `?q=` search, `?limit=`, `?chatbotId=`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}},{"name":"chatbotId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Session list"}}}},"/conversations/{sessionId}":{"get":{"summary":"Get a conversation transcript","security":[{"bearerAuth":[]}],"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Messages in the session"}}}},"/leads":{"get":{"summary":"List leads","description":"Requires scope `leads:read`. Intent-scored leads newest first; optional `?chatbotId=`. Each lead has score/band, an AI summary, contact details, qualification, and `external_user_id` when the visitor was signed in (MonCha.identify).","security":[{"bearerAuth":[]}],"parameters":[{"name":"chatbotId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Lead list"}}}},"/analytics":{"get":{"summary":"Analytics summary (30 days)","description":"Requires scope `analytics:read`. Daily volumes, top questions, unanswered rate, feedback, sessions.","security":[{"bearerAuth":[]}],"parameters":[{"name":"chatbotId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Analytics summary"}}}},"/bookings":{"get":{"summary":"List bookings","description":"Requires scope `bookings:read`. Appointment requests newest first. Filter with `?status=pending|confirmed|rejected|cancelled`, `?chatbotId=`, `?limit=`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","confirmed","rejected","cancelled"]}},{"name":"chatbotId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}}],"responses":{"200":{"description":"Booking list"}}}},"/bookings/{id}":{"get":{"summary":"Get a booking","description":"Requires scope `bookings:read`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Booking"},"404":{"description":"Not found"}}},"patch":{"summary":"Update a booking","description":"Requires scope `bookings:write`. `action` is `confirm`, `reject`, `reschedule`, or `cancel`. Confirm/reject apply to pending requests. Reschedule and cancel apply to pending or confirmed bookings and email the visitor. Reschedule requires `requestedSlot`. Optional `cancelComment` / `rejectionComment` is included in the visitor email.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["confirm","reject","reschedule","cancel"]},"requestedSlot":{"type":"string","format":"date-time"},"rejectionComment":{"type":"string","maxLength":500},"cancelComment":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Updated booking"},"409":{"description":"Slot taken or already decided"}}}}}}