{"openapi":"3.1.0","info":{"title":"CloudYali Public API","summary":"Public, unauthenticated endpoints published by the CloudYali website.","description":"CloudYali is a FinOps platform for cloud cost visibility and management across AWS, Azure and GCP.\n\nThis document describes the public, unauthenticated endpoints served by www.cloudyali.io.\nThey let agents and integrations discover what CloudYali does, read published content,\nand submit a demo request without scraping HTML.\n\nAll responses are JSON. Successful responses use the envelope `{ \"success\": true, \"data\": ... }`.\nErrors use `{ \"success\": false, \"error\": { \"code\", \"message\", \"hint\", \"documentation_url\", \"request_id\" } }`\nand the `code` field is stable and safe to branch on.\n\nNo authentication is required for any operation in this document. Requests are rate limited to 120 per 60 seconds per client;\nevery response carries `RateLimit-Policy`, uncached responses also carry the live `RateLimit` field, and a rejected request returns 429 with `Retry-After`.\n\nThe API is versioned in the URL path and is currently v1. Breaking changes ship under a new major version path, never in place.\nA retirement is announced at least 180 days ahead with the RFC 9745 `Deprecation` and RFC 8594 `Sunset` headers. The full policy is at https://www.cloudyali.io/developers/api-versioning.\n\nThe authenticated CloudYali platform API used by the console is documented separately at https://docs.cloudyali.io.","version":"1.0.0","termsOfService":"https://www.cloudyali.io/terms-of-service","contact":{"name":"CloudYali Support","email":"support@cloudyali.io","url":"https://www.cloudyali.io/developers"},"license":{"name":"CloudYali API Terms","url":"https://www.cloudyali.io/terms-of-service"}},"servers":[{"url":"https://www.cloudyali.io","description":"CloudYali production website"}],"x-lifecycle":{"current_version":"v1","versioning":"URL path (/api/v1/...). Breaking changes ship under a new major version path.","compatibility":"Additive within a major version: new endpoints, new optional parameters and new response fields may appear at any time. Clients must ignore unknown fields.","deprecation_signal":"Deprecated endpoints return the RFC 9745 Deprecation header and the RFC 8594 Sunset header, plus Link rel=\"deprecation\" and, where one exists, Link rel=\"successor-version\".","minimum_notice_days":180,"policy_url":"https://www.cloudyali.io/developers/api-versioning","deprecated_endpoints":[]},"x-rate-limit":{"policy_name":"public","quota":120,"window_seconds":60,"headers":["RateLimit-Policy","RateLimit","X-RateLimit-Limit","X-RateLimit-Remaining","X-RateLimit-Reset"],"retry_after_header":"Retry-After","documentation_url":"https://www.cloudyali.io/developers#rate-limits"},"externalDocs":{"description":"CloudYali developer resources","url":"https://www.cloudyali.io/developers"},"tags":[{"name":"Discovery","description":"Endpoint discovery and service health."},{"name":"Product","description":"CloudYali product capability catalog."},{"name":"Content","description":"Published CloudYali blog content."},{"name":"Sales","description":"Demo requests and sales contact."}],"paths":{"/api":{"get":{"operationId":"getApiIndex","summary":"List available CloudYali public API endpoints","description":"Returns a discovery document listing every public endpoint, the URL of this OpenAPI specification, and links to CloudYali developer resources. Call this first when exploring the API.","tags":["Discovery"],"security":[],"parameters":[{"name":"pretty","in":"query","required":false,"description":"Return indented JSON instead of the compact default. Useful when a human, or an agent showing its work, has to read the response directly.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Discovery document.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"ApiIndexResponse","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","required":["service","openapi_url","endpoints"],"properties":{"service":{"type":"string"},"description":{"type":"string"},"documentation_url":{"type":"string","format":"uri"},"openapi_url":{"type":"string","format":"uri"},"llms_txt_url":{"type":"string","format":"uri"},"endpoints":{"type":"array","items":{"type":"object","required":["method","path","operation_id","description"],"properties":{"method":{"type":"string","enum":["GET","POST"]},"path":{"type":"string"},"operation_id":{"type":"string"},"description":{"type":"string"}}}}}}}}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server error.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/health":{"get":{"operationId":"getServiceHealth","summary":"Check CloudYali website API health","description":"Returns the liveness status of the CloudYali public website API. Use this to verify connectivity before issuing other calls. Always returns HTTP 200 when the service is reachable.","tags":["Discovery"],"security":[],"parameters":[{"name":"pretty","in":"query","required":false,"description":"Return indented JSON instead of the compact default. Useful when a human, or an agent showing its work, has to read the response directly.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Service is healthy.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"HealthResponse","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","required":["status","service","version","timestamp"],"properties":{"status":{"type":"string","enum":["ok"]},"service":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}}}}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server error.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/features":{"get":{"operationId":"listProductFeatures","summary":"List CloudYali product capabilities","description":"Returns the full catalog of CloudYali FinOps capabilities — cost visibility, cost savings, budget management, asset inventory, tag governance, AI cost tracking and integrations — including which cloud providers each capability covers. Use this to answer questions about what CloudYali does.","tags":["Product"],"security":[],"parameters":[{"name":"id","in":"query","required":false,"description":"Return only the capability with this identifier. Identifiers are stable and match the feature page slug.","schema":{"type":"string","enum":["cost-visibility","cost-savings","budget-management","asset-inventory","tag-governance","ai-cost-tracking","mcp-server","integrations"]}},{"name":"provider","in":"query","required":false,"description":"Return only capabilities that cover this cloud provider or service, for example `AWS`, `Azure`, `GCP`, `OpenAI` or `Databricks`. Matched case-insensitively against the `providers` array.","schema":{"type":"string","minLength":1,"maxLength":64}},{"name":"pretty","in":"query","required":false,"description":"Return indented JSON instead of the compact default. Useful when a human, or an agent showing its work, has to read the response directly.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Product capability catalog.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"FeatureListResponse","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","required":["features","count"],"properties":{"count":{"type":"integer","minimum":0},"features":{"type":"array","items":{"$ref":"#/components/schemas/Feature"}}}}}}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server error.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/blogs":{"get":{"operationId":"listBlogPosts","summary":"List published CloudYali blog posts","description":"Returns a paginated list of published CloudYali blog posts about FinOps and cloud cost management, newest first. Each item includes a canonical URL and a markdown URL suitable for agent ingestion.","tags":["Content"],"security":[],"parameters":[{"name":"limit","in":"query","required":false,"description":"Maximum number of posts to return.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"description":"Number of posts to skip, for pagination.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}},{"name":"category","in":"query","required":false,"description":"Filter to a single category slug, for example `finops`.","schema":{"type":"string","pattern":"^[a-z0-9-]{1,120}$"}},{"name":"pretty","in":"query","required":false,"description":"Return indented JSON instead of the compact default. Useful when a human, or an agent showing its work, has to read the response directly.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Paginated list of blog posts.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"BlogListResponse","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","required":["posts","total","limit","offset"],"properties":{"total":{"type":"integer","minimum":0,"description":"Total posts matching the filter, ignoring pagination."},"limit":{"type":"integer"},"offset":{"type":"integer"},"posts":{"type":"array","items":{"$ref":"#/components/schemas/BlogPostSummary"}}}}}}}}},"400":{"description":"Malformed request — invalid JSON body or query parameter.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"An upstream dependency of this endpoint failed.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/blogs/{slug}":{"get":{"operationId":"getBlogPostBySlug","summary":"Retrieve one CloudYali blog post","description":"Returns a single published blog post by its slug, including the full body rendered as Markdown. Use `listBlogPosts` to discover valid slugs.","tags":["Content"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"description":"URL-safe identifier of the post, as returned by `listBlogPosts`.","schema":{"type":"string","pattern":"^[a-z0-9-]{1,200}$"}},{"name":"pretty","in":"query","required":false,"description":"Return indented JSON instead of the compact default. Useful when a human, or an agent showing its work, has to read the response directly.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"The requested blog post.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"BlogDetailResponse","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"$ref":"#/components/schemas/BlogPostDetail"}}}}}},"400":{"description":"Malformed request — invalid JSON body or query parameter.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource does not exist.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"An upstream dependency of this endpoint failed.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/demo-request":{"get":{"operationId":"getDemoRequestStatus","summary":"Check the demo request endpoint","description":"Returns the availability and version of the demo request endpoint without submitting anything.","tags":["Sales"],"security":[],"parameters":[{"name":"pretty","in":"query","required":false,"description":"Return indented JSON instead of the compact default. Useful when a human, or an agent showing its work, has to read the response directly.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Endpoint is available.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"DemoRequestStatusResponse","required":["success","data"],"properties":{"success":{"type":"boolean","enum":[true]},"data":{"type":"object","required":["status","version"],"properties":{"status":{"type":"string","enum":["ok"]},"version":{"type":"string"},"message":{"type":"string"}}}}}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server error.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"operationId":"submitDemoRequest","summary":"Submit a CloudYali demo request","description":"Submits a request for a CloudYali product demo. All listed fields are required. Returns a confirmation id on success. This creates a sales lead — only call it on explicit instruction from a real person who wants to be contacted.","tags":["Sales"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DemoRequest"}}}},"responses":{"200":{"description":"Demo request accepted.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","title":"DemoRequestResponse","required":["success","message"],"properties":{"success":{"type":"boolean","enum":[true]},"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"}}}}}}}},"400":{"description":"Malformed request — invalid JSON body or query parameter.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Request was well-formed but failed field validation.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded — more than 120 requests in a 60-second window. Wait for `Retry-After` seconds and retry.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server error.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"An upstream dependency of this endpoint failed.","headers":{"RateLimit-Policy":{"description":"The published quota, as an IETF structured field. Always `\"public\";q=120;w=60`.","schema":{"type":"string"}},"RateLimit":{"description":"Live quota for the calling client — `r` is the remaining requests, `t` the seconds until the window resets. Present only on responses a shared cache will not store, so that a CDN can never replay one caller’s counters to another.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Requests allowed per window. The de-facto header, alongside `RateLimit`.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix epoch seconds at which the current window resets.","schema":{"type":"integer"}},"API-Version":{"description":"Major version of the API that served this response.","schema":{"type":"string","examples":["v1"]}},"Link":{"description":"Always carries `rel=\"deprecation\"` pointing at the versioning and deprecation policy. A deprecated endpoint additionally carries `rel=\"successor-version\"`.","schema":{"type":"string"}},"Deprecation":{"description":"RFC 9745. Present only on a deprecated endpoint: an `@`-prefixed Unix timestamp for when the deprecation was announced.","schema":{"type":"string"}},"Sunset":{"description":"RFC 8594. Present only on a deprecated endpoint: the HTTP-date after which it stops responding.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{},"schemas":{"ErrorResponse":{"type":"object","title":"ErrorResponse","description":"Structured error envelope returned by every CloudYali public endpoint. Never HTML.","required":["success","error"],"additionalProperties":false,"properties":{"success":{"type":"boolean","enum":[false],"description":"Always false on an error response."},"error":{"type":"object","required":["code","message","hint","documentation_url","request_id"],"properties":{"code":{"type":"string","enum":["bad_request","validation_error","invalid_json","not_found","method_not_allowed","rate_limited","upstream_error","configuration_error","internal_error"],"description":"Stable machine-readable error code. Safe to branch on."},"message":{"type":"string","description":"Human-readable description of what went wrong."},"hint":{"type":"string","description":"Suggested resolution step for the caller."},"details":{"description":"Optional machine-readable context, such as the offending field."},"documentation_url":{"type":"string","format":"uri","description":"Where to read more about this endpoint."},"request_id":{"type":"string","description":"Correlation id for this request. Include it in support tickets."}}}}},"Feature":{"type":"object","title":"Feature","required":["id","name","summary","capabilities","providers","url"],"properties":{"id":{"type":"string","enum":["cost-visibility","cost-savings","budget-management","asset-inventory","tag-governance","ai-cost-tracking","mcp-server","integrations"],"description":"Stable feature identifier, matching the feature page slug."},"name":{"type":"string","description":"Human-readable capability name."},"summary":{"type":"string","description":"One-sentence description of the capability."},"capabilities":{"type":"array","items":{"type":"string"},"description":"Concrete things this capability lets a team do."},"providers":{"type":"array","items":{"type":"string"},"description":"Cloud providers and services this capability covers."},"url":{"type":"string","format":"uri","description":"Canonical feature page URL."}}},"BlogPostSummary":{"type":"object","title":"BlogPostSummary","required":["slug","title","url"],"properties":{"slug":{"type":"string","description":"URL-safe unique identifier for the post."},"title":{"type":"string","description":"Post title."},"excerpt":{"type":"string","description":"Short summary of the post."},"url":{"type":"string","format":"uri","description":"Canonical URL of the post."},"markdown_url":{"type":"string","format":"uri","description":"Plain-markdown rendering of the post, for agent consumption."},"published_at":{"type":"string","format":"date-time","description":"ISO 8601 publication timestamp."},"reading_time_minutes":{"type":"integer","minimum":0},"author":{"type":"string","description":"Author display name."},"categories":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}}}},"BlogPostDetail":{"allOf":[{"$ref":"#/components/schemas/BlogPostSummary"},{"type":"object","title":"BlogPostDetail","properties":{"body_markdown":{"type":"string","description":"Full post body rendered as Markdown."}}}]},"DemoRequest":{"type":"object","title":"DemoRequest","description":"Fields required to request a CloudYali product demo.","required":["firstName","lastName","businessEmail","companyName","jobTitle","cloudBill","howDidYouHear"],"properties":{"firstName":{"type":"string","minLength":1,"description":"Requester first name."},"lastName":{"type":"string","minLength":1,"description":"Requester last name."},"businessEmail":{"type":"string","format":"email","description":"Business email address to send the demo invitation to."},"companyName":{"type":"string","minLength":1,"description":"Company name."},"jobTitle":{"type":"string","minLength":1,"description":"Requester job title."},"cloudBill":{"type":"string","minLength":1,"description":"Approximate annual cloud spend band, for example \"$100k - $500k\"."},"howDidYouHear":{"type":"string","minLength":1,"description":"How the requester heard about CloudYali."}}}}},"security":[]}