{
  "openapi": "3.1.0",
  "info": {
    "title": "Redlisten API",
    "version": "1.0.0",
    "summary": "Reddit posts, comments, search, keyword streams and trends as an API.",
    "description": "Every public post and comment on Reddit, seconds after it is posted. Native /v1 endpoints plus the Reddit listing paths (/r/{sub}/new.json, /comments/{id}, /user/{name}, /search) with the same response layout. Get a free key at https://app.redlisten.com. Docs at https://redlisten.com/docs.",
    "contact": {
      "email": "support@redlisten.com",
      "url": "https://redlisten.com"
    },
    "termsOfService": "https://redlisten.com/terms",
    "x-logo": {
      "url": "https://redlisten.com/icon-512.png",
      "backgroundColor": "#000000",
      "altText": "Redlisten"
    }
  },
  "servers": [
    {
      "url": "https://api.redlisten.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    },
    {
      "apiKeyQuery": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer rl_live_..."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      },
      "apiKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "key",
        "description": "For RSS readers that cannot set headers."
      }
    },
    "parameters": {
      "limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000
        },
        "description": "Page size. Clamped to the plan's page size (50 Free, 250 Pro, 1000 Team and above)."
      },
      "cursor": {
        "name": "cursor",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "next_cursor from a previous page, or 'latest' to start from now."
      },
      "since": {
        "name": "since",
        "in": "query",
        "schema": {
          "type": "string",
          "format": "date-time"
        },
        "description": "ISO 8601 time to start from. Ignored when cursor is set."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "status": {
                "type": "integer"
              },
              "code": {
                "type": "string",
                "description": "quota_exceeded, items_quota_exceeded, plan_required, rate_limited"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "Page": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "next_cursor": {
            "type": "string"
          },
          "has_more": {
            "type": "boolean"
          }
        }
      },
      "Post": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "subreddit": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "selftext": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "score": {
            "type": "integer"
          },
          "num_comments": {
            "type": "integer"
          },
          "created_utc": {
            "type": "number"
          },
          "permalink": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "live, removed or deleted"
          }
        }
      },
      "Comment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "subreddit": {
            "type": "string"
          },
          "author": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "score": {
            "type": "integer"
          },
          "link_id": {
            "type": "string"
          },
          "created_utc": {
            "type": "number"
          },
          "permalink": {
            "type": "string"
          },
          "status": {
            "type": "string"
          }
        }
      },
      "StreamDefinition": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80
          },
          "any": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "all": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subreddits": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude_subreddits": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "authors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "post",
                "comment"
              ]
            }
          },
          "nsfw": {
            "type": "boolean"
          }
        }
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "webhook_url": {
            "type": "string",
            "format": "uri"
          },
          "webhook_secret": {
            "type": "string"
          },
          "slack_webhook": {
            "type": "string",
            "format": "uri"
          },
          "discord_webhook": {
            "type": "string",
            "format": "uri"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "digest": {
            "type": "string",
            "enum": [
              "daily",
              "weekly"
            ],
            "nullable": true
          }
        }
      }
    }
  },
  "paths": {
    "/health": {
      "get": {
        "summary": "Service health",
        "security": [],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "summary": "Plan, limits and usage for this key",
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/status": {
      "get": {
        "summary": "Feed status: volumes and delivery lag",
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/posts": {
      "get": {
        "summary": "Live feed of every new post, in arrival order",
        "description": "Counts items delivered against the plan's monthly feed item allowance.",
        "parameters": [
          {
            "$ref": "#/components/parameters/cursor"
          },
          {
            "$ref": "#/components/parameters/since"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page"
                }
              }
            }
          },
          "429": {
            "description": "rate or quota limit",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/posts/{id}": {
      "get": {
        "summary": "One post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          },
          "404": {
            "description": "not found"
          }
        }
      }
    },
    "/v1/posts/{id}/comments": {
      "get": {
        "summary": "Comments on a post, newest first",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/comments": {
      "get": {
        "summary": "Live feed of every new comment, in arrival order",
        "parameters": [
          {
            "$ref": "#/components/parameters/cursor"
          },
          {
            "$ref": "#/components/parameters/since"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page"
                }
              }
            }
          }
        }
      }
    },
    "/v1/comments/{id}": {
      "get": {
        "summary": "One comment",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/authors/{name}/posts": {
      "get": {
        "summary": "Posts by an author, newest first",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/authors/{name}/comments": {
      "get": {
        "summary": "Comments by an author, newest first",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/streams": {
      "get": {
        "summary": "List keyword streams on this key",
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      },
      "post": {
        "summary": "Create a keyword stream",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StreamDefinition"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "created"
          },
          "403": {
            "description": "stream cap reached"
          }
        }
      }
    },
    "/v1/streams/{id}": {
      "get": {
        "summary": "Stream definition and status",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      },
      "patch": {
        "summary": "Set delivery for a stream (webhook, Slack, Discord, email digest)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "delivery": {
                    "$ref": "#/components/schemas/Delivery"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ok"
          },
          "403": {
            "description": "plan_required"
          }
        }
      },
      "delete": {
        "summary": "Delete a stream",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "deleted"
          }
        }
      }
    },
    "/v1/streams/{id}/items": {
      "get": {
        "summary": "Matches collected by a stream",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/cursor"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page"
                }
              }
            }
          }
        }
      }
    },
    "/v1/streams/{id}/volume": {
      "get": {
        "summary": "Match counts per hour or day",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "interval",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hour",
                "day"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/streams/{id}/live": {
      "get": {
        "summary": "Server sent events of new matches (Business)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "text/event-stream"
          }
        }
      }
    },
    "/v1/streams/{id}/exports": {
      "get": {
        "summary": "Daily JSONL exports of a stream (Business)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/live": {
      "get": {
        "summary": "Server sent events of every new post or comment (Business)",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "posts",
                "comments"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "text/event-stream"
          }
        }
      }
    },
    "/v1/trends": {
      "get": {
        "summary": "Mentions of a term per hour or day (Pro and above)",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "interval",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hour",
                "day"
              ]
            }
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/trends/compare": {
      "get": {
        "summary": "Up to five terms side by side (Team and above)",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Comma separated terms"
          },
          {
            "name": "interval",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hour",
                "day"
              ]
            }
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/v1/trends/communities": {
      "get": {
        "summary": "Subreddits that mention a term most (Team and above)",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 30
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/r/{subreddit}/new.json": {
      "get": {
        "summary": "Reddit style listing of new posts in a subreddit (use 'all' for everything, a+b for several)",
        "parameters": [
          {
            "name": "subreddit",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100
            }
          },
          {
            "name": "after",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reddit Listing"
          }
        }
      }
    },
    "/r/{subreddit}/new.rss": {
      "get": {
        "summary": "Atom feed of new posts in the layout Reddit served. Pass the key as ?key=",
        "parameters": [
          {
            "name": "subreddit",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "application/atom+xml"
          }
        }
      }
    },
    "/r/{subreddit}/comments.json": {
      "get": {
        "summary": "Reddit style listing of new comments in a subreddit",
        "parameters": [
          {
            "name": "subreddit",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reddit Listing"
          }
        }
      }
    },
    "/r/{subreddit}/about.json": {
      "get": {
        "summary": "Subreddit summary",
        "parameters": [
          {
            "name": "subreddit",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok"
          }
        }
      }
    },
    "/comments/{id}.json": {
      "get": {
        "summary": "A post and its comment tree, Reddit layout",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "new",
                "old",
                "top"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 2000
            }
          },
          {
            "name": "depth",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "[post listing, comment listing]"
          }
        }
      }
    },
    "/user/{name}.json": {
      "get": {
        "summary": "A user's recent posts and comments, Reddit layout (also /submitted and /comments)",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reddit Listing"
          }
        }
      }
    },
    "/search.json": {
      "get": {
        "summary": "Full text search, Reddit layout. AND, OR, NOT, quotes, subreddit:, author:",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "link",
                "comment",
                "link,comment"
              ]
            }
          },
          {
            "name": "t",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hour",
                "day",
                "week",
                "month",
                "year"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "maximum": 100
            }
          },
          {
            "name": "after",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Reddit Listing"
          }
        }
      }
    },
    "/api/info.json": {
      "get": {
        "summary": "Look up posts and comments by fullname",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Comma separated t3_ and t1_ ids, up to 100"
          }
        ],
        "responses": {
          "200": {
            "description": "Reddit Listing"
          }
        }
      }
    },
    "/api/v1/access_token": {
      "post": {
        "summary": "Token endpoint for PRAW and other OAuth clients. Basic auth with client_id = your API key.",
        "security": [],
        "responses": {
          "200": {
            "description": "{access_token, token_type, expires_in}"
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "summary": "MCP server (streamable HTTP). Authorization: Bearer rl_live_...",
        "responses": {
          "200": {
            "description": "MCP response"
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Redlisten documentation",
    "url": "https://redlisten.com/docs"
  }
}