{
  "openapi": "3.1.1",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "Rida.me Public Content API",
    "summary": "Read-only access to Rida Al Barazi's published site content.",
    "description": "The Rida.me Public Content API lets agents and developers discover the API, retrieve the curated site guide, and read a published page as Markdown. It is anonymous, read-only, URL-versioned, and covered by the published versioning and deprecation policy. It has no accounts, write operations, webhooks, or access to private information.",
    "version": "1.0.0",
    "contact": {
      "name": "Rida Al Barazi",
      "url": "https://rida.me/contact/",
      "email": "me@rida.me"
    }
  },
  "servers": [
    {
      "url": "https://rida.me",
      "description": "Rida.me production API"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Rida.me content",
      "description": "Anonymous, read-only operations over public Rida.me content."
    }
  ],
  "externalDocs": {
    "description": "Rida.me developer resources",
    "url": "https://rida.me/developers/"
  },
  "x-versioning-policy": "https://rida.me/developers/#api-versioning-and-deprecation",
  "paths": {
    "/api/v1": {
      "get": {
        "operationId": "getRidaMeApi",
        "summary": "Discover the Rida.me API",
        "description": "Returns the API identity, version, authentication policy, and the complete list of supported operations.",
        "tags": ["Rida.me content"],
        "parameters": [
          { "$ref": "#/components/parameters/JsonFormat" }
        ],
        "responses": {
          "200": {
            "description": "The API description and operation list.",
            "content": {
              "application/json": {
                "schema": { "type": "object", "$ref": "#/components/schemas/ApiIndexResponse" }
              }
            },
            "headers": {
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" },
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
              "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidParameter" },
          "406": { "$ref": "#/components/responses/NotAcceptable" },
          "429": { "$ref": "#/components/responses/RateLimitExceeded" },
          "500": { "$ref": "#/components/responses/InternalError" },
          "default": { "$ref": "#/components/responses/UnexpectedError" }
        }
      }
    },
    "/api/v1/site-guide": {
      "get": {
        "operationId": "getRidaMeSiteGuide",
        "summary": "Get the Rida.me agent guide",
        "description": "Returns the curated llms.txt guide as JSON-wrapped Markdown. Use this operation first when the best source page is unknown.",
        "tags": ["Rida.me content"],
        "parameters": [
          { "$ref": "#/components/parameters/JsonFormat" }
        ],
        "responses": {
          "200": {
            "description": "The canonical Rida.me agent guide.",
            "content": {
              "application/json": {
                "schema": { "type": "object", "$ref": "#/components/schemas/ContentResponse" }
              }
            },
            "headers": {
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" },
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
              "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidParameter" },
          "406": { "$ref": "#/components/responses/NotAcceptable" },
          "429": { "$ref": "#/components/responses/RateLimitExceeded" },
          "500": { "$ref": "#/components/responses/InternalError" },
          "default": { "$ref": "#/components/responses/UnexpectedError" }
        }
      }
    },
    "/api/v1/page": {
      "get": {
        "operationId": "getRidaMePage",
        "summary": "Get a published Rida.me page",
        "description": "Returns one public page as JSON-wrapped Markdown. The path must come from llms.txt, the sitemap, or another canonical Rida.me link.",
        "tags": ["Rida.me content"],
        "parameters": [
          {
            "name": "path",
            "in": "query",
            "required": true,
            "description": "Canonical same-origin page path, including its leading slash. Examples: /about/ or /blog/mcp-auth-problem/.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "pattern": "^/(?!/)[A-Za-z0-9._~!$&'()*+,;=:@/-]*$",
              "examples": ["/about/", "/talks/", "/blog/mcp-auth-problem/"]
            }
          },
          { "$ref": "#/components/parameters/JsonFormat" }
        ],
        "responses": {
          "200": {
            "description": "The requested canonical page as Markdown.",
            "content": {
              "application/json": {
                "schema": { "type": "object", "$ref": "#/components/schemas/ContentResponse" }
              }
            },
            "headers": {
              "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
              "RateLimit": { "$ref": "#/components/headers/RateLimit" },
              "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
              "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
              "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
              "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidParameter" },
          "404": { "$ref": "#/components/responses/PageNotFound" },
          "406": { "$ref": "#/components/responses/NotAcceptable" },
          "429": { "$ref": "#/components/responses/RateLimitExceeded" },
          "500": { "$ref": "#/components/responses/InternalError" },
          "default": { "$ref": "#/components/responses/UnexpectedError" }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiMetadata": {
        "type": "object",
        "additionalProperties": false,
        "required": ["apiVersion", "documentationUrl", "openapiUrl", "versionPolicyUrl"],
        "properties": {
          "apiVersion": { "type": "string", "description": "Semantic version of the HTTP API.", "examples": ["1.0.0"] },
          "documentationUrl": { "type": "string", "format": "uri", "description": "Human-readable Rida.me developer documentation." },
          "openapiUrl": { "type": "string", "format": "uri", "description": "Canonical URL of this OpenAPI document." },
          "versionPolicyUrl": { "type": "string", "format": "uri", "description": "Published API versioning and deprecation policy." }
        }
      },
      "Operation": {
        "type": "object",
        "additionalProperties": false,
        "required": ["operationId", "method", "path", "description"],
        "properties": {
          "operationId": { "type": "string", "description": "Unique function-calling-compatible operation identifier." },
          "method": { "type": "string", "enum": ["GET"], "description": "Supported HTTP method." },
          "path": { "type": "string", "description": "API endpoint path." },
          "description": { "type": "string", "description": "Agent-readable operation behavior." }
        }
      },
      "ApiIndexData": {
        "type": "object",
        "additionalProperties": false,
        "required": ["name", "version", "description", "authentication", "operations"],
        "properties": {
          "name": { "type": "string", "description": "Canonical API name." },
          "version": { "type": "string", "description": "Semantic API version." },
          "description": { "type": "string", "description": "Scope and purpose of the API." },
          "authentication": {
            "type": "object",
            "additionalProperties": false,
            "required": ["required", "type"],
            "properties": {
              "required": { "type": "boolean", "const": false, "description": "Whether callers must authenticate." },
              "type": { "type": "string", "const": "none", "description": "Authentication mechanism for this public API." }
            }
          },
          "operations": { "type": "array", "items": { "$ref": "#/components/schemas/Operation" }, "minItems": 3, "maxItems": 3 }
        }
      },
      "ApiIndexResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data", "meta"],
        "properties": {
          "data": { "$ref": "#/components/schemas/ApiIndexData" },
          "meta": { "$ref": "#/components/schemas/ApiMetadata" }
        }
      },
      "ContentData": {
        "type": "object",
        "additionalProperties": false,
        "required": ["path", "url", "markdown"],
        "properties": {
          "path": { "type": "string", "description": "Canonical Rida.me path." },
          "url": { "type": "string", "format": "uri", "description": "Canonical human-readable page URL." },
          "markdown": { "type": "string", "minLength": 1, "description": "Published page content in Markdown." }
        }
      },
      "ContentResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": ["data", "meta"],
        "properties": {
          "data": { "$ref": "#/components/schemas/ContentData" },
          "meta": { "$ref": "#/components/schemas/ApiMetadata" }
        }
      },
      "Problem": {
        "type": "object",
        "additionalProperties": false,
        "required": ["type", "title", "status", "detail", "instance", "code", "resolution"],
        "properties": {
          "type": { "type": "string", "format": "uri", "description": "Stable URI identifying the problem type." },
          "title": { "type": "string", "description": "Short human-readable problem summary." },
          "status": { "type": "integer", "minimum": 400, "maximum": 599, "description": "HTTP status code for this occurrence." },
          "detail": { "type": "string", "description": "Occurrence-specific explanation." },
          "instance": { "type": "string", "description": "Request path and query identifying this occurrence." },
          "code": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]+$", "description": "Stable machine-readable error code." },
          "resolution": { "type": "string", "description": "Concrete hint for correcting or recovering from the error." }
        }
      }
    },
    "parameters": {
      "JsonFormat": {
        "name": "format",
        "in": "query",
        "required": false,
        "description": "Explicit response representation for function-calling clients. JSON is the only supported API representation.",
        "schema": {
          "type": "string",
          "const": "json",
          "default": "json"
        }
      }
    },
    "headers": {
      "RateLimitPolicy": {
        "description": "Current IETF structured quota policy: 120 requests per 60-second per-client edge window.",
        "schema": { "type": "string", "examples": ["\"public\";q=120;w=60"] }
      },
      "RateLimit": {
        "description": "Current IETF structured service limit with remaining quota (r) and reset delay in seconds (t).",
        "schema": { "type": "string", "examples": ["\"public\";r=119;t=42"] }
      },
      "RateLimitLimit": {
        "description": "Transitional quota limit field for clients built against earlier IETF drafts.",
        "schema": { "type": "integer", "minimum": 1, "examples": [120] }
      },
      "RateLimitRemaining": {
        "description": "Transitional remaining-quota field for clients built against earlier IETF drafts.",
        "schema": { "type": "integer", "minimum": 0, "examples": [119] }
      },
      "RateLimitReset": {
        "description": "Transitional seconds-until-reset field for clients built against earlier IETF drafts.",
        "schema": { "type": "integer", "minimum": 1, "examples": [42] }
      },
      "DeprecationPolicyLink": {
        "description": "RFC 9745 deprecation link relation pointing to the active API lifecycle policy. Its presence does not mean v1 is deprecated.",
        "schema": { "type": "string", "examples": ["<https://rida.me/developers/#api-versioning-and-deprecation>; rel=\"deprecation\"; type=\"text/html\""] }
      },
      "RetryAfter": {
        "description": "Seconds the client must wait before retrying after a 429 response.",
        "schema": { "type": "integer", "minimum": 1, "examples": [42] }
      }
    },
    "responses": {
      "InvalidParameter": {
        "description": "The required path parameter is missing or invalid.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
          "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
        },
        "content": { "application/problem+json": { "schema": { "type": "object", "$ref": "#/components/schemas/Problem" } } }
      },
      "PageNotFound": {
        "description": "No published page exists at the requested path.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
          "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
        },
        "content": { "application/problem+json": { "schema": { "type": "object", "$ref": "#/components/schemas/Problem" } } }
      },
      "NotAcceptable": {
        "description": "The request does not accept the JSON representation returned by this API.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
          "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
        },
        "content": { "application/problem+json": { "schema": { "type": "object", "$ref": "#/components/schemas/Problem" } } }
      },
      "RateLimitExceeded": {
        "description": "The per-client API request budget was exhausted.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" },
          "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
        },
        "content": { "application/problem+json": { "schema": { "type": "object", "$ref": "#/components/schemas/Problem" } } }
      },
      "InternalError": {
        "description": "Published content could not be loaded.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
          "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
        },
        "content": { "application/problem+json": { "schema": { "type": "object", "$ref": "#/components/schemas/Problem" } } }
      },
      "UnexpectedError": {
        "description": "A typed RFC 9457 problem response for any error not listed separately.",
        "headers": {
          "RateLimit-Policy": { "$ref": "#/components/headers/RateLimitPolicy" },
          "RateLimit": { "$ref": "#/components/headers/RateLimit" },
          "RateLimit-Limit": { "$ref": "#/components/headers/RateLimitLimit" },
          "RateLimit-Remaining": { "$ref": "#/components/headers/RateLimitRemaining" },
          "RateLimit-Reset": { "$ref": "#/components/headers/RateLimitReset" },
          "Link": { "$ref": "#/components/headers/DeprecationPolicyLink" }
        },
        "content": { "application/problem+json": { "schema": { "type": "object", "$ref": "#/components/schemas/Problem" } } }
      }
    }
  }
}
