{
  "openapi": "3.1.0",
  "info": {
    "title": "SkyRingAI Public API",
    "version": "1.1.0",
    "summary": "Read pricing and service information, and submit leads, for SkyRingAI.",
    "description": "A small public API for AI agents and developers. SkyRingAI is a 24/7 AI phone receptionist for appointment-based service businesses.\n\nAuthentication: none. Every endpoint here serves public marketing data or accepts a lead the visitor asked you to submit.\n\nRate limits: 60 requests per 60 seconds per client IP. Every response carries `RateLimit` and `RateLimit-Policy` headers; a 429 also carries `Retry-After`.\n\nErrors: every non-2xx response is an RFC 9457 problem document (`application/problem+json`) with a machine-readable `code`.\n\nVersioning and deprecation: the major version is in the URL path (`/v1/...`). Breaking changes ship under a new path segment. When an endpoint is scheduled for removal it returns `Deprecation` and `Sunset` headers, and we leave at least 6 months between the first `Deprecation` header and the sunset date. Human documentation: https://www.skyringai.com/developers",
    "termsOfService": "https://www.skyringai.com/terms-of-service",
    "contact": {
      "name": "SkyRingAI",
      "url": "https://www.skyringai.com/contact",
      "email": "support@skyringai.com"
    },
    "license": { "name": "Proprietary", "identifier": "LicenseRef-Proprietary" }
  },
  "externalDocs": {
    "description": "Developer portal",
    "url": "https://www.skyringai.com/developers"
  },
  "x-deprecation-policy": {
    "versioning": "Major version in the URL path (/v1/...).",
    "signals": ["Deprecation header (RFC 9745)", "Sunset header (RFC 8594)"],
    "minimum_notice": "P6M",
    "contact": "support@skyringai.com"
  },
  "servers": [
    {
      "url": "https://afutexcrovgkwevrvdtj.supabase.co/functions/v1/public-api",
      "description": "Production"
    }
  ],
  "security": [],
  "tags": [
    { "name": "Catalog", "description": "Public pricing and service information." },
    { "name": "Leads", "description": "Submit a trial or demo request." }
  ],
  "paths": {
    "/v1/plans": {
      "get": {
        "operationId": "getPlans",
        "tags": ["Catalog"],
        "summary": "List pricing plans and optional add-ons",
        "description": "Returns the current SkyRingAI plans, included minutes, overage rates, and optional add-ons. Use this to answer pricing questions before submitting a lead. Prices are in US dollars.",
        "security": [],
        "responses": {
          "200": {
            "description": "The current pricing catalog.",
            "headers": {
              "RateLimit": { "$ref": "#/components/headers/RateLimit" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PlanCatalog" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/v1/service-info": {
      "get": {
        "operationId": "getServiceInfo",
        "tags": ["Catalog"],
        "summary": "Get company, coverage, and capability information",
        "description": "Returns who SkyRingAI is, which countries and languages are supported, which business types are served, what the product can do, and how to reach a human.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service information.",
            "headers": {
              "RateLimit": { "$ref": "#/components/headers/RateLimit" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ServiceInfo" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/v1/leads": {
      "post": {
        "operationId": "submitLead",
        "tags": ["Leads"],
        "summary": "Submit a trial lead or demo request",
        "description": "Submit a trial interest lead or a demo request on behalf of a user who asked you to. Set formType to 'trial' for general interest. Set formType to 'demo' when the user wants a live walkthrough and can give a preferred date and time. Email is optional for trial and required for demo. Only submit real contact details the user gave you.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/LeadRequest" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Lead received.",
            "headers": {
              "RateLimit": { "$ref": "#/components/headers/RateLimit" },
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/LeadAccepted" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "405": { "$ref": "#/components/responses/MethodNotAllowed" },
          "429": { "$ref": "#/components/responses/TooManyRequests" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    }
  },
  "components": {
    "headers": {
      "RateLimit": {
        "description": "Current quota, e.g. `limit=60, remaining=59, reset=60`.",
        "schema": { "type": "string" }
      },
      "RateLimitPolicy": {
        "description": "Advertised policy, e.g. `60;w=60`.",
        "schema": { "type": "string" }
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying.",
        "schema": { "type": "integer", "minimum": 1 }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was rejected.",
        "content": {
          "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
        }
      },
      "MethodNotAllowed": {
        "description": "Wrong HTTP method for this endpoint.",
        "content": {
          "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
        }
      },
      "NotFound": {
        "description": "No endpoint matches the requested path.",
        "content": {
          "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
        }
      },
      "TooManyRequests": {
        "description": "Rate limit exceeded.",
        "headers": {
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" }
        },
        "content": {
          "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
        }
      },
      "InternalError": {
        "description": "Unexpected server error.",
        "content": {
          "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } }
        }
      }
    },
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem document.",
        "required": ["type", "title", "status", "code"],
        "properties": {
          "type": { "type": "string", "format": "uri", "description": "Stable URI identifying the problem type." },
          "title": { "type": "string", "description": "Short human-readable summary." },
          "status": { "type": "integer", "description": "HTTP status code." },
          "detail": { "type": "string", "description": "Human-readable explanation for this occurrence." },
          "code": {
            "type": "string",
            "description": "Machine-readable error code.",
            "enum": [
              "invalid_json",
              "validation_failed",
              "method_not_allowed",
              "not_found",
              "rate_limited",
              "misconfigured",
              "internal_error"
            ]
          },
          "errors": {
            "type": "array",
            "description": "Field-level validation messages, when applicable.",
            "items": { "type": "string" }
          }
        }
      },
      "Plan": {
        "type": "object",
        "required": ["id", "name", "monthly_price", "monthly_price_cents", "included_minutes", "overage_price_cents_per_minute"],
        "properties": {
          "id": { "type": "string", "description": "Stable plan identifier." },
          "name": { "type": "string" },
          "best_fit": { "type": "string", "description": "Who the plan suits." },
          "monthly_price": { "type": "string", "description": "Formatted monthly price, e.g. `$169`." },
          "monthly_price_cents": { "type": "integer" },
          "included_minutes": { "type": "integer" },
          "overage_price_cents_per_minute": { "type": "integer" },
          "first_month_promotion_cents": {
            "type": ["integer", "null"],
            "description": "First-month promotional price in cents, or null when no promotion is running."
          },
          "support": { "type": "string" },
          "summary": { "type": "string" }
        }
      },
      "AddOn": {
        "type": "object",
        "required": ["id", "name", "monthly_price", "monthly_price_cents"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "monthly_price": { "type": "string" },
          "monthly_price_cents": { "type": "integer" },
          "available_on": { "type": "string", "description": "Plans the add-on can be purchased on." },
          "note": { "type": "string" }
        }
      },
      "PlanCatalog": {
        "type": "object",
        "required": ["api_version", "currency", "plans", "add_ons"],
        "properties": {
          "api_version": { "type": "string" },
          "contract_revision": { "type": "string", "description": "Changes whenever the pricing contract changes." },
          "currency": { "type": "string", "examples": ["USD"] },
          "billing": { "type": "string" },
          "canonical_url": { "type": "string", "format": "uri" },
          "add_ons_url": { "type": "string", "format": "uri" },
          "plans": { "type": "array", "items": { "$ref": "#/components/schemas/Plan" } },
          "add_ons": { "type": "array", "items": { "$ref": "#/components/schemas/AddOn" } },
          "notes": { "type": "array", "items": { "type": "string" } }
        }
      },
      "ServiceInfo": {
        "type": "object",
        "required": ["api_version", "name", "description", "website", "contact", "coverage", "supported_business_types"],
        "properties": {
          "api_version": { "type": "string" },
          "name": { "type": "string" },
          "legal_name": { "type": "string" },
          "description": { "type": "string" },
          "website": { "type": "string", "format": "uri" },
          "developer_portal": { "type": "string", "format": "uri" },
          "contact": {
            "type": "object",
            "properties": {
              "sales_phone": { "type": "string" },
              "support_phone": { "type": "string" },
              "support_email": { "type": "string", "format": "email" },
              "contact_page": { "type": "string", "format": "uri" }
            }
          },
          "address": {
            "type": "object",
            "properties": {
              "locality": { "type": "string" },
              "region": { "type": "string" },
              "country": { "type": "string" }
            }
          },
          "coverage": {
            "type": "object",
            "properties": {
              "countries": { "type": "array", "items": { "type": "string" } },
              "languages": { "type": "array", "items": { "type": "string" } },
              "hours": { "type": "string" }
            }
          },
          "supported_business_types": { "type": "array", "items": { "type": "string" } },
          "capabilities": { "type": "array", "items": { "type": "string" } },
          "trial": {
            "type": "object",
            "properties": {
              "available": { "type": "boolean" },
              "length_days": { "type": "integer" },
              "included_minutes": { "type": "integer" },
              "credit_card_required": { "type": "boolean" },
              "start_url": { "type": "string", "format": "uri" }
            }
          },
          "machine_readable": {
            "type": "object",
            "properties": {
              "openapi": { "type": "string", "format": "uri" },
              "llms_txt": { "type": "string", "format": "uri" },
              "ai_txt": { "type": "string", "format": "uri" },
              "pricing_json": { "type": "string", "format": "uri" }
            }
          }
        }
      },
      "LeadRequest": {
        "type": "object",
        "required": ["formType", "fullName", "phone", "businessType"],
        "properties": {
          "formType": {
            "type": "string",
            "enum": ["trial", "demo"],
            "description": "Use 'trial' for general interest. Use 'demo' when the user wants a live walkthrough and has a preferred date and time."
          },
          "fullName": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100,
            "description": "Full name of the business owner. Letters, spaces, hyphens, and apostrophes only."
          },
          "phone": {
            "type": "string",
            "minLength": 10,
            "maxLength": 20,
            "description": "Contact phone number, digits with optional spaces, parentheses, plus, or hyphen."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 255,
            "description": "Optional for trial, required for demo."
          },
          "businessType": {
            "type": "string",
            "enum": [
              "hvac-plumbing-electrical",
              "dental-medical-healthcare",
              "legal-law-firm",
              "contractor-construction",
              "salon-spa-beauty",
              "real-estate",
              "other-service"
            ],
            "description": "Category that best describes the user's business."
          },
          "preferredDateTime": {
            "type": "string",
            "maxLength": 100,
            "description": "Required when formType is 'demo'. e.g. 'Monday March 25 at 2pm CST'."
          },
          "challenge": {
            "type": "string",
            "maxLength": 500,
            "description": "Optional. The biggest phone-coverage problem the business has."
          }
        }
      },
      "LeadAccepted": {
        "type": "object",
        "required": ["success", "message"],
        "properties": {
          "success": { "type": "boolean", "const": true },
          "message": { "type": "string" }
        }
      }
    }
  }
}
