{
  "openapi": "3.1.0",
  "info": {
    "title": "rines.io public API",
    "version": "1.0.0",
    "summary": "Read-only public API for Tim Rines' personal site",
    "description": "Unauthenticated HTTP + MCP surface for rines.io. Errors are RFC 9457 application/problem+json. Versioning is URL-path /api/v1. Deprecated versions send Deprecation and Sunset headers for at least 90 days. Policy JSON: GET /api/v1. Docs: https://www.rines.io/docs#versioning. Rate limits: 60 req / 60s with RateLimit headers.",
    "contact": {
      "name": "Tim Rines",
      "email": "tim@rines.io",
      "url": "https://www.rines.io"
    },
    "license": {
      "name": "UNLICENSED"
    }
  },
  "servers": [
    {
      "url": "https://www.rines.io",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "discovery",
      "description": "Machine-readable discovery documents"
    },
    {
      "name": "contact",
      "description": "Public contact API"
    },
    {
      "name": "mcp",
      "description": "Model Context Protocol Streamable HTTP"
    }
  ],
  "paths": {
    "/api": {
      "get": {
        "operationId": "getApiIndex",
        "tags": [
          "discovery"
        ],
        "summary": "rines.io API index",
        "description": "Lists public rines.io API entry points.",
        "responses": {
          "200": {
            "description": "API index",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/api/v1": {
      "get": {
        "operationId": "getApiVersionPolicy",
        "tags": [
          "discovery"
        ],
        "summary": "API versioning and deprecation policy",
        "description": "Current version, deprecation flags, and Sunset/Deprecation header policy.",
        "responses": {
          "200": {
            "description": "Versioning policy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionPolicy"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/api/v1/contact": {
      "get": {
        "operationId": "getContactDiscovery",
        "tags": [
          "contact"
        ],
        "summary": "Contact API discovery",
        "description": "Unauthenticated discovery document for POST /api/v1/contact.",
        "responses": {
          "200": {
            "description": "Discovery document",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDiscovery"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      },
      "post": {
        "operationId": "postContact",
        "tags": [
          "contact"
        ],
        "summary": "Submit a contact message",
        "description": "Validates {name,email,message}. Does not relay mail. Returns 202 with a mailto next step.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactInput"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactAccepted"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/api/contact": {
      "get": {
        "operationId": "getContactDiscoveryAlias",
        "tags": [
          "contact"
        ],
        "summary": "Stable alias of /api/v1/contact",
        "description": "Same discovery document as GET /api/v1/contact.",
        "responses": {
          "200": {
            "description": "Discovery document",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactDiscovery"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      },
      "post": {
        "operationId": "postContactAlias",
        "tags": [
          "contact"
        ],
        "summary": "Stable alias of POST /api/v1/contact",
        "description": "Same contract as POST /api/v1/contact.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactInput"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactAccepted"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/mcp": {
      "get": {
        "operationId": "getMcpSse",
        "tags": [
          "mcp"
        ],
        "summary": "MCP Streamable HTTP SSE stream",
        "description": "With Accept: text/event-stream, opens the Streamable HTTP SSE stream. Otherwise returns the JSON MCP manifest. Handshake: POST initialize with Accept: application/json, text/event-stream.",
        "responses": {
          "200": {
            "description": "SSE hello",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/McpManifest"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      },
      "post": {
        "operationId": "postMcpJsonRpc",
        "tags": [
          "mcp"
        ],
        "summary": "MCP JSON-RPC",
        "description": "initialize, tools/list, tools/call, resources/list, resources/read, ping.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JsonRpcRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "202": {
            "description": "Notification acknowledged",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "description": "Parse error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonRpcResponse"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      },
      "delete": {
        "operationId": "deleteMcpSession",
        "tags": [
          "mcp"
        ],
        "summary": "End MCP session",
        "description": "Clears the Mcp-Session-Id.",
        "responses": {
          "204": {
            "description": "Session cleared"
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/mcp.json": {
      "get": {
        "operationId": "getMcpManifest",
        "tags": [
          "mcp"
        ],
        "summary": "MCP server manifest",
        "description": "JSON manifest for the rines.io MCP server.",
        "responses": {
          "200": {
            "description": "Manifest",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/McpManifest"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "tags": [
          "discovery"
        ],
        "summary": "This OpenAPI document",
        "description": "OpenAPI 3.1 description of the rines.io public HTTP API.",
        "responses": {
          "200": {
            "description": "OpenAPI 3.1",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenApiDocument"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "tags": [
          "discovery"
        ],
        "summary": "Agent index",
        "description": "Plain-text agent index with when-to-use guidance.",
        "responses": {
          "200": {
            "description": "text/plain markdown",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    },
    "/.well-known/api-catalog": {
      "get": {
        "operationId": "getApiCatalog",
        "tags": [
          "discovery"
        ],
        "summary": "RFC 9727 linkset",
        "description": "API catalog linkset for rines.io.",
        "responses": {
          "200": {
            "description": "application/linkset+json",
            "content": {
              "application/linkset+json": {
                "schema": {
                  "$ref": "#/components/schemas/Linkset"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Linkset"
                }
              }
            },
            "headers": {
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Sunset": {
                "$ref": "#/components/headers/Sunset"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Problem400"
          },
          "404": {
            "$ref": "#/components/responses/Problem404"
          },
          "405": {
            "$ref": "#/components/responses/Problem405"
          },
          "429": {
            "$ref": "#/components/responses/Problem429"
          },
          "500": {
            "$ref": "#/components/responses/Problem500"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ContactInput": {
        "type": "object",
        "required": [
          "name",
          "email",
          "message"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 200
          },
          "message": {
            "type": "string",
            "maxLength": 5000
          },
          "subject": {
            "type": "string",
            "maxLength": 200
          }
        }
      },
      "ContactDiscovery": {
        "type": "object",
        "required": [
          "name",
          "version",
          "method",
          "auth",
          "docs",
          "openapi",
          "rateLimit"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "method": {
            "type": "string",
            "enum": [
              "POST"
            ]
          },
          "auth": {
            "type": "string",
            "enum": [
              "none"
            ]
          },
          "docs": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          },
          "rateLimit": {
            "type": "object",
            "required": [
              "limit",
              "windowSeconds"
            ],
            "properties": {
              "limit": {
                "type": "integer"
              },
              "windowSeconds": {
                "type": "integer"
              }
            }
          },
          "deprecation": {
            "$ref": "#/components/schemas/DeprecationBlock"
          }
        },
        "additionalProperties": false
      },
      "ContactAccepted": {
        "type": "object",
        "required": [
          "success",
          "accepted",
          "delivery",
          "next",
          "hint"
        ],
        "properties": {
          "success": {
            "type": "boolean"
          },
          "accepted": {
            "type": "boolean"
          },
          "delivery": {
            "type": "string"
          },
          "next": {
            "type": "string"
          },
          "hint": {
            "type": "string"
          },
          "echo": {
            "type": "object"
          }
        },
        "additionalProperties": false
      },
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code",
          "error"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "validation_error",
              "invalid_json",
              "rate_limit_exceeded",
              "method_not_allowed",
              "not_found",
              "internal_error"
            ]
          },
          "error": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "ApiIndex": {
        "type": "object",
        "required": [
          "name",
          "version",
          "docs",
          "openapi",
          "contact",
          "mcp"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "docs": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          },
          "contact": {
            "type": "string",
            "format": "uri"
          },
          "mcp": {
            "type": "string",
            "format": "uri"
          },
          "errors": {
            "type": "string"
          },
          "auth": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "VersionPolicy": {
        "type": "object",
        "required": [
          "version",
          "current",
          "deprecated",
          "policy",
          "docs"
        ],
        "properties": {
          "version": {
            "type": "string"
          },
          "current": {
            "type": "boolean"
          },
          "deprecated": {
            "type": "boolean"
          },
          "sunset": {
            "type": [
              "string",
              "null"
            ]
          },
          "deprecation": {
            "type": [
              "string",
              "null"
            ]
          },
          "policy": {
            "type": "string"
          },
          "docs": {
            "type": "string"
          },
          "contact": {
            "type": "string",
            "format": "uri"
          },
          "openapi": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": false
      },
      "DeprecationBlock": {
        "type": "object",
        "properties": {
          "policy": {
            "type": "string"
          },
          "sunsetHeader": {
            "type": "string"
          },
          "deprecationHeader": {
            "type": "string"
          }
        }
      },
      "JsonRpcRequest": {
        "type": "object",
        "required": [
          "jsonrpc",
          "method"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "enum": [
              "2.0"
            ]
          },
          "id": {
            "type": [
              "string",
              "number",
              "null"
            ]
          },
          "method": {
            "type": "string"
          },
          "params": {
            "type": "object"
          }
        }
      },
      "JsonRpcResponse": {
        "type": "object",
        "required": [
          "jsonrpc"
        ],
        "properties": {
          "jsonrpc": {
            "type": "string",
            "enum": [
              "2.0"
            ]
          },
          "id": {
            "type": [
              "string",
              "number",
              "null"
            ]
          },
          "result": {},
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "integer"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "McpManifest": {
        "type": "object",
        "required": [
          "name",
          "version",
          "protocolVersion",
          "transport"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "protocolVersion": {
            "type": "string"
          },
          "transport": {
            "type": "object",
            "required": [
              "type",
              "url"
            ],
            "properties": {
              "type": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "capabilities": {
            "type": "object"
          },
          "tools": {
            "type": "array"
          },
          "websiteUrl": {
            "type": "string",
            "format": "uri"
          },
          "documentationUrl": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": false
      },
      "Linkset": {
        "type": "object",
        "required": [
          "linkset"
        ],
        "properties": {
          "linkset": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "OpenApiDocument": {
        "type": "object",
        "additionalProperties": true,
        "required": [
          "openapi",
          "info",
          "paths"
        ],
        "properties": {
          "openapi": {
            "type": "string"
          },
          "info": {
            "type": "object",
            "required": [
              "title",
              "version"
            ],
            "properties": {
              "title": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "description": {
                "type": "string"
              }
            }
          },
          "paths": {
            "type": "object",
            "additionalProperties": true
          }
        }
      }
    },
    "headers": {
      "RateLimit": {
        "description": "IETF RateLimit header",
        "schema": {
          "type": "string",
          "example": "limit=60, remaining=59, reset=58"
        }
      },
      "RateLimitPolicy": {
        "description": "IETF RateLimit-Policy",
        "schema": {
          "type": "string",
          "example": "60;w=60"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait after HTTP 429",
        "schema": {
          "type": "integer"
        }
      },
      "ApiVersion": {
        "description": "Response API version",
        "schema": {
          "type": "string",
          "example": "1"
        }
      },
      "Deprecation": {
        "description": "RFC 8594. Absent while v1 is current.",
        "schema": {
          "type": "string"
        }
      },
      "Sunset": {
        "description": "RFC 8594 HTTP-date when a deprecated version will be removed.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Problem400": {
        "description": "Validation or parse error",
        "headers": {
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Sunset": {
            "$ref": "#/components/headers/Sunset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Problem404": {
        "description": "Unknown API path",
        "headers": {
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Sunset": {
            "$ref": "#/components/headers/Sunset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Problem405": {
        "description": "Method not allowed",
        "headers": {
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Sunset": {
            "$ref": "#/components/headers/Sunset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Problem429": {
        "description": "Rate limit exceeded",
        "headers": {
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Sunset": {
            "$ref": "#/components/headers/Sunset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "Problem500": {
        "description": "Internal error",
        "headers": {
          "RateLimit": {
            "$ref": "#/components/headers/RateLimit"
          },
          "RateLimit-Policy": {
            "$ref": "#/components/headers/RateLimitPolicy"
          },
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Sunset": {
            "$ref": "#/components/headers/Sunset"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    }
  }
}
