{
  "openapi": "3.0.3",
  "info": {
    "title": "AutoChatly WhatsApp OTP API",
    "version": "1.0.0",
    "description": "Send one-time passwords to your users on WhatsApp from your own WhatsApp Business number, then verify them. Create an API key in the AutoChatly dashboard (WhatsApp OTP page) after connecting your WhatsApp number and getting the OTP template approved. Call this API only from your server; never expose the API key in a browser or mobile app.",
    "contact": { "name": "AutoChatly support", "email": "support@autochatly.com", "url": "https://autochatly.com/whatsapp-otp-api-docs/" }
  },
  "servers": [{ "url": "https://app.autochatly.com/api/verify/v1" }],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/send": {
      "post": {
        "summary": "Send a WhatsApp OTP",
        "description": "Generates a 6-digit code, sends it from your WhatsApp Business number using your approved authentication template, and returns a request_id. The code itself is never returned.",
        "operationId": "sendOtp",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendRequest" }, "example": { "phone": "+919876543210" } } }
        },
        "responses": {
          "200": { "description": "Code sent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendResponse" }, "example": { "ok": true, "request_id": "6f1c2b7e-3a9d-4c1e-9b8a-2f4d5e6a7b8c", "expires_in": 300, "channel": "whatsapp" } } } },
          "401": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" },
          "502": { "$ref": "#/components/responses/Error" },
          "503": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/check": {
      "post": {
        "summary": "Verify a code",
        "description": "Checks the code the user typed. Codes are single use, expire (default 5 minutes) and lock after 5 wrong attempts.",
        "operationId": "checkOtp",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckRequest" }, "example": { "request_id": "6f1c2b7e-3a9d-4c1e-9b8a-2f4d5e6a7b8c", "code": "123456" } } }
        },
        "responses": {
          "200": { "description": "Verified", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CheckResponse" }, "example": { "ok": true, "verified": true, "phone": "+919876543210" } } } },
          "401": { "$ref": "#/components/responses/Error" },
          "404": { "$ref": "#/components/responses/Error" },
          "409": { "$ref": "#/components/responses/Error" },
          "410": { "$ref": "#/components/responses/Error" },
          "422": { "$ref": "#/components/responses/Error" },
          "429": { "$ref": "#/components/responses/Error" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "description": "Your AutoChatly OTP API key (starts with acv_live_)." } },
    "schemas": {
      "SendRequest": { "type": "object", "required": ["phone"], "properties": { "phone": { "type": "string", "maxLength": 20, "description": "User's WhatsApp number in international format, e.g. +919876543210. A 10-digit Indian mobile is accepted and treated as +91." } } },
      "SendResponse": { "type": "object", "properties": { "ok": { "type": "boolean" }, "request_id": { "type": "string", "format": "uuid" }, "expires_in": { "type": "integer", "description": "Seconds until the code expires" }, "channel": { "type": "string", "enum": ["whatsapp"] } } },
      "CheckRequest": { "type": "object", "required": ["request_id", "code"], "properties": { "request_id": { "type": "string", "format": "uuid" }, "code": { "type": "string", "pattern": "^[0-9]{6}$" } } },
      "CheckResponse": { "type": "object", "properties": { "ok": { "type": "boolean" }, "verified": { "type": "boolean" }, "phone": { "type": "string" } } },
      "Error": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean", "example": false },
          "error": { "type": "string", "enum": ["unauthorized", "too_many_requests", "invalid_phone", "country_not_allowed", "not_configured", "too_soon", "phone_limit", "ip_limit", "app_limit", "send_failed", "not_found", "already_used", "expired", "blocked", "too_many_attempts", "wrong_code"] },
          "message": { "type": "string", "description": "Human-readable message, safe to show to end users." },
          "verified": { "type": "boolean" },
          "attempts_left": { "type": "integer" }
        }
      }
    },
    "responses": { "Error": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } } }
  }
}
