Load Inoreader data to DuckDB
Build a Inoreader to DuckDB pipeline with your coding agent. One prompt scaffolds it with the dltHub AI harness, plus the Inoreader API base URL, auth, endpoints, and incremental loading.
Inoreader is a web feed reader platform and API for accessing users' subscriptions, feeds, and article streams. Everything needed to build a working Inoreader → DuckDB pipeline is on this page: the API's base URL, authentication, endpoints, pagination and incremental field — plus a prompt that hands the whole job to your coding agent.
Build your Inoreader to DuckDB pipeline
Paste this prompt into Claude, Codex, or Cursor. The agent does the rest.
PromptRunuvx dlthub-init@latestto build a pipeline from Inoreader to DuckDB and run it on dltHub
That scaffolds a dltHub workspace and installs the dltHub AI harness — the project rules, the secrets-management skill, and the dlt MCP server your agent needs to work safely. From there it reads the Inoreader API, proposes the endpoints to load, then writes, runs and validates the pipeline while you review rather than type. Credentials are inspected through MCP tools, so your agent never reads secrets.toml itself. How the LLM-native workflow works →
Prefer to write it yourself? Every fact the agent uses is below.
Inoreader API at a glance
| Base URL | https://www.inoreader.com/reader/api/0 |
| Example endpoint | GET reader/api/0/stream/contents/{streamId} |
| Records found at | items |
| Authentication | AppId/AppKey headers and OAuth 2.0 Bearer token for user authorization — sent in the Authorization header, prefixed Bearer |
| Also required | AppId, AppKey |
| Pagination | Cursor-based via c, next cursor at continuation, page size via n (default 20, max 1000) |
| Record id | id |
| API reference | https://www.inoreader.com/developers/ |
These values come from the Inoreader API reference — the authoritative source if anything here looks out of date.
How do I authenticate with the Inoreader API?
All requests require AppId and AppKey headers for application authentication. User-scoped endpoints additionally require an Authorization header with a Bearer token obtained via OAuth 2.0.
1. Get your credentials
- Sign in to your Inoreader account. 2. Navigate to your Inoreader Preferences page. 3. Look for the "Developer" or "Create new application" section. 4. Follow the prompts to register your application. 5. Upon successful registration, the portal will provide you with a unique 'App ID' and 'App Key' which are required for API authentication. Note that Inoreader API access generally requires a Pro plan.
2. Add them to .dlt/secrets.toml
[sources.inoreader_source] app_id = "your_app_id_here" app_key = "your_app_key_here"
dlt reads this file automatically at runtime. With the harness, the setup-secrets skill prompts you for the values and never handles the raw credential in chat. For production, see setting up credentials with dlt.
What Inoreader data can I load into DuckDB?
These are the Inoreader endpoints dlt can load into DuckDB:
| Resource | Endpoint | Method | Data selector | Description |
|---|---|---|---|---|
| stream_contents | stream/contents/[streamId] | GET | items | Fetches articles for a given stream ID |
| stream_item_ids | stream/items/ids | GET | itemRefs | Fetches article IDs for a given stream ID |
| subscription_list | subscription/list | GET | subscriptions | Fetches the list of user subscriptions |
| tag_list | tag/list | GET | tags | Fetches the user's folders and tags |
| stream_preference_list | preference/stream/list | GET | streamprefs | Fetches folders and system preference lists |
How do I load only new Inoreader records?
The Inoreader API reference does not document a timestamp or sequence field for these endpoints, so there is nothing to advertise here as verified. Pick a field from the endpoints table above that increases with every write, then set it as the cursor_path.
{"name": "stream_contents", "endpoint": { "path": "reader/api/0/stream/contents/{streamId}", # Replace with a field that increases on every write. "incremental": {"cursor_path": "REPLACE_ME", "initial_value": "2024-01-01T00:00:00Z"}, }}
On the first run dlt loads everything from initial_value; on every run after that it requests only what changed and appends with write_disposition="merge" if you set a primary key. See incremental loading.
What does the generated Inoreader pipeline look like?
A standard dlt REST API pipeline — the same code you would write by hand, loading /stream/contents and /subscription/list from the Inoreader API into DuckDB:
import dlt from dlt.sources.rest_api import RESTAPIConfig, rest_api_resources @dlt.source def inoreader_source(app_key=dlt.secrets.value): config: RESTAPIConfig = { "client": { "base_url": "https://www.inoreader.com/reader/api/0", "auth": {"type": "bearer", "token": app_key}, }, "resources": [ {"name": "stream_contents", "endpoint": {"path": "reader/api/0/stream/contents/{streamId}", "data_selector": "items"}}, {"name": "subscription_list", "endpoint": {"path": "reader/api/0/subscription/list", "data_selector": "subscriptions"}} ], } yield from rest_api_resources(config) def load_inoreader_to_duckdb() -> None: pipeline = dlt.pipeline( pipeline_name="inoreader_pipeline", destination="duckdb", dataset_name="inoreader_data", ) load_info = pipeline.run(inoreader_source()) print(load_info) if __name__ == "__main__": load_inoreader_to_duckdb()
Run it with python inoreader_pipeline.py. The agent iterates on this until it loads cleanly — you review and approve, rather than write it from scratch.
How do I query Inoreader data in DuckDB?
dlt creates one table per resource. Query the loaded data with Python or SQL — or ask your agent to, through the MCP server's execute_sql_query tool.
Python (pandas DataFrame):
import dlt data = dlt.pipeline("inoreader_pipeline").dataset() df = data.stream_contents.df() print(df.head())
SQL:
SELECT * FROM inoreader_data.stream_contents LIMIT 10;
See querying your data with dataset and exploring it in marimo notebooks.
How do I deploy the Inoreader to DuckDB pipeline in production?
The pipeline runs locally, which is ideal for prototyping and one-off analysis. When you need it on a schedule, monitored on every load, and shared with your team, deploy the same dlt code on the dltHub platform — no infrastructure to maintain. The prompt above already ends with "run it on dltHub", so your agent can take it there directly.
- Deploy & schedule — run the pipeline as a managed job with automatic retries.
- Monitor — observable job queues, alerting, and load metrics for every run.
- Transform — promote raw Inoreader loads into governed, documented models.
- Visualize & share — explore data in notebooks and publish live dashboards instead of static screenshots.
What other destinations can I load Inoreader data to?
dlt loads into any of these — only the destination argument changes:
| Destination | Example value |
|---|---|
| PostgreSQL | "postgres" |
| BigQuery | "bigquery" |
| Snowflake | "snowflake" |
| Redshift | "redshift" |
| Databricks | "databricks" |
| Filesystem (S3, GCS, Azure) | "filesystem" |
Set dlt.pipeline(destination="snowflake") and add credentials in .dlt/secrets.toml. On the dltHub platform the same pipeline runs against a managed Iceberg lakehouse. See the full destinations list.
Next steps
Was this page helpful?
Community Hub
Need more dlt context for Inoreader to DuckDB?
Request dlt skills, commands, AGENT.md files, and AI-native context.