openapi: 3.0.3
info:
  title: Queso API
  version: 1.0.0
  description: API documentation for Queso services.
paths:
  /api/v1/bookmarks/:
    post:
      operationId: Create Bookmark
      tags:
      - Bookmarks
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookmarkCreate'
        required: true
      security:
      - BearerTokenAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSingleResponse'
          description: ''
        '400':
          description: Invalid bookmark payload
        '401':
          description: Authentication credentials were not provided or invalid
        '500':
          description: Unexpected error while creating bookmark
  /api/v1/bookmarks/{id}/:
    get:
      operationId: Get Bookmark
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSingleResponse'
          description: ''
        '404':
          description: Bookmark not found
        '500':
          description: Unexpected error while retrieving bookmark
    patch:
      operationId: Update Bookmark
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchedBookmarkUpdate'
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSingleResponse'
          description: ''
        '400':
          description: Invalid bookmark update payload
        '404':
          description: Bookmark not found
        '500':
          description: Unexpected error while updating bookmark
    delete:
      operationId: Delete Bookmark
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '204':
          description: Bookmark deleted
        '404':
          description: Bookmark not found
        '500':
          description: Unexpected error while deleting bookmark
  /api/v1/bookmarks/newsletter/:
    get:
      operationId: Generate Newsletter
      description: Creates a personalized newsletter from unread bookmarks.Pass `read_time`
        to control how long the newsletter takes to read
      parameters:
      - in: query
        name: limit
        schema:
          type: integer
        description: Candidate pool size to consider (default 100, max 100).
      - in: query
        name: read_time
        schema:
          type: integer
        description: Optional reading-time target in minutes (default 30). Returns
          unread bookmarks with total estimated time close to this value.
      - in: query
        name: tags
        schema:
          type: string
        description: Optional comma-separated tag list. Matches any provided tag.
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerateNewsletterResponse'
          description: ''
        '400':
          description: Invalid query parameters
        '500':
          description: Unexpected error while generating newsletter
  /api/v1/bookmarks/public/:
    get:
      operationId: List Public Bookmarks
      description: 'Returns only bookmarks tagged with "public". Useful to share bookmarks
        and notes publicly. Rate limit: 10/hour.'
      parameters:
      - in: query
        name: limit
        schema:
          type: integer
        description: Maximum results per page (default 10, max 100).
      - in: query
        name: page
        schema:
          type: integer
        description: Page number to return (default 1).
      - in: query
        name: user_profile_id
        schema:
          type: string
        description: Profile ID of the bookmark owner (8-digit string).
        required: true
      tags:
      - Bookmarks
      security:
      - {}
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkListResponse'
          description: ''
        '400':
          description: Invalid pagination parameters
        '500':
          description: Unexpected error while listing public bookmarks
  /api/v1/bookmarks/tags/:
    get:
      operationId: List Bookmark Tags
      description: Returns all bookmark tags and the count of bookmarks that use the
        tag. Tags are formatted to lowercase with excess whitespace removed
      parameters:
      - in: query
        name: filter
        schema:
          type: string
        description: Optional bookmark filter expression using bracket notation (e.g.
          filter[read][_eq]=false).
      - in: query
        name: search
        schema:
          type: string
        description: Optional bookmark search query before tag counting.
      - in: query
        name: tag
        schema:
          type: string
        description: Single included tag filter. Equivalent to tags[].
      - in: query
        name: tags
        schema:
          type: string
        description: Comma-separated included tags filter. Equivalent to tags[].
      - in: query
        name: tags[]
        schema:
          type: string
        description: Repeatable included tags filter. Counts are computed from bookmarks
          that contain all provided tags.
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkTagListResponse'
          description: ''
        '400':
          description: Invalid filter query
        '500':
          description: Unexpected error while listing bookmark tags
  /api/v1/feeds/:
    get:
      operationId: List all RSS feeds
      tags:
      - RSS
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RSSFeedListResponse'
          description: ''
        '500':
          description: Unexpected error while listing feeds
    post:
      operationId: Subscribe to RSS feed
      tags:
      - RSS
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RSSFeedCreate'
        required: true
      security:
      - BearerTokenAuth: []
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RSSFeedResponse'
          description: ''
        '400':
          description: Invalid RSS feed payload
        '409':
          description: Feed subscription already exists
        '500':
          description: Unexpected error while creating feed
  /api/v1/feeds/{rssFeedId}/:
    get:
      operationId: Get RSS feed subscription
      parameters:
      - in: path
        name: rssFeedId
        schema:
          type: integer
        required: true
      tags:
      - RSS
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RSSFeedResponse'
          description: ''
        '404':
          description: Feed not found or user not subscribed
        '500':
          description: Unexpected error while retrieving feed
    put:
      operationId: Toggle RSS feed visibility
      parameters:
      - in: path
        name: rssFeedId
        schema:
          type: integer
        required: true
      tags:
      - RSS
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RSSFeedUpdateRequest'
        required: true
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RSSFeedResponse'
          description: ''
        '400':
          description: Invalid fields submitted for update
        '404':
          description: Feed not found or user not subscribed
        '500':
          description: Unexpected error while updating feed
    delete:
      operationId: Unsubscribe from RSS feed
      parameters:
      - in: path
        name: rssFeedId
        schema:
          type: integer
        required: true
      tags:
      - RSS
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          description: Feed subscription removed
        '404':
          description: Feed not found or user not subscribed
        '500':
          description: Unexpected error while unsubscribing from feed
  /api/v1/feeds/{rssFeedId}/items/:
    get:
      operationId: Get RSS feed entries
      parameters:
      - in: query
        name: limit
        schema:
          type: integer
        description: Maximum results per page (default 50).
      - in: query
        name: page
        schema:
          type: integer
        description: Page number to return (default 1).
      - in: path
        name: rssFeedId
        schema:
          type: integer
        required: true
      tags:
      - RSS
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RSSItemListResponse'
          description: ''
        '404':
          description: Feed not found or not subscribed
        '500':
          description: Unexpected error while retrieving feed items
  /api/v1/feeds/items/{rssItemId}/:
    get:
      operationId: Get RSS entry details
      parameters:
      - in: path
        name: rssItemId
        schema:
          type: integer
        required: true
      tags:
      - RSS
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RSSItemDetailResponse'
          description: ''
        '404':
          description: RSS item not found or not accessible
        '500':
          description: Unexpected error while retrieving RSS item
  /api/v1/feeds/recent/:
    get:
      operationId: Get recent RSS entries
      parameters:
      - in: query
        name: limit
        schema:
          type: integer
        description: Maximum results per page (default 50).
      - in: query
        name: page
        schema:
          type: integer
        description: Page number to return (default 1).
      tags:
      - RSS
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RSSItemRecentResponse'
          description: ''
        '500':
          description: Unexpected error while retrieving recent RSS items
  /api/v2/bookmarks/:
    get:
      operationId: List Bookmarks V2
      description: Cursor-paginated bookmarks list. Returns lightweight bookmark records
        (notes and snapshot are excluded) and tag facets for the currently filtered
        result set.
      parameters:
      - in: query
        name: bookmark_type
        schema:
          type: string
        description: 'Bookmark type filter: all, is_unread, is_quote, is_til, is_note,
          is_read, bookmarks.'
      - in: query
        name: cursor
        schema:
          type: string
        description: Opaque cursor token from the previous response.
      - in: query
        name: filter
        schema:
          type: string
        description: Optional advanced filter expression using bracket notation.
      - in: query
        name: limit
        schema:
          type: integer
        description: Maximum results per request (default 20, max 100).
      - in: query
        name: search
        schema:
          type: string
        description: Search query applied to bookmark title/link/author/notes.
      - in: query
        name: sort[]
        schema:
          type: string
        description: 'Sort field for cursor pagination. Allowed values: -date_created,
          date_created, -date_updated, date_updated, -estimated_time, estimated_time,
          -published_date, published_date.'
      - in: query
        name: tags[]
        schema:
          type: string
        description: Repeatable tag filter with AND semantics.
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BookmarkV2ListResponse'
          description: ''
        '400':
          description: Invalid query parameters
        '500':
          description: Unexpected error while listing bookmarks
  /api/v2/bookmarks/{id}/notes/:
    get:
      operationId: Get Bookmark Notes
      description: Returns only the notes field for a bookmark.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkNotesResponse'
          description: ''
        '404':
          description: Bookmark not found
  /api/v2/bookmarks/{id}/snapshot/:
    get:
      operationId: Get Bookmark Snapshot
      description: Returns only the snapshot field for a bookmark.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSnapshotResponse'
          description: ''
        '404':
          description: Bookmark not found
  /api/v2/bookmarks/{id}/snapshot/audio/:
    get:
      operationId: Get Bookmark Snapshot Audio
      description: Returns a short-lived, pre-signed URL to the bookmark's snapshot
        audio in the file vault. The URL is valid for `QUESO_BOOKMARK_AUDIO_URL_EXPIRY_SECONDS`
        seconds. Returns 404 if audio has not yet been synthesized (`snapshot_audio_status
        != 'ready'`).
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSnapshotAudioResponse'
          description: ''
        '404':
          description: Bookmark not found or audio not ready
    post:
      operationId: Generate Bookmark Snapshot Audio
      description: Creates an audio version of the saved article or blog post so you
        can listen to it. Generation continues in the background when the response
        status is `pending`. Check the bookmark snapshot for its current audio status,
        then use the snapshot audio endpoint to get a playback URL when it is `ready`.
        If audio is already available, this returns `ready` without generating it
        again.
      parameters:
      - in: path
        name: id
        schema:
          type: string
          format: uuid
        required: true
      tags:
      - Bookmarks
      security:
      - BearerTokenAuth: []
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSnapshotAudioGenerationResponse'
          description: ''
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookmarkSnapshotAudioGenerationResponse'
          description: ''
        '400':
          description: The bookmark does not have a saved article snapshot
        '404':
          description: Bookmark not found
        '429':
          description: Audio generation rate limit reached
        '503':
          description: Audio generation is busy; try again in a few minutes
