{
  "openapi": "3.1.0",
  "info": {
    "title": "CallChatSyn API",
    "version": "1.0.0",
    "description": "Let your website, app or AI agent answer customer questions and book appointments with a CallChatSyn business's own answering bot. Create an API key in Dashboard > Developers. Requests count toward the business's plan usage limits."
  },
  "servers": [{ "url": "https://callchatsyn.com" }],
  "security": [{ "bearer": [] }],
  "components": {
    "securitySchemes": { "bearer": { "type": "http", "scheme": "bearer", "description": "ccs_live_… API key" } },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "enum": ["unauthorized", "billing", "plan", "rate_limited", "invalid_request", "not_found", "conflict"] },
              "message": { "type": "string" }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/api/v1/answer": {
      "post": {
        "summary": "Answer a customer's message",
        "description": "Rule-based answering bot: matches the business's FAQs, looks up order status, and recognises booking or 'talk to a person' requests. English and Chinese.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "required": ["message"], "properties": { "message": { "type": "string", "maxLength": 2000 } } } } }
        },
        "responses": {
          "200": {
            "description": "Reply",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "intent": { "type": "string", "enum": ["faq", "order_status", "appointment", "human_handoff"] },
                    "lang": { "type": "string", "enum": ["en", "zh"] },
                    "matched": { "type": "boolean", "description": "false when no FAQ matched and the reply is the generic fallback" },
                    "reply": { "type": "string" },
                    "next": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "description": "Invalid request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "401": { "description": "Missing or invalid API key" },
          "402": { "description": "Business's plan is inactive" },
          "403": { "description": "Feature not in the business's plan" },
          "429": { "description": "Usage limit reached" }
        }
      }
    },
    "/api/v1/slots": {
      "get": {
        "summary": "List open appointment times",
        "parameters": [{ "name": "lang", "in": "query", "schema": { "type": "string", "enum": ["en", "zh"] } }],
        "responses": {
          "200": {
            "description": "Open times",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "slots": { "type": "array", "items": { "type": "object", "properties": { "start": { "type": "string", "format": "date-time" }, "label": { "type": "string" } } } },
                    "services": { "type": "array", "items": { "type": "string" } },
                    "locations": { "type": "array", "items": { "type": "string" } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/bookings": {
      "post": {
        "summary": "Book an open time",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["start", "service"],
                "description": "Give at least one of email or phone.",
                "properties": {
                  "start": { "type": "string", "format": "date-time", "description": "A 'start' value from /api/v1/slots" },
                  "service": { "type": "string" },
                  "name": { "type": "string" },
                  "email": { "type": "string" },
                  "phone": { "type": "string" },
                  "remarks": { "type": "string", "maxLength": 500 }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Booked; the business is notified" },
          "400": { "description": "Missing fields" },
          "404": { "description": "Time not offered" },
          "409": { "description": "Time just taken" }
        }
      }
    }
  }
}
