{
  "openapi": "3.1.0",
  "info": {
    "title": "Chinaready public site APIs",
    "version": "0.5.0",
    "description": "Public assistant and form APIs for https://chinaready.co, plus an unauthenticated AI retrieval API hosted by Cloudflare AI Search; no public OAuth yet."
  },
  "servers": [
    {
      "url": "https://chinaready.co"
    }
  ],
  "paths": {
    "/api/contact": {
      "post": {
        "summary": "Submit a contact message",
        "operationId": "postContact",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "message": {
                    "type": "string",
                    "description": "Required for normal contact requests; omitted for assistant handoffs."
                  },
                  "company": {
                    "type": "string"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "source_page": {
                    "type": "string",
                    "description": "Set to assistant for an AI Assistant handoff."
                  },
                  "conversation": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "role",
                        "content"
                      ],
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "assistant"
                          ]
                        },
                        "content": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "low_match",
                      "human_request",
                      "upstream"
                    ]
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "name",
                      "email",
                      "message"
                    ],
                    "properties": {
                      "source_page": {
                        "not": {
                          "const": "assistant"
                        }
                      }
                    }
                  },
                  {
                    "required": [
                      "name",
                      "email",
                      "source_page",
                      "conversation"
                    ],
                    "properties": {
                      "source_page": {
                        "const": "assistant"
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Message received",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "status": {
                      "type": "string",
                      "example": "received"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON or missing required fields"
          }
        }
      }
    },
    "/api/intake": {
      "post": {
        "summary": "Submit a China readiness intake assessment",
        "operationId": "postIntake",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Intake payload; email is required (top-level or basics.email).",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  },
                  "basics": {
                    "type": "object",
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Assessment received and auto-scored",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "status": {
                      "type": "string",
                      "example": "auto_scored"
                    },
                    "message": {
                      "type": "string"
                    },
                    "business_compliance_score": {
                      "type": "number"
                    },
                    "technical_compliance_score": {
                      "type": "number"
                    },
                    "operational_compliance_score": {
                      "type": "number"
                    },
                    "routing_bucket": {
                      "type": "string"
                    },
                    "initial_recommendation": {
                      "type": "string"
                    },
                    "submission_json": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON or missing email"
          }
        }
      }
    },
    "/api/assistant/chat": {
      "post": {
        "summary": "Ask the Chinaready site assistant",
        "operationId": "postAssistantChat",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "messages"
                ],
                "properties": {
                  "messages": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "type": "object",
                      "required": [
                        "role",
                        "content"
                      ],
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "assistant"
                          ]
                        },
                        "content": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Grounded answer, contact-form action, or upstream error action",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "action"
                  ],
                  "properties": {
                    "action": {
                      "type": "string",
                      "enum": [
                        "answer",
                        "contact_form",
                        "error"
                      ]
                    },
                    "text": {
                      "type": "string"
                    },
                    "sources": {
                      "type": "array",
                      "maxItems": 3,
                      "items": {
                        "type": "object",
                        "required": [
                          "url",
                          "title",
                          "type"
                        ],
                        "properties": {
                          "url": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "insight",
                              "blog",
                              "faq",
                              "service",
                              "about"
                            ]
                          }
                        }
                      }
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "low_match",
                        "human_request",
                        "upstream"
                      ]
                    },
                    "stage": {
                      "type": "string",
                      "enum": [
                        "search",
                        "generate"
                      ]
                    },
                    "code": {
                      "type": "integer"
                    },
                    "notice": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, empty question, or conversation over the turn limit"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/search": {
      "servers": [
        {
          "url": "https://search.chinaready.co"
        }
      ],
      "post": {
        "summary": "Semantic search over chinaready.co content (retrieval for AI tools)",
        "operationId": "aiSearch",
        "description": "Unauthenticated semantic search over the Chinaready corpus — public guides, services, and FAQ content hosted by Cloudflare AI Search. Each returned excerpt begins with a url/title/type source header whose url is the absolute chinaready.co page link; cite that URL in answers. Shared endpoint with the site's Ask AI panel; rate limited (~120 requests/minute). A Model Context Protocol server exposing the same corpus lives at /mcp on this host.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "messages"
                ],
                "properties": {
                  "messages": {
                    "type": "array",
                    "maxItems": 10,
                    "items": {
                      "type": "object",
                      "required": [
                        "role",
                        "content"
                      ],
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "assistant"
                          ]
                        },
                        "content": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Retrieval chunks with source URLs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "object",
                      "properties": {
                        "query_kind": {
                          "type": "string"
                        },
                        "search_query": {
                          "type": "string"
                        },
                        "chunks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "score": {
                                "type": "number"
                              },
                              "text": {
                                "type": "string",
                                "description": "Excerpt text; begins with a url/title/type source header whose url is the absolute chinaready.co page URL to cite."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/search": {
      "post": {
        "summary": "Site search over the Chinaready corpus (article-level, AI-ranked)",
        "operationId": "postSiteSearch",
        "description": "Per-IP rate limited retrieval proxy over the same corpus as the Ask AI panel and search.chinaready.co. Accepts a single query string; returns article-level results (best chunk score per URL, snippet included), ranked by relevance. Generation-free.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ranked article results or empty action",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "action": {
                      "type": "string",
                      "enum": [
                        "results",
                        "empty"
                      ]
                    },
                    "query": {
                      "type": "string"
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "url": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "score": {
                            "type": "number"
                          },
                          "snippet": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON or missing/oversized query"
          },
          "429": {
            "description": "Per-IP rate limit exceeded"
          }
        }
      }
    }
  }
}
