Settings

Avatar
{{ csrf_input(request) | safe }}

Changing your login name doesn't affect your data or API token.

{{ csrf_input(request) | safe }}
{{ csrf_input(request) | safe }}

Configure RSS clients (Capy, Reeder, …) with username {{ current_user }} and this token as the password.

{{ current_api_token }}

Drag Save to Lectio to your bookmarks bar to save the page you're reading into Saved Articles. From a phone share sheet or shortcut, request {{ request.base_url }}api/save?username={{ current_user }}&token=<API token>&url=<article URL>.

Best capture — browser extension: install the Readit extension and in its Options set Backend to {{ (request.base_url | string).rstrip('/') }} and Save token to your API token above. One-click saves then ship the rendered page from your browser, so paywalled and bot-walled articles arrive with full text.

Appearance

New posts dated older than this are marked read when fetched. Folders and feeds can only shorten it. 0 disables.

Caps tall (portrait) article images to this width; wide images stay full-width. 0 disables.

Ctrl/Cmd-click or middle-click on a post title opens the article in a new tab without opening it here. Off leaves the post unread.

Loads every image in an article's body through Lectio's image cache instead of directly from the source site. Stops content blockers from breaking articles whose images they filter, at the cost of more cache traffic and losing high-DPI (srcset) images.

Feed filtering

Network

Routes your feed fetches through the instance's configured proxy (set by an admin in Administration). "As needed" only escalates a feed after it's been refused outright.

Email addresses available when sending articles. Me is always available and uses your Profile email. Use ★ to set the default.

API key enables video durations in titles. Add your channel ID / handle to sync subscriptions as feeds — both fields required.

All YouTube feeds (overrides per-feed setting)

Register a Web app at Google Cloud Console, add redirect URI , then paste below and Save to enable account features and playlist adds.

Connect YouTube account

Lectio's own tally — Google gives no live quota read. Resets midnight Pacific.

Register an app at deviantart.com/studio/apps (use a Confidential client so the secret stays visible) to get a Client ID + Secret, then Save. Add to the app's OAuth2 Redirect URI whitelist to enable watch-list sync. Subscribe to a gallery by adding a deviantart.com/<user> URL like any feed.

Connect DeviantArt account