components:
  schemas:
    BookmarkCreate:
      type: object
      description: Serializer for creating bookmarks
      properties:
        title:
          type: string
          maxLength: 500
        link:
          type: string
          format: uri
          maxLength: 2048
        author:
          type: string
          default: ''
          maxLength: 255
        estimated_time:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          default: 0
        is_quote:
          type: boolean
          default: false
        is_til:
          type: boolean
          default: false
        is_note:
          type: boolean
          default: false
        tags:
          type: array
          items:
            type: string
        read:
          type: boolean
          default: false
        notes:
          type: string
          default: ''
        snapshot:
          type: string
          default: ''
        meta_image:
          type: string
          format: uri
          default: ''
          maxLength: 2048
        published_date:
          type: string
          format: date-time
          nullable: true
        source_type:
          enum:
          - manual
          - rss
          - import
          type: string
          description: |-
            * `manual` - Manual
            * `rss` - RSS
            * `import` - Import
          x-spec-enum-id: debedf0966278d87
          default: manual
        source_id:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
        is_favorite:
          type: boolean
          default: false
      required:
      - title
    BookmarkListMeta:
      type: object
      properties:
        total_count:
          type: integer
        filter_count:
          type: integer
      required:
      - total_count
    BookmarkListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/BookmarkResponse'
        meta:
          $ref: '#/components/schemas/BookmarkListMeta'
      required:
      - data
      - meta
    BookmarkLite:
      type: object
      description: Bookmark serializer without heavy text fields for v2 list API.
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        date_created:
          type: string
          format: date-time
          readOnly: true
        date_updated:
          type: string
          format: date-time
          readOnly: true
        title:
          type: string
          maxLength: 500
        link:
          type: string
          format: uri
          maxLength: 2048
        author:
          type: string
          maxLength: 255
        estimated_time:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
        is_quote:
          type: boolean
        is_til:
          type: boolean
        is_note:
          type: boolean
        tags: {}
        read:
          type: boolean
        has_snapshot:
          type: boolean
          readOnly: true
        has_snapshot_audio:
          type: boolean
          readOnly: true
        has_notes:
          type: boolean
          readOnly: true
        meta_image:
          type: string
          format: uri
          maxLength: 2048
        published_date:
          type: string
          format: date-time
          readOnly: true
        source_type:
          enum:
          - manual
          - rss
          - import
          type: string
          description: |-
            * `manual` - Manual
            * `rss` - RSS
            * `import` - Import
          x-spec-enum-id: debedf0966278d87
        source_id:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
        is_favorite:
          type: boolean
      required:
      - date_created
      - date_updated
      - has_notes
      - has_snapshot
      - has_snapshot_audio
      - id
      - published_date
      - title
    BookmarkNotes:
      type: object
      properties:
        id:
          type: string
          format: uuid
        notes:
          type: string
      required:
      - id
      - notes
    BookmarkNotesResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BookmarkNotes'
      required:
      - data
    BookmarkResponse:
      type: object
      description: Serializer for bookmark responses
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        date_created:
          type: string
          format: date-time
          readOnly: true
        date_updated:
          type: string
          format: date-time
          readOnly: true
        title:
          type: string
          maxLength: 500
        link:
          type: string
          format: uri
          maxLength: 2048
        author:
          type: string
          maxLength: 255
        estimated_time:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
        is_quote:
          type: boolean
        is_til:
          type: boolean
        is_note:
          type: boolean
        tags: {}
        read:
          type: boolean
        notes:
          type: string
        snapshot:
          type: string
        snapshot_audio_status:
          enum:
          - ''
          - pending
          - ready
          - failed
          - too_long
          type: string
          description: |-
            * `` - Not requested
            * `pending` - Pending
            * `ready` - Ready
            * `failed` - Failed
            * `too_long` - Too long
          x-spec-enum-id: f6f3b3c2d3144701
        has_snapshot:
          type: boolean
          readOnly: true
        has_snapshot_audio:
          type: boolean
          readOnly: true
        has_notes:
          type: boolean
          readOnly: true
        meta_image:
          type: string
          format: uri
          maxLength: 2048
        published_date:
          type: string
          format: date-time
          readOnly: true
        source_type:
          enum:
          - manual
          - rss
          - import
          type: string
          description: |-
            * `manual` - Manual
            * `rss` - RSS
            * `import` - Import
          x-spec-enum-id: debedf0966278d87
        source_id:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
        is_favorite:
          type: boolean
      required:
      - date_created
      - date_updated
      - has_notes
      - has_snapshot
      - has_snapshot_audio
      - id
      - published_date
      - title
    BookmarkSingleResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BookmarkResponse'
      required:
      - data
    BookmarkSnapshot:
      type: object
      properties:
        id:
          type: string
          format: uuid
        snapshot:
          type: string
        snapshot_audio_status:
          type: string
        has_snapshot_audio:
          type: boolean
      required:
      - id
      - snapshot
    BookmarkSnapshotAudio:
      type: object
      properties:
        id:
          type: string
          format: uuid
        url:
          type: string
          format: uri
        expires_in:
          type: integer
      required:
      - expires_in
      - id
      - url
    BookmarkSnapshotAudioGeneration:
      type: object
      properties:
        id:
          type: string
          format: uuid
        snapshot_audio_status:
          enum:
          - pending
          - ready
          type: string
          description: |-
            * `pending` - pending
            * `ready` - ready
          x-spec-enum-id: f0d3e0da7881e1a3
        has_snapshot_audio:
          type: boolean
      required:
      - has_snapshot_audio
      - id
      - snapshot_audio_status
    BookmarkSnapshotAudioGenerationResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BookmarkSnapshotAudioGeneration'
      required:
      - data
    BookmarkSnapshotAudioResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BookmarkSnapshotAudio'
      required:
      - data
    BookmarkSnapshotResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BookmarkSnapshot'
      required:
      - data
    BookmarkTag:
      type: object
      properties:
        tag:
          type: string
        display:
          type: string
        count:
          type: integer
      required:
      - count
      - display
      - tag
    BookmarkTagListMeta:
      type: object
      properties:
        total_count:
          type: integer
      required:
      - total_count
    BookmarkTagListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/BookmarkTag'
        meta:
          $ref: '#/components/schemas/BookmarkTagListMeta'
      required:
      - data
      - meta
    BookmarkV2ListMeta:
      type: object
      properties:
        next_cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
        total_count:
          type: integer
        available_tags:
          type: array
          items:
            $ref: '#/components/schemas/BookmarkV2TagFacet'
      required:
      - available_tags
      - has_more
      - total_count
    BookmarkV2ListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/BookmarkLite'
        meta:
          $ref: '#/components/schemas/BookmarkV2ListMeta'
      required:
      - data
      - meta
    BookmarkV2TagFacet:
      type: object
      properties:
        tag:
          type: string
        count:
          type: integer
      required:
      - count
      - tag
    GenerateNewsletterResponse:
      type: object
      properties:
        markdown:
          type: string
        target_read_time:
          type: integer
        total_estimated_time:
          type: integer
        article_count:
          type: integer
        data:
          type: array
          items:
            $ref: '#/components/schemas/NewsletterItem'
      required:
      - article_count
      - data
      - markdown
      - target_read_time
      - total_estimated_time
    NewsletterItem:
      type: object
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
        link:
          type: string
          format: uri
        author:
          type: string
        estimated_time:
          type: integer
        tags:
          type: array
          items:
            type: string
        meta_image:
          type: string
        teaser:
          type: string
      required:
      - author
      - estimated_time
      - id
      - link
      - meta_image
      - tags
      - teaser
      - title
    PatchedBookmarkUpdate:
      type: object
      description: Serializer for updating bookmarks (partial updates allowed)
      properties:
        title:
          type: string
          maxLength: 500
        link:
          type: string
          format: uri
          maxLength: 2048
        author:
          type: string
          maxLength: 255
        estimated_time:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
        is_quote:
          type: boolean
        is_til:
          type: boolean
        is_note:
          type: boolean
        tags:
          type: array
          items:
            type: string
        read:
          type: boolean
        notes:
          type: string
        snapshot:
          type: string
        meta_image:
          type: string
          format: uri
          maxLength: 2048
        published_date:
          type: string
          format: date-time
          nullable: true
        source_type:
          enum:
          - manual
          - rss
          - import
          type: string
          description: |-
            * `manual` - Manual
            * `rss` - RSS
            * `import` - Import
          x-spec-enum-id: debedf0966278d87
        source_id:
          type: integer
          maximum: 2147483647
          minimum: -2147483648
          nullable: true
        is_favorite:
          type: boolean
    RSSFeed:
      type: object
      description: Serializer for RSS feed responses
      properties:
        id:
          type: integer
          readOnly: true
        url:
          type: string
          format: uri
          maxLength: 2000
        title:
          type: string
          maxLength: 500
        description:
          type: string
          nullable: true
        date_created:
          type: string
          format: date-time
          readOnly: true
        last_fetched:
          type: string
          format: date-time
          readOnly: true
        active:
          type: boolean
        date_subscribed:
          type: string
          format: date-time
      required:
      - date_created
      - id
      - last_fetched
      - title
      - url
    RSSFeedCreate:
      type: object
      description: Serializer for creating RSS feeds - only requires URL
      properties:
        url:
          type: string
          format: uri
          maxLength: 2000
      required:
      - url
    RSSFeedListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/RSSFeed'
      required:
      - data
    RSSFeedResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/RSSFeed'
      required:
      - data
    RSSFeedUpdateRequest:
      type: object
      properties:
        active:
          type: boolean
      required:
      - active
    RSSItem:
      type: object
      description: Serializer for RSS item responses
      properties:
        id:
          type: integer
          readOnly: true
        feed_id:
          type: integer
          readOnly: true
        title:
          type: string
          readOnly: true
        link:
          type: string
          format: uri
          readOnly: true
        description:
          type: string
          readOnly: true
          nullable: true
        pub_date:
          type: string
          format: date-time
          readOnly: true
        updated_date:
          type: string
          format: date-time
          readOnly: true
        author:
          type: string
          readOnly: true
          nullable: true
        guid:
          type: string
          readOnly: true
        read:
          type: boolean
          readOnly: true
        image:
          type: string
          format: uri
          readOnly: true
          nullable: true
        meta_image:
          type: string
          format: uri
          readOnly: true
          nullable: true
        meta_author:
          type: string
          readOnly: true
          nullable: true
        content:
          type: string
          readOnly: true
          nullable: true
        content_type:
          enum:
          - html
          - text
          type: string
          description: |-
            * `html` - HTML
            * `text` - Text
          x-spec-enum-id: 0f324ba58b732882
          readOnly: true
        feed_title:
          type: string
          readOnly: true
        feed_url:
          type: string
          readOnly: true
      required:
      - author
      - content
      - content_type
      - description
      - feed_id
      - feed_title
      - feed_url
      - guid
      - id
      - image
      - link
      - meta_author
      - meta_image
      - pub_date
      - read
      - title
      - updated_date
    RSSItemDetail:
      type: object
      description: Serializer for detailed RSS item view - includes all fields
      properties:
        id:
          type: integer
          readOnly: true
        feed_id:
          type: integer
          readOnly: true
        title:
          type: string
          readOnly: true
        link:
          type: string
          format: uri
          readOnly: true
        description:
          type: string
          readOnly: true
          nullable: true
        pub_date:
          type: string
          format: date-time
          readOnly: true
        updated_date:
          type: string
          format: date-time
          readOnly: true
        author:
          type: string
          readOnly: true
          nullable: true
        guid:
          type: string
          readOnly: true
        read:
          type: boolean
          readOnly: true
        image:
          type: string
          format: uri
          readOnly: true
          nullable: true
        meta_image:
          type: string
          format: uri
          readOnly: true
          nullable: true
        meta_author:
          type: string
          readOnly: true
          nullable: true
        content:
          type: string
          readOnly: true
        content_type:
          enum:
          - html
          - text
          type: string
          description: |-
            * `html` - HTML
            * `text` - Text
          x-spec-enum-id: 0f324ba58b732882
          readOnly: true
        feed_title:
          type: string
          readOnly: true
        feed_url:
          type: string
          readOnly: true
      required:
      - author
      - content
      - content_type
      - description
      - feed_id
      - feed_title
      - feed_url
      - guid
      - id
      - image
      - link
      - meta_author
      - meta_image
      - pub_date
      - read
      - title
      - updated_date
    RSSItemDetailResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/RSSItemDetail'
      required:
      - data
    RSSItemListMeta:
      type: object
      properties:
        total_count:
          type: integer
        page:
          type: integer
        limit:
          type: integer
      required:
      - limit
      - page
      - total_count
    RSSItemListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/RSSItem'
        meta:
          $ref: '#/components/schemas/RSSItemListMeta'
      required:
      - data
      - meta
    RSSItemRecentMeta:
      type: object
      properties:
        total_count:
          type: integer
        page:
          type: integer
        limit:
          type: integer
        days:
          type: integer
      required:
      - days
      - limit
      - page
      - total_count
    RSSItemRecentResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/RSSItem'
        meta:
          $ref: '#/components/schemas/RSSItemRecentMeta'
      required:
      - data
      - meta
  securitySchemes:
    BearerTokenAuth:
      type: http
      scheme: bearer
      bearerFormat: Token
    basicAuth:
      type: http
      scheme: basic
