{
  "openapi": "3.1.1",
  "info": {
    "title": "Feedmesh API",
    "description": "The REST API behind the Feedmesh apps, for your own scripts and apps. Guides, examples and terms: https://feedmesh.com/developers\n\n**Signing in.** Send `Authorization: Bearer <token>` with every request: a personal access token (`fm_pat_…`, made on feedmesh.com under Account > Developer) or, for an app other people sign in to, an OAuth access token (authorization code flow with PKCE; the app registers itself: https://feedmesh.com/developers/api#oauth). Tokens carry scopes: `feeds.read` for reading (GET) and `feeds.write` for changes. The API is part of Feedmesh Plus (https://feedmesh.com/plus): an account without it is refused with 403 and the code `plus_required` (only `GET /me/plan` answers any account).\n\n**Paging.** Lists that page take `limit` (how many, 25 by default and at most 100) and `cursor`. Each page has `nextCursor`: pass it as `cursor` for the next page; it's null on the last page. Cursors are opaque, so don't build or change them. A page can come back with fewer items than `limit` (muted articles are left out) and still have a `nextCursor`.\n\n**Errors.** Errors are RFC 9457 problem details (`application/problem+json`, the `Problem` schema) with a stable `code` to switch on, for example `{\"type\":\"https://feedmesh.com/api/v2/errors/already-subscribed\",\"title\":\"Already subscribed to that feed.\",\"status\":409,\"code\":\"already_subscribed\"}`. The `title` is for people and may change. 400 is bad input, 401 a missing or expired token, 403 a missing scope (`insufficient_scope`) or plan (`plus_required`), 404 something that isn't there or isn't yours, 409 a conflict such as a duplicate or a limit.\n\n**Full text.** Lists and search carry titles, links and other details, never the full text. It comes one article at a time, when you ask for it (`GET /items/{id}?fullText=true` or `GET /items/{id}/fulltext`), like a browser's Reader View: 300 a day on Plus, one count shared with the MCP server's `get_article` (Free's 10 a day are for MCP, as the API is part of Plus).\n\n**Limits.** Each token may make 60 requests a minute; searches and lookups also share a per-minute limit. Over it, the answer is 429; wait for the seconds in `Retry-After` when it's given. Full text and new follows also have daily allowances by plan: when one is used up the answer is 429 with the code `allowance_used`, which allowance (`allowance`), its `limit` and when it resets (`resetsAt`, UTC). `GET /me/plan` shows the plan, its limits and today's use.\n\n**Conventions.** JSON in camelCase; dates in UTC, ISO 8601; IDs are GUIDs as strings. GET answers carry an `ETag`: send it back in `If-None-Match` and an unchanged answer is 304 with no body. Fields may be added over time, so ignore ones you don't know.\n\n**Use.** The API is for your own reading, your own AI assistant and automating your own workflow, through your own account. Don't use it to bulk-export articles, build datasets, republish or redistribute publishers' articles, or train, fine-tune or ground AI models or products that serve anyone but you; and don't use more accounts or tokens to get around the daily amounts. The terms: https://feedmesh.com/terms-of-service#automated-access",
    "version": "2"
  },
  "servers": [
    {
      "url": "https://feedmesh.com/api/v2",
      "description": "Feedmesh"
    }
  ],
  "paths": {
    "/categories": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "List categories",
        "description": "Your categories in their order, and whether any subscriptions aren't in one.\n\nScope: `feeds.read`.",
        "operationId": "listCategories",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoriesResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      },
      "post": {
        "tags": [
          "Feeds"
        ],
        "summary": "Add a category",
        "description": "Makes a new category with this title (1 to 100 characters), last in the list. There can be at most 10 (409 category_limit).\n\nScope: `feeds.write`.",
        "operationId": "addCategory",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CategoryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/categories/order": {
      "put": {
        "tags": [
          "Feeds"
        ],
        "summary": "Order categories",
        "description": "Puts the categories whose IDs are given first, in that order; any left out keep their order after them.\n\nScope: `feeds.write`.",
        "operationId": "orderCategories",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CategoryResponse"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/categories/{id}": {
      "patch": {
        "tags": [
          "Feeds"
        ],
        "summary": "Rename a category",
        "description": "Gives the category a new title (1 to 100 characters).\n\nScope: `feeds.write`.",
        "operationId": "renameCategory",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CategoryRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Feeds"
        ],
        "summary": "Remove a category",
        "description": "Removes the category. Its subscriptions stay, out of any category.\n\nScope: `feeds.write`.",
        "operationId": "removeCategory",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/changes": {
      "post": {
        "tags": [
          "Reading"
        ],
        "summary": "Apply several read and saved changes",
        "description": "Up to 500 changes in one request, applied in order: each is read, unread, save, unsave or readAll, and gets the status its own call would answer (204 done, 404, 400). Sending the same changes twice is harmless.\n\nScope: `feeds.write`.",
        "operationId": "applySeveralReadAndSavedChanges",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/discover/categories": {
      "get": {
        "tags": [
          "Discover & search"
        ],
        "summary": "List topics",
        "description": "Feedmesh's topics (Technology, Sports …) with their tags; search for \"#tag\" to see a tag's feeds.\n\nScope: `feeds.read`.",
        "operationId": "listTopics",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DiscoverCategoryResponse"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/discover/featured": {
      "get": {
        "tags": [
          "Discover & search"
        ],
        "summary": "List popular feeds",
        "description": "Feedmesh's most read feeds, the most read first, and whether you follow each.\n\nScope: `feeds.read`.",
        "operationId": "listPopularFeeds",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DiscoverFeedResponse"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/discover/lookup": {
      "get": {
        "tags": [
          "Discover & search"
        ],
        "summary": "Look up an address",
        "description": "The feeds at a web address (url=), or linked from the page there, each checked that it can be read; problem says why when there are none.\n\nScope: `feeds.read`.",
        "operationId": "lookUpAddress",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoverLookupResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/discover/search": {
      "get": {
        "tags": [
          "Discover & search"
        ],
        "summary": "Search for feeds",
        "description": "Feeds to follow for q (1 to 200 characters): words search Feedmesh's feeds and then the web, \"#tag\" a topic's tag, a web address is looked up, and \"@handle\" finds a YouTube channel. Feeds found on the web have no feedId yet: follow them by url.\n\nScope: `feeds.read`.",
        "operationId": "searchForFeeds",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DiscoverFeedResponse"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/discover/similar": {
      "get": {
        "tags": [
          "Discover & search"
        ],
        "summary": "Find feeds like a subscription",
        "description": "Up to five working feeds like one of your subscriptions (subscription=), the most read first: for one that stopped updating.\n\nScope: `feeds.read`.",
        "operationId": "findFeedsLikeSubscription",
        "parameters": [
          {
            "name": "subscription",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DiscoverFeedResponse"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/items/{id}": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "Get an article",
        "description": "An article as opened from one of your subscriptions (subscription=) or lists (list=saved or recent), with its summary and the articles before and after it there. fullText=true sends the full text instead, which counts against the day's full-text allowance (300 a day on Plus, shared with MCP) when Feedmesh has one (fullTextAvailable).\n\nScope: `feeds.read`.",
        "operationId": "getArticle",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subscription",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "list",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "fullText",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/items/{id}/fulltext": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "Get an article's full text",
        "description": "Just the article's full text, as Feedmesh read it from the site, for one article in one of your subscriptions (subscription=) or lists (list=), when you ask for it. One article a request; each counts against the day's full-text allowance (300 a day on Plus, shared with MCP), unless Feedmesh has no full text for it: then fullText is the feed's summary (or null), fullTextAvailable is false, and it doesn't count.\n\nScope: `feeds.read`.",
        "operationId": "getArticlesFullText",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subscription",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "list",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FullTextResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/items/{id}/read": {
      "put": {
        "tags": [
          "Reading"
        ],
        "summary": "Mark an article read",
        "description": "Marks the article read in the subscription it's in (subscription=, required). Doing it twice is harmless.\n\nScope: `feeds.write`.",
        "operationId": "markArticleRead",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subscription",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Reading"
        ],
        "summary": "Mark an article unread",
        "description": "Marks the article unread again in the subscription it's in (subscription=, required).\n\nScope: `feeds.write`.",
        "operationId": "markArticleUnread",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subscription",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/items/{id}/saved": {
      "put": {
        "tags": [
          "Reading"
        ],
        "summary": "Save an article",
        "description": "Adds the article to your saved articles. Saving it twice is harmless.\n\nScope: `feeds.write`.",
        "operationId": "saveArticle",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Reading"
        ],
        "summary": "Unsave an article",
        "description": "Takes the article out of your saved articles.\n\nScope: `feeds.write`.",
        "operationId": "unsaveArticle",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/local/follows": {
      "get": {
        "tags": [
          "Local News"
        ],
        "summary": "List followed places",
        "description": "The places you follow, each with its town's scout and how many sources it has found since you followed.\n\nScope: `feeds.read`.",
        "operationId": "listFollowedPlaces",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FollowResponse"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/local/follows/{id}": {
      "patch": {
        "tags": [
          "Local News"
        ],
        "summary": "Keep or stop adding a place's sources",
        "description": "keepAdding false stops adding the sources the scout finds for the place (true starts again); the feeds you follow stay.\n\nScope: `feeds.write`.",
        "operationId": "keepOrStopAddingPlacesSources",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeepAddingRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Local News"
        ],
        "summary": "Unfollow a place",
        "description": "Forgets the followed place; the feeds you follow from it stay.\n\nScope: `feeds.write`.",
        "operationId": "unfollowPlace",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/local/follows/{id}/found": {
      "get": {
        "tags": [
          "Local News"
        ],
        "summary": "List what the scout found",
        "description": "The sources the scout found for a followed place's town, the newest first: which were found since you followed it, and which you follow.\n\nScope: `feeds.read`.",
        "operationId": "listWhatScoutFound",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FoundSource"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/local/places": {
      "get": {
        "tags": [
          "Local News"
        ],
        "summary": "Find a place",
        "description": "Places matching a ZIP code or a town's name (q=, as in \"58102\", \"Fargo\" or \"Fargo, ND\"), up to 10, the biggest first.\n\nScope: `feeds.read`.",
        "operationId": "findPlace",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "How many to return: 25 by default, at most 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PlaceResponse"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/local/places/{id}": {
      "get": {
        "tags": [
          "Local News"
        ],
        "summary": "List a place's local sources",
        "description": "The news sources near a place in their groups (newspapers, TV, radio, local sites, statewide, local government), nearest first, with which ones you follow, the scout's state for its town, and your follow of the place.\n\nScope: `feeds.read`.",
        "operationId": "listPlacesLocalSources",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaceSourcesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/local/places/{id}/follow": {
      "post": {
        "tags": [
          "Local News"
        ],
        "summary": "Follow a place",
        "description": "Follows the sources picked (feedIds, any near the place; ones you follow already are skipped) into a category (categoryId or newCategoryTitle, or none), as their own subscriptions or, with asOneFeed, as one merged feed. keepAdding (on unless false) adds what the scout finds later, and the town is scouted if it never was.\n\nScope: `feeds.write`.",
        "operationId": "followPlace",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FollowRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowResult"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/local/places/{id}/scout": {
      "post": {
        "tags": [
          "Local News"
        ],
        "summary": "Ask the scout to look for more sources",
        "description": "Asks Feedmesh's scout to look for more news sources around the place's town (no follow needed), unless one is under way or the last finished under a day ago. It works in the background; the answer is its state.\n\nScope: `feeds.write`.",
        "operationId": "askScoutToLookForMoreSources",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScoutState"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/me/plan": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get your plan and usage",
        "description": "The account's plan (free, plus, pro or builder), its daily limits (-1: no limit), what's been used today, what's left (remainingToday, -1: no limit) and when that resets (midnight UTC). Full texts are one count for the REST API and MCP.\n\nScope: `feeds.read`.",
        "operationId": "getYourPlanAndUsage",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/notifications": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "List notification settings",
        "description": "The subscriptions that notify you of new articles, each with its keywords (none: every new article). They're the same on every device.\n\nScope: `feeds.read`.",
        "operationId": "listNotificationSettings",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsResponse"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/recent": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "List recently read articles",
        "description": "A page of the articles you read lately, the most recent first.\n\nScope: `feeds.read`.",
        "operationId": "listRecentlyReadArticles",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "The previous page's nextCursor, for the next page; leave it out for the first.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "How many to return: 25 by default, at most 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/saved": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "List saved articles",
        "description": "A page of the articles you saved, the most recently saved first.\n\nScope: `feeds.read`.",
        "operationId": "listSavedArticles",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "The previous page's nextCursor, for the next page; leave it out for the first.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "How many to return: 25 by default, at most 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/search": {
      "get": {
        "tags": [
          "Discover & search"
        ],
        "summary": "Search your articles",
        "description": "Articles in the feeds you follow (or in one subscription, subscription=) whose title, summary or author match q (2 to 200 characters): those with every word, or with any of them when none has them all (someWords). Best match first, or sort=newest.\n\nScope: `feeds.read`.",
        "operationId": "searchYourArticles",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "subscription",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "The previous page's nextCursor, for the next page; leave it out for the first.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "How many to return: 25 by default, at most 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/subscriptions": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "List subscriptions",
        "description": "Your subscriptions in their order, each with its feeds and whether they're updating. category= limits it to one category's (its ID), or \"none\" for the ones not in a category.\n\nScope: `feeds.read`.",
        "operationId": "listSubscriptions",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubscriptionResponse"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      },
      "post": {
        "tags": [
          "Feeds"
        ],
        "summary": "Follow a feed",
        "description": "Subscribes to a feed by its ID (feedId, from discover or search) or by a web address (url), which is looked up; crawlMode \"page\" watches a page without a feed. Answers 409 already_subscribed, 409 similar_feed (a feed with a very similar address exists; send similarityCheck false to add it anyway), 410 feed_ended or 422 when no feed is found. Each follow counts against the day's allowance.\n\nScope: `feeds.write`.",
        "operationId": "followFeed",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/merge": {
      "post": {
        "tags": [
          "Feeds"
        ],
        "summary": "Merge subscriptions",
        "description": "Combines two or more subscriptions into one stream of articles, named with the title given, if any.\n\nScope: `feeds.write`.",
        "operationId": "mergeSubscriptions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MergeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/order": {
      "put": {
        "tags": [
          "Feeds"
        ],
        "summary": "Order subscriptions",
        "description": "Within each category, the subscriptions whose IDs are given take its places in that order.\n\nScope: `feeds.write`.",
        "operationId": "orderSubscriptions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/remove": {
      "post": {
        "tags": [
          "Feeds"
        ],
        "summary": "Unfollow several subscriptions",
        "description": "Removes the subscriptions whose IDs are given; IDs that aren't yours are ignored.\n\nScope: `feeds.write`.",
        "operationId": "unfollowSeveralSubscriptions",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/unread": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "Count unread articles",
        "description": "Each subscription's unread articles over the last days (30 by default, at most 90), up to 99; capped is true when there are more. Muted articles don't count.\n\nScope: `feeds.read`.",
        "operationId": "countUnreadArticles",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnreadResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "Get a subscription",
        "description": "One of your subscriptions, with its feeds and whether they're updating.\n\nScope: `feeds.read`.",
        "operationId": "getSubscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      },
      "patch": {
        "tags": [
          "Feeds"
        ],
        "summary": "Change a subscription",
        "description": "Changes only what's given: title (\"\" goes back to the feed's own), color (a hex color, \"\" for the default), category (a category ID, or \"none\" to move it out of any) and muteWords (articles mentioning one are hidden).\n\nScope: `feeds.write`.",
        "operationId": "changeSubscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Feeds"
        ],
        "summary": "Unfollow a subscription",
        "description": "Removes the subscription, with its read and notification settings.\n\nScope: `feeds.write`.",
        "operationId": "unfollowSubscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}/feeds/{feedId}": {
      "delete": {
        "tags": [
          "Feeds"
        ],
        "summary": "Take a feed out of a merged subscription",
        "description": "Removes one feed from a merged subscription; keepAsOwn=true keeps it as a subscription of its own. A subscription's only feed can't be taken out (409 last_feed).\n\nScope: `feeds.write`.",
        "operationId": "takeFeedOutOfMergedSubscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "feedId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "keepAsOwn",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RemoveFeedResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}/items": {
      "get": {
        "tags": [
          "Reading"
        ],
        "summary": "List a subscription's articles",
        "description": "A page of the subscription's articles, newest first, without the ones its mute words hide. unreadOnly=true leaves out read ones (left out, it follows the account's Hide read articles setting).\n\nScope: `feeds.read`.",
        "operationId": "listSubscriptionsArticles",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "The previous page's nextCursor, for the next page; leave it out for the first.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "How many to return: 25 by default, at most 100.",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "unreadOnly",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.read"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}/notifications": {
      "put": {
        "tags": [
          "Notifications"
        ],
        "summary": "Turn on a subscription's notifications",
        "description": "Notifies you of the subscription's new articles: every one, or with keywords (up to 50) only those that mention one. Sending it again replaces the keywords.\n\nScope: `feeds.write`.",
        "operationId": "turnOnSubscriptionsNotifications",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Notifications"
        ],
        "summary": "Turn off a subscription's notifications",
        "description": "Stops notifications for the subscription's new articles.\n\nScope: `feeds.write`.",
        "operationId": "turnOffSubscriptionsNotifications",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}/read": {
      "post": {
        "tags": [
          "Reading"
        ],
        "summary": "Mark a subscription read",
        "description": "Marks everything in the subscription read up to now, or up to readTo (never in the future, and never earlier than a date already marked).\n\nScope: `feeds.write`.",
        "operationId": "markSubscriptionRead",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/MarkAllReadRequest"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}/replace": {
      "post": {
        "tags": [
          "Feeds"
        ],
        "summary": "Replace a subscription's feed",
        "description": "The subscription reads this feed (feedId or url, as when following) instead of its own, keeping its place, category, name, color and mute words. For a feed that stopped updating or moved.\n\nScope: `feeds.write`.",
        "operationId": "replaceSubscriptionsFeed",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    },
    "/subscriptions/{id}/split": {
      "post": {
        "tags": [
          "Feeds"
        ],
        "summary": "Split a merged subscription",
        "description": "Turns a merged subscription back into one subscription per feed (409 not_merged if it has only one).\n\nScope: `feeds.write`.",
        "operationId": "splitMergedSubscription",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SplitResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/400"
          },
          "401": {
            "$ref": "#/components/responses/401"
          },
          "403": {
            "$ref": "#/components/responses/403"
          },
          "404": {
            "$ref": "#/components/responses/404"
          },
          "429": {
            "$ref": "#/components/responses/429"
          }
        },
        "security": [
          {
            "bearer": [
              "feeds.write"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AddRequest": {
        "required": [
          "url",
          "feedId",
          "categoryId",
          "crawlMode",
          "similarityCheck"
        ],
        "type": "object",
        "properties": {
          "url": {
            "type": [
              "null",
              "string"
            ]
          },
          "feedId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "categoryId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "crawlMode": {
            "type": [
              "null",
              "string"
            ]
          },
          "similarityCheck": {
            "type": [
              "null",
              "boolean"
            ]
          }
        }
      },
      "Block": {
        "required": [
          "type"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "spans": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Span"
            }
          },
          "items": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Span"
              }
            }
          },
          "paragraphs": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Span"
              }
            }
          }
        }
      },
      "CategoriesResponse": {
        "required": [
          "categories",
          "hasUncategorized"
        ],
        "type": "object",
        "properties": {
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CategoryResponse"
            }
          },
          "hasUncategorized": {
            "type": "boolean"
          }
        }
      },
      "CategoryRequest": {
        "required": [
          "title"
        ],
        "type": "object",
        "properties": {
          "title": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "CategoryResponse": {
        "required": [
          "id",
          "title",
          "order"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "order": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "Change": {
        "required": [
          "type",
          "item",
          "subscription",
          "readTo"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "null",
              "string"
            ]
          },
          "item": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "subscription": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "readTo": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "ChangeRequest": {
        "required": [
          "title",
          "color",
          "category",
          "muteWords"
        ],
        "type": "object",
        "properties": {
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "color": {
            "type": [
              "null",
              "string"
            ]
          },
          "category": {
            "type": [
              "null",
              "string"
            ]
          },
          "muteWords": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ChangeResult": {
        "required": [
          "status",
          "code"
        ],
        "type": "object",
        "properties": {
          "status": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "code": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ChangesRequest": {
        "required": [
          "changes"
        ],
        "type": "object",
        "properties": {
          "changes": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Change"
            }
          }
        }
      },
      "ChangesResponse": {
        "required": [
          "results"
        ],
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangeResult"
            }
          }
        }
      },
      "DiscoverCategoryResponse": {
        "required": [
          "id",
          "title",
          "tags",
          "iconUrl"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "iconUrl": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "DiscoverFeedResponse": {
        "required": [
          "feedId",
          "title",
          "description",
          "url",
          "favIconUrl",
          "favIconLargeUrl",
          "readers",
          "articlesPerWeek",
          "subscribed",
          "inFeedmesh"
        ],
        "type": "object",
        "properties": {
          "feedId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "description": {
            "type": [
              "null",
              "string"
            ]
          },
          "url": {
            "type": [
              "null",
              "string"
            ]
          },
          "favIconUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "favIconLargeUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "readers": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "articlesPerWeek": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "subscribed": {
            "type": "boolean"
          },
          "inFeedmesh": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "default": "ok"
          },
          "lastSuccess": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "lastArticle": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "youTube": {
            "type": "boolean",
            "default": false
          },
          "imageUrl": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "DiscoverLookupResponse": {
        "required": [
          "feeds",
          "problem"
        ],
        "type": "object",
        "properties": {
          "feeds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DiscoverFeedResponse"
            }
          },
          "problem": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "FeedResponse": {
        "required": [
          "id",
          "title",
          "link",
          "favIconUrl",
          "enabled",
          "dateAdded",
          "dateLastChecked"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "link": {
            "type": [
              "null",
              "string"
            ]
          },
          "favIconUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "dateAdded": {
            "type": "string",
            "format": "date-time"
          },
          "dateLastChecked": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "default": "ok"
          },
          "dateLastSuccess": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "dateLastItemAdded": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "statusNote": {
            "type": [
              "null",
              "string"
            ]
          },
          "dateEnded": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "FollowRequest": {
        "required": [
          "feedIds",
          "categoryId",
          "newCategoryTitle",
          "asOneFeed",
          "oneFeedTitle",
          "keepAdding"
        ],
        "type": "object",
        "properties": {
          "feedIds": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "categoryId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "newCategoryTitle": {
            "type": [
              "null",
              "string"
            ]
          },
          "asOneFeed": {
            "type": [
              "null",
              "boolean"
            ]
          },
          "oneFeedTitle": {
            "type": [
              "null",
              "string"
            ]
          },
          "keepAdding": {
            "type": [
              "null",
              "boolean"
            ]
          }
        }
      },
      "FollowResponse": {
        "required": [
          "id",
          "placeId",
          "label",
          "categoryId",
          "subscriptionId",
          "keepAdding",
          "dateAdded"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "placeId": {
            "type": "string"
          },
          "label": {
            "type": [
              "null",
              "string"
            ]
          },
          "categoryId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "subscriptionId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "keepAdding": {
            "type": "boolean"
          },
          "dateAdded": {
            "type": "string",
            "format": "date-time"
          },
          "scout": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/ScoutState"
              }
            ]
          },
          "newSources": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "default": 0
          },
          "lastNewSource": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "oneFeedTitle": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "FollowResult": {
        "required": [
          "follow",
          "subscriptionIds",
          "alreadyFollowed",
          "scout"
        ],
        "type": "object",
        "properties": {
          "follow": {
            "$ref": "#/components/schemas/FollowResponse"
          },
          "subscriptionIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "alreadyFollowed": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "scout": {
            "$ref": "#/components/schemas/ScoutState"
          }
        }
      },
      "FoundSource": {
        "required": [
          "feedId",
          "title",
          "siteUrl",
          "kind",
          "website",
          "status",
          "dateFound",
          "sinceFollowed",
          "inYourFeeds"
        ],
        "type": "object",
        "properties": {
          "feedId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "siteUrl": {
            "type": "string"
          },
          "kind": {
            "type": [
              "null",
              "string"
            ]
          },
          "website": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "dateFound": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "sinceFollowed": {
            "type": "boolean"
          },
          "inYourFeeds": {
            "type": "boolean"
          }
        }
      },
      "FullTextResponse": {
        "required": [
          "id",
          "fullText",
          "fullTextAvailable"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullText": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Block"
            }
          },
          "fullTextAvailable": {
            "type": "boolean"
          }
        }
      },
      "ItemResponse": {
        "required": [
          "id",
          "subscriptionId",
          "title",
          "author",
          "link",
          "shareUrl",
          "datePublished",
          "dateAdded",
          "wordCount",
          "readTimeMinutes",
          "hasMainImage",
          "imageUrl",
          "largeImageUrl",
          "isRead",
          "isSaved",
          "subscriptionTitle",
          "color",
          "feedId",
          "feedTitle",
          "feedFavIconUrl",
          "fullTextAvailable",
          "content",
          "fullText",
          "position",
          "total",
          "previousId",
          "nextId"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "subscriptionId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "author": {
            "type": [
              "null",
              "string"
            ]
          },
          "link": {
            "type": [
              "null",
              "string"
            ]
          },
          "shareUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "datePublished": {
            "type": "string",
            "format": "date-time"
          },
          "dateAdded": {
            "type": "string",
            "format": "date-time"
          },
          "wordCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "readTimeMinutes": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "hasMainImage": {
            "type": "boolean"
          },
          "imageUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "largeImageUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "isRead": {
            "type": "boolean"
          },
          "isSaved": {
            "type": "boolean"
          },
          "subscriptionTitle": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "feedId": {
            "type": "string",
            "format": "uuid"
          },
          "feedTitle": {
            "type": [
              "null",
              "string"
            ]
          },
          "feedFavIconUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "fullTextAvailable": {
            "type": "boolean"
          },
          "content": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Block"
            }
          },
          "fullText": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "$ref": "#/components/schemas/Block"
            }
          },
          "position": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "previousId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "nextId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "videoId": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "ItemsResponse": {
        "required": [
          "items",
          "nextCursor",
          "feedCount",
          "feedsCrawled"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ItemSummary"
            }
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          },
          "feedCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "feedsCrawled": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "status": {
            "type": "string",
            "default": "ok"
          },
          "lastSuccess": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "statusNote": {
            "type": [
              "null",
              "string"
            ]
          },
          "dateEnded": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "ItemSummary": {
        "required": [
          "id",
          "title",
          "author",
          "datePublished",
          "dateAdded",
          "hasMainImage",
          "previewImageUrl",
          "wordCount",
          "isRead",
          "feedId",
          "feedTitle"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "author": {
            "type": [
              "null",
              "string"
            ]
          },
          "datePublished": {
            "type": "string",
            "format": "date-time"
          },
          "dateAdded": {
            "type": "string",
            "format": "date-time"
          },
          "hasMainImage": {
            "type": "boolean"
          },
          "previewImageUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "wordCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "isRead": {
            "type": "boolean"
          },
          "feedId": {
            "type": "string",
            "format": "uuid"
          },
          "feedTitle": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "KeepAddingRequest": {
        "required": [
          "keepAdding"
        ],
        "type": "object",
        "properties": {
          "keepAdding": {
            "type": [
              "null",
              "boolean"
            ]
          }
        }
      },
      "LimitsResponse": {
        "required": [
          "mcpCallsPerDay",
          "fullTextPerDay",
          "followsPerDay",
          "api",
          "mcpWrite",
          "outboundFeeds"
        ],
        "type": "object",
        "properties": {
          "mcpCallsPerDay": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "fullTextPerDay": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "followsPerDay": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "api": {
            "type": "boolean"
          },
          "mcpWrite": {
            "type": "boolean"
          },
          "outboundFeeds": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "ListItemSummary": {
        "required": [
          "id",
          "title",
          "author",
          "datePublished",
          "dateAdded",
          "hasMainImage",
          "previewImageUrl",
          "wordCount",
          "isRead",
          "feedTitle",
          "subscriptionId",
          "dateSaved"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "author": {
            "type": [
              "null",
              "string"
            ]
          },
          "datePublished": {
            "type": "string",
            "format": "date-time"
          },
          "dateAdded": {
            "type": "string",
            "format": "date-time"
          },
          "hasMainImage": {
            "type": "boolean"
          },
          "previewImageUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "wordCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "isRead": {
            "type": "boolean"
          },
          "feedTitle": {
            "type": [
              "null",
              "string"
            ]
          },
          "subscriptionId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "dateSaved": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "ListResponse": {
        "required": [
          "items",
          "nextCursor"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListItemSummary"
            }
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "LocalSource": {
        "required": [
          "feedId",
          "title",
          "link",
          "kind",
          "scope",
          "town",
          "state",
          "miles",
          "working",
          "website",
          "followed"
        ],
        "type": "object",
        "properties": {
          "feedId": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          },
          "link": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "scope": {
            "type": "string"
          },
          "town": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "miles": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "null",
              "number",
              "string"
            ],
            "format": "double"
          },
          "working": {
            "type": "boolean"
          },
          "website": {
            "type": "boolean"
          },
          "followed": {
            "type": "boolean"
          }
        }
      },
      "MarkAllReadRequest": {
        "required": [
          "readTo"
        ],
        "type": "object",
        "properties": {
          "readTo": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "MergeRequest": {
        "required": [
          "ids",
          "title"
        ],
        "type": "object",
        "properties": {
          "ids": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "title": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "OrderRequest": {
        "required": [
          "ids"
        ],
        "type": "object",
        "properties": {
          "ids": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "PlaceResponse": {
        "required": [
          "id",
          "kind",
          "label",
          "name",
          "state",
          "county",
          "cityId",
          "lat",
          "lon",
          "population",
          "country"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "county": {
            "type": [
              "null",
              "string"
            ]
          },
          "cityId": {
            "type": [
              "null",
              "string"
            ]
          },
          "lat": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "lon": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "population": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "null",
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "country": {
            "type": "string"
          }
        }
      },
      "PlaceSourcesResponse": {
        "required": [
          "place",
          "groups",
          "scout",
          "follow"
        ],
        "type": "object",
        "properties": {
          "place": {
            "$ref": "#/components/schemas/PlaceResponse"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceGroup"
            }
          },
          "scout": {
            "$ref": "#/components/schemas/ScoutState"
          },
          "follow": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/FollowResponse"
              }
            ]
          }
        }
      },
      "PlanResponse": {
        "required": [
          "plan",
          "status",
          "source",
          "currentPeriodEnd",
          "beta",
          "limits",
          "usedToday",
          "resetsAt",
          "remainingToday"
        ],
        "type": "object",
        "properties": {
          "plan": {
            "type": "string"
          },
          "status": {
            "type": [
              "null",
              "string"
            ]
          },
          "source": {
            "type": [
              "null",
              "string"
            ]
          },
          "currentPeriodEnd": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "beta": {
            "type": "boolean"
          },
          "limits": {
            "$ref": "#/components/schemas/LimitsResponse"
          },
          "usedToday": {
            "$ref": "#/components/schemas/UsedResponse"
          },
          "resetsAt": {
            "type": "string",
            "format": "date-time"
          },
          "remainingToday": {
            "$ref": "#/components/schemas/RemainingResponse"
          }
        }
      },
      "Problem": {
        "required": [
          "status",
          "code"
        ],
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "A link naming the kind of error.",
            "format": "uri"
          },
          "title": {
            "type": "string",
            "description": "What went wrong, in a sentence for people."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code."
          },
          "detail": {
            "type": [
              "null",
              "string"
            ],
            "description": "More about it, when there's more to say."
          },
          "code": {
            "type": "string",
            "description": "The stable error code, such as invalid_cursor, plus_required or allowance_used."
          }
        },
        "description": "An error, as RFC 9457 problem details. Switch on code; the title is for people. Some codes add fields (allowance_used: allowance, limit, resetsAt; already_subscribed: subscriptionId; similar_feed: feed)."
      },
      "RemainingResponse": {
        "required": [
          "mcpCalls",
          "fullText",
          "follows"
        ],
        "type": "object",
        "properties": {
          "mcpCalls": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "fullText": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "follows": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      },
      "RemoveFeedResponse": {
        "required": [
          "subscription",
          "own"
        ],
        "type": "object",
        "properties": {
          "subscription": {
            "$ref": "#/components/schemas/SubscriptionResponse"
          },
          "own": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/SubscriptionResponse"
              }
            ]
          }
        }
      },
      "ScoutState": {
        "required": [
          "state",
          "since"
        ],
        "type": "object",
        "properties": {
          "state": {
            "type": "string"
          },
          "since": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "sites": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "default": 0
          },
          "checked": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "default": 0
          },
          "added": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32",
            "default": 0
          },
          "canLookAgain": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "SearchResponse": {
        "required": [
          "items",
          "nextCursor",
          "someWords"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListItemSummary"
            }
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ]
          },
          "someWords": {
            "type": "boolean"
          }
        }
      },
      "SetRequest": {
        "required": [
          "keywords"
        ],
        "type": "object",
        "properties": {
          "keywords": {
            "type": [
              "null",
              "array"
            ],
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SettingResponse": {
        "required": [
          "subscriptionId",
          "keywords"
        ],
        "type": "object",
        "properties": {
          "subscriptionId": {
            "type": "string",
            "format": "uuid"
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SettingsResponse": {
        "required": [
          "subscriptions"
        ],
        "type": "object",
        "properties": {
          "subscriptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SettingResponse"
            }
          }
        }
      },
      "SourceGroup": {
        "required": [
          "group",
          "title",
          "sources"
        ],
        "type": "object",
        "properties": {
          "group": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocalSource"
            }
          }
        }
      },
      "Span": {
        "required": [
          "text"
        ],
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "href": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "SplitResponse": {
        "required": [
          "subscriptions"
        ],
        "type": "object",
        "properties": {
          "subscriptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SubscriptionResponse"
            }
          }
        }
      },
      "SubscriptionResponse": {
        "required": [
          "id",
          "title",
          "color",
          "categoryId",
          "order",
          "muteWords",
          "favIconUrl",
          "dateAdded",
          "dateReadTo",
          "feeds"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "color": {
            "type": "string"
          },
          "categoryId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid"
          },
          "order": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "muteWords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "favIconUrl": {
            "type": [
              "null",
              "string"
            ]
          },
          "dateAdded": {
            "type": "string",
            "format": "date-time"
          },
          "dateReadTo": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "feeds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FeedResponse"
            }
          },
          "status": {
            "type": "string",
            "default": "ok"
          },
          "statusNote": {
            "type": [
              "null",
              "string"
            ]
          },
          "dateEnded": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "UnreadCount": {
        "required": [
          "id",
          "unread",
          "capped"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "unread": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "capped": {
            "type": "boolean"
          }
        }
      },
      "UnreadResponse": {
        "required": [
          "since",
          "subscriptions"
        ],
        "type": "object",
        "properties": {
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "subscriptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UnreadCount"
            }
          }
        }
      },
      "UsedResponse": {
        "required": [
          "mcpCalls",
          "fullText",
          "follows",
          "apiCalls",
          "readerApiCalls"
        ],
        "type": "object",
        "properties": {
          "mcpCalls": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "fullText": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "follows": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "apiCalls": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "readerApiCalls": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          }
        }
      }
    },
    "responses": {
      "400": {
        "description": "The request isn't valid: the problem's code says what (invalid_cursor, invalid_title …).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "401": {
        "description": "No token, or one that has expired or been revoked.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "403": {
        "description": "The token lacks the scope (insufficient_scope), or the account's plan doesn't include this (plus_required).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "404": {
        "description": "Not found, or not the caller's.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "429": {
        "description": "Too many requests (wait for Retry-After), or a daily allowance is used up (allowance_used, with allowance, limit and resetsAt).",
        "headers": {
          "Retry-After": {
            "description": "Seconds to wait before trying again.",
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "description": "A personal access token from feedmesh.com Account > Developer, or an OAuth access token.",
        "scheme": "bearer"
      }
    }
  },
  "tags": [
    {
      "name": "Reading",
      "description": "The articles in your subscriptions, saved and recently read lists; full text; read, unread and saved; unread counts."
    },
    {
      "name": "Feeds",
      "description": "Following and unfollowing feeds, and arranging subscriptions and categories: names, colors, mute words, order, merging."
    },
    {
      "name": "Discover & search",
      "description": "Finding feeds to follow (Feedmesh's topics, popular feeds, search, looking up an address) and searching your articles."
    },
    {
      "name": "Notifications",
      "description": "Which subscriptions notify you of new articles, and for which keywords."
    },
    {
      "name": "Local News",
      "description": "Local news sources near a place (by ZIP code or town), following a place, and asking Feedmesh's scout to look for more."
    },
    {
      "name": "Account",
      "description": "Your plan and today's usage."
    }
  ]
}