{
  "openapi": "3.0.3",
  "info": {
    "title": "RSS to JSON API",
    "version": "1.0.0",
    "description": "Parse RSS 2.0, Atom, and JSON feeds to structured JSON. Auto-discovers feeds from any website URL. Supports single-feed parsing, batch parsing of up to 10 feeds, and configurable item limits. In-memory cache (5-minute TTL) keeps repeated requests fast.\n",
    "contact": {
      "name": "RSS to JSON API Support",
      "email": "api@hiroapp.cc"
    }
  },
  "servers": [
    {
      "url": "https://api.sprytools.com/v1/rss",
      "description": "Production (SpryTools API Gateway)"
    }
  ],
  "tags": [
    {
      "name": "Parse",
      "description": "Parse RSS, Atom and JSON feeds to structured JSON"
    },
    {
      "name": "Discover",
      "description": "Auto-discover feed URLs from a website"
    }
  ],
  "security": [
    {
      "ApiKeyHeader": []
    },
    {
      "RapidApiProxy": []
    }
  ],
  "paths": {
    "/api/v1/parse": {
      "get": {
        "operationId": "parseFeedGet",
        "summary": "Parse a single feed URL",
        "description": "Fetch and parse an RSS 2.0, Atom, or JSON Feed URL. Returns title, items, and metadata. Results are cached for 5 minutes.\n",
        "tags": [
          "Parse"
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Full URL of the RSS/Atom/JSON feed",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "example": "https://feeds.bbci.co.uk/news/rss.xml"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of items to return (max 100)",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Parsed feed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParsedFeed"
                },
                "example": {
                  "title": "BBC News",
                  "link": "https://www.bbc.co.uk/news",
                  "description": "BBC News - Home",
                  "language": "en-gb",
                  "lastBuildDate": "2026-05-28T12:00:00.000Z",
                  "count": 2,
                  "items": [
                    {
                      "title": "Breaking News",
                      "link": "https://www.bbc.co.uk/news/article1",
                      "description": "Summary of the article",
                      "pubDate": "2026-05-28T11:00:00.000Z",
                      "guid": "https://www.bbc.co.uk/news/article1"
                    },
                    {
                      "title": "Another Story",
                      "link": "https://www.bbc.co.uk/news/article2",
                      "description": "Another summary",
                      "pubDate": "2026-05-28T10:00:00.000Z",
                      "guid": "https://www.bbc.co.uk/news/article2"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "parseFeedsBatch",
        "summary": "Parse multiple feeds in batch",
        "description": "Parse up to 10 feed URLs in a single request. Each URL is processed concurrently. Results include per-URL status so partial failures are visible.\n",
        "tags": [
          "Parse"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "urls"
                ],
                "properties": {
                  "urls": {
                    "type": "array",
                    "description": "Feed URLs to parse (max 10)",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "minItems": 1,
                    "maxItems": 10
                  },
                  "limit": {
                    "type": "integer",
                    "description": "Items per feed (max 100)",
                    "default": 20,
                    "minimum": 1,
                    "maximum": 100
                  }
                }
              },
              "example": {
                "urls": [
                  "https://feeds.bbci.co.uk/news/rss.xml",
                  "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml"
                ],
                "limit": 5
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch parse results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchParseResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/api/v1/discover": {
      "get": {
        "operationId": "discoverFeeds",
        "summary": "Auto-discover feed URLs from a website",
        "description": "Crawl a website's HTML and find linked RSS, Atom, and JSON Feed URLs via `<link>` tags and common feed paths.\n",
        "tags": [
          "Discover"
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Website URL to scan for feeds",
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "example": "https://www.bbc.co.uk"
          }
        ],
        "responses": {
          "200": {
            "description": "Discovered feeds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoverResult"
                },
                "example": {
                  "website": "https://www.bbc.co.uk",
                  "count": 3,
                  "feeds": [
                    {
                      "url": "https://feeds.bbci.co.uk/news/rss.xml",
                      "type": "rss",
                      "title": "BBC News"
                    },
                    {
                      "url": "https://feeds.bbci.co.uk/sport/rss.xml",
                      "type": "rss",
                      "title": "BBC Sport"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/UnprocessableEntity"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key passed via the x-api-key header"
      },
      "RapidApiProxy": {
        "type": "apiKey",
        "in": "header",
        "name": "x-rapidapi-proxy-secret",
        "description": "RapidAPI proxy secret (set automatically by RapidAPI)"
      }
    },
    "schemas": {
      "FeedItem": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "link": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "pubDate": {
            "type": "string",
            "format": "date-time"
          },
          "guid": {
            "type": "string"
          },
          "author": {
            "type": "string",
            "nullable": true
          },
          "enclosure": {
            "type": "object",
            "nullable": true
          }
        }
      },
      "ParsedFeed": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "link": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "language": {
            "type": "string",
            "nullable": true
          },
          "lastBuildDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "count": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FeedItem"
            }
          }
        }
      },
      "BatchParseResultItem": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "error"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/ParsedFeed"
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "BatchParseResult": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchParseResultItem"
            }
          }
        }
      },
      "DiscoveredFeed": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "type": {
            "type": "string",
            "enum": [
              "rss",
              "atom",
              "json"
            ]
          },
          "title": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "DiscoverResult": {
        "type": "object",
        "properties": {
          "website": {
            "type": "string",
            "format": "uri"
          },
          "count": {
            "type": "integer"
          },
          "feeds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DiscoveredFeed"
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request — missing or invalid parameters",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Query param 'url' required"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "API key missing",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "API key required"
            }
          }
        }
      },
      "UnprocessableEntity": {
        "description": "Feed URL could not be fetched or parsed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Failed to fetch feed: connection refused"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (100 requests per minute)",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Rate limit exceeded"
            }
          }
        }
      },
      "InternalError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "Internal server error"
            }
          }
        }
      }
    }
  }
}