Failed to add — click to view the artist on DeviantArt:

    Watched but deactivated — the artist deactivated their DeviantArt account; skipped until it's reactivated (re-checked daily):

      Subscribed but no longer watched — updates paused automatically the first time this was noticed (nothing lost or unsubscribed); re-enable one from Feed Properties to keep following it live, unsubscribe below, or leave it paused:

        Lectio saves articles via the Instapaper Simple API using your account credentials. No separate API key is needed.

        Connect your Pinterest account to get a Pin button on each article that saves it (its lead image, linked back to the source) to a board you pick. Register an app at Pinterest Developers with redirect URI , or use the shared instance credentials set in the Administration panel.

        Connect Pinterest account

        Connect Quire to get an Add to Quire button on each article that creates a task in a project you pick. Register an app at quire.io/apps/dev to get a Client ID + Secret, then Save. Add to the app's Redirect URI whitelist.

        Connect Quire account

        Quire limits API calls per organization by minute and hour; this is Lectio's own running tally of its calls in the last minute/hour. Automations back off as it fills.

        Connect your Reddit account to get a Submit to Reddit button on each article, and to fetch Reddit feeds via the authenticated API (60 req/min instead of anonymous limits). Create a web app at reddit.com/prefs/apps with redirect URI , then enter the client ID and secret below and Save. Shared instance credentials are set in the Administration panel.

        Connect Reddit account

        When you ★ star an article, also send it to these destinations. One-way — un-starring doesn't remove it. Each is available once its integration is configured/connected.

        Configure Instapaper, connect YouTube, or set up Email (above / in Settings) to enable on-star destinations.

        {% set needs_replacement_feeds = problematic_feeds | selectattr("needs_replacement") | list %} {% set _active_problem_feeds = problematic_feeds | rejectattr("needs_replacement") | list %} {% set failing_feeds = _active_problem_feeds | selectattr("acknowledged_at", "none") | list %} {% set acked_feeds = _active_problem_feeds | rejectattr("acknowledged_at", "none") | list %}
        {# The folders table (a hidden row per feed — megabytes at thousands of feeds) is NOT rendered inline: it loads on first open of the Feeds tab from /settings/feeds/panel/folders into the container below. The search input and sfc toolbar stay server-rendered — their JS binds to them by id at DOMContentLoaded. #}
        search

        Loading…

        {# Up to LECTIO_FAILING_FEEDS_LIMIT (default 500) rows of markup — loads on first open of this view, not inline with the page. #}

        Loading…

        {% if inactive_feeds %} {% set auto_feeds = inactive_feeds|selectattr("reason")|list %} {% set own_feeds = inactive_feeds|rejectattr("reason")|list %} {% for group_title, group in (("Disabled automatically", auto_feeds), ("Disabled by you", own_feeds)) %} {% if group %} {% if auto_feeds and own_feeds %}

        {{ group_title }}

        {% endif %}
          {% for feed in group %}
        • {% if feed.folder_name %}{{ feed.folder_name }}{% endif %} Disabled ({{ feed.disabled_label }})
          {% if feed.folder_id %}{% endif %}
        • {% endfor %}
        {% endif %} {% endfor %} {% else %}

        No deactivated feeds.

        {% endif %}

        Active feeds ranked by how long since their newest post — oldest first. Feeds that have never posted appear at the top.

        {# Ranks EVERY active feed — megabytes at thousands of feeds — so the list loads on first open of this view, not inline with the page. #}

        Loading…

        Which feeds are routing through each outbound-fetch escalation tier right now.

        Loading…

        OPML

        Export OPML

        Takeout

        download Export ZIP

        To import your Inoreader subscriptions list, use Import OPML on the General tab. Come back here after feeds are subscribed to import starred items and labels.

        Import from files — Select one or more .json files from the ExportTool (one per label), or the .zip from Inoreader's Export everything. Stars and labels apply to articles already fetched by Lectio.

        No files selected

        API sync (trickle import) — Pulls subscriptions, labels, and starred items directly from Inoreader. Rate-limited to ~10 calls per scheduler cycle (~250/day free tier). Register an app at inoreader.com/developers with redirect URI , then save credentials and connect.

        Connect

        Save credentials and connect to enable API import.

        Import subscriptions (with folder assignments), starred articles, and article tags from a Miniflux instance. Enter your Miniflux URL and an API token (Settings → API Keys in Miniflux).

        Import subscriptions (with folder assignments), labels (as article tags), and starred articles from a FreshRSS instance. Use your FreshRSS API password (not your regular password) — configure it in FreshRSS → Profile.

        Import subscriptions (with category folders), starred articles, and labels from a Tiny Tiny RSS instance. Uses the tt-rss JSON API.

        Import your Instapaper bookmarks into Saved Items. In Instapaper, go to Settings → Export → Download .CSV file, then upload it here. Archived Instapaper articles import as archived saves; custom folders and the Liked/Starred flag become tags. Article text is fetched in the background after import.

        Rules match article titles (or body) and trigger actions automatically. Matches are case-insensitive. Enable .* for regex.

        {# Filter the list to one rule type. Populated by hlRenderTypeFilter — only types that actually have rules get a chip, so the row stays short on a library that only uses three of them. #}
        {# Suggestion-with-preview, never automatic (decided 2026-08-24) — see Plan.md "Utilities: find rules that could be one rule". Hidden until hlLoadSuggestions() finds something; nothing here is ever pre-checked or applied without a click. #}
        Suggestions

        Loading…

        Feeds

        Saved articles

        Clean-up

        YouTube

        Same folder

        Nothing is pre-selected — Compare before combining. Click a feed to open its Properties.

        Different folders

        Nothing is pre-selected — Compare before combining. Click a feed to open its Properties.

        Format upgrade

        A format-selector URL (?alt=rss, ?type=atom, ...) isn't always worse than its default — compare before switching. Same-family alternates (e.g. atom for a WordPress ?feed=rss2 subscription) are included too.

        Same address, different query

        A query param can be a real duplicate (format selector) or genuinely different content (a category/tag feed) — nothing here is pre-selected. Compare before combining.

        Same title, different feed

        Review by hand — a same-title pair can legitimately be a site's blog and its own podcast, so nothing here is ever auto-applied. Click a feed to open its Properties.

        Dismissed as "not dupes"

        Un-dismiss to let a group be suggested again.

        Confirmed
        Possible

        Every copy starts on Keep — switch the ones you want removed to Delete.

        Remove duplicate videos from the playlists you pick, keeping the first copy of each. Nothing is pre-selected.

        Uses the country blocks YouTube lists for each video. It can't see every rights-holder block, so a few unwatchable videos may remain.

        Delete posts older than a date from the selected folders. Starred and manually tagged posts are never deleted.

        Nothing is preselected — check the tags whose articles should lose their star. The tag still keeps the article: it stays archived, tagged, and safe from pruning. Only the star is removed.

        A star means to-do. Anything starred long ago is not something you are still getting to, so this archives it: it leaves the Inbox and is marked read, while its tags, its offline copy and its protection from cleanup all stay. Un-archive any item to put it back.

        Check the age spread before running this. The star date was rewritten for everything carried over by an import or migration — so a large cluster in one month usually means “when the data moved”, not when you starred it.

        Age by
        Archive stars older than

        Nothing is preselected — check the hosts you want to file. Largest first, and each row says how strong the match is. Filing a batch and re-scanning is the intended way to work through this.

        Tag aliases

        Publishers disagree about the same subject, so one topic arrives under several spellings and filtering on one silently misses the rest. An alias folds one into another everywhere — manual tags, captured feed tags, filter rules and imports.

        →

          No aliases yet.

          Ignored suggested tags

          A tag value that's never worth filing under, on any feed — filters it out of the suggestion chips themselves, not a rule that acts on entries carrying it. Distinct from the × on a single feed's chip (Feed Properties → Hidden tags), which only dismisses it there.

            Nothing ignored globally yet.

            Your tags

            Counts are kept apart on purpose: manual is what you applied by hand, feed is what publishers sent. An alias rewrites both, and one combined number would hide which half is which.

            TagManualFeed
            Feeds
            —
            Folders
            —
            Total articles
            —
            Unread
            —
            Read
            —
            Saved
            —
            Thumb cache
            —
            Image cache
            —
            Reader DB
            —
            Meta DB
            —
            YT sync
            {{ youtube_sync_last_at }}
            {{ youtube_sync_last_result }}