Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
969 lines (706 sloc) 19.1 KB

REST API

Authentication

The Miniflux API uses HTTP Basic authentication. The credentials are the username/password of your account.

Clients

There are 2 official API clients, one written in Go and another one written in Python.

Golang Client

Installation:

go get -u miniflux.app/client

Usage Example:

package main

import (
    "fmt"

    miniflux "miniflux.app/client"
)

func main() {
    client := miniflux.New("https://miniflux.example.org", "admin", "secret")

    // Fetch all feeds.
    feeds, err := client.Feeds()
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(feeds)
}

Python Client

Installation:

pip install miniflux

Usage example:

import miniflux

client = miniflux.Client("https://miniflux.example.org", "my_username", "my_secret_password")

# Get all feeds
feeds = client.get_feeds()

# Refresh a feed
client.refresh_feed(123)

# Discover subscriptions from a website
subscriptions = client.discover("https://example.org")

# Create a new feed, with a personalized user agent and with the crawler enabled
feed_id = client.create_feed("http://example.org/feed.xml", 42, crawler=True, user_agent="GoogleBot")

# Fetch 10 starred entries
entries = client.get_entries(starred=True, limit=10)

# Fetch last 5 feed entries
feed_entries = client.get_feed_entries(123, direction='desc', order='published_at', limit=5)

# Update a feed category
client.update_Feed(123, category_id=456)

API Reference

Status Codes

  • 200: Everything is OK
  • 201: Resource created/modified
  • 204: Resource removed/modified
  • 400: Bad request
  • 401: Unauthorized (bad username/password)
  • 403: Forbidden (access not allowed)
  • 500: Internal server error

Error Response

{
    "error_message": "Some error"
}

Discover Subscriptions

Request:

POST /v1/discover
Content-Type: application/json

{
    "url": "http://example.org"
}

Response:

[
    {
        "url": "http://example.org/feed.atom",
        "title": "Atom Feed",
        "type": "atom"
    },
    {
        "url": "http://example.org/feed.rss",
        "title": "RSS Feed",
        "type": "rss"
    }
]

Optional fields:

  • username: Feed username (string)
  • password: Feed password (string)
  • user_agent: Custom user agent (string)

Get Feeds

Request:

GET /v1/feeds

Response:

[
    {
        "id": 42,
        "user_id": 123,
        "title": "Example Feed",
        "site_url": "http://example.org",
        "feed_url": "http://example.org/feed.atom",
        "rewrite_rules": "",
        "scraper_rules": "",
        "crawler": false,
        "checked_at": "2017-12-22T21:06:03.133839-05:00",
        "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
        "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
        "parsing_error_count": 0,
        "parsing_error_message": "",
        "category": {
            "id": 793,
            "user_id": 123,
            "title": "Some category"
        },
        "icon": {
            "feed_id": 42,
            "icon_id": 84
        }
    }
]

Notes:

  • icon is null when the feed doesn't have any favicon.

Get Feed

Request:

GET /v1/feeds/42

Response:

{
    "id": 42,
    "user_id": 123,
    "title": "Example Feed",
    "site_url": "http://example.org",
    "feed_url": "http://example.org/feed.atom",
    "rewrite_rules": "",
    "scraper_rules": "",
    "crawler": false,
    "checked_at": "2017-12-22T21:06:03.133839-05:00",
    "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
    "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
    "parsing_error_count": 0,
    "parsing_error_message": "",
    "category": {
        "id": 793,
        "user_id": 123,
        "title": "Some category"
    },
    "icon": {
        "feed_id": 42,
        "icon_id": 84
    }
}

Notes:

  • icon is null when the feed doesn't have any favicon.

Get Feed Icon

Request:

GET /v1/feeds/42/icon

Response:

{
    "id": 262,
    "data": "image/png;base64,iVBORw0KGgoAAA....",
    "mime_type": "image/png"
}

Notes:

  • If the feed doesn't have any favicon, a 404 is returned.

Create Feed

Request:

POST /v1/feeds
Content-Type: application/json

{
    "feed_url": "http://example.org/feed.atom",
    "category_id": 22
}

Response:

{
    "feed_id": 262,
}

Required fields:

  • feed_url: Feed URL (string)
  • category_id: Category ID (int)

Optional fields:

  • username: Feed username (string)
  • password: Feed password (string)
  • crawler: Enable/Disable scraper (boolean)
  • user_agent: Custom user agent for the feed (string)

Update Feed

Request:

PUT /v1/feeds/42
Content-Type: application/json

{
    "title": "New Feed Title",
    "category": {
        "id": 22
    }
}

Response:

{
    "id": 42,
    "user_id": 123,
    "title": "New Feed Title",
    "site_url": "http://example.org",
    "feed_url": "http://example.org/feed.atom",
    "rewrite_rules": "",
    "scraper_rules": "",
    "crawler": false,
    "checked_at": "2017-12-22T21:06:03.133839-05:00",
    "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
    "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
    "parsing_error_count": 0,
    "parsing_error_message": "",
    "category": {
        "id": 22,
        "user_id": 123,
        "title": "Another category"
    },
    "icon": {
        "feed_id": 42,
        "icon_id": 84
    }
}

Available fields:

  • feed_url: (string)
  • site_url: (string)
  • title: (string)
  • category_id: (int)
  • scraper_rules: (string)
  • rewrite_rules: (string)
  • crawler: (boolean)
  • username: (string)
  • password: (string)
  • user_agent: Custom user agent for the feed (string)

Refresh Feed

Request:

PUT /v1/feeds/42/refresh

Note

  • Returns 204 status code for success.
  • This API call is synchronous and can takes hundred of milliseconds.

Remove Feed

Request:

DELETE /v1/feeds/42

Get Feed Entry

Request:

GET /v1/feeds/42/entries/888

Response:

{
    "id": 888,
    "user_id": 123,
    "feed_id": 42,
    "title": "Entry Title",
    "url": "http://example.org/article.html",
    "comments_url": "",
    "author": "Foobar",
    "content": "<p>HTML contents</p>",
    "hash": "29f99e4074cdacca1766f47697d03c66070ef6a14770a1fd5a867483c207a1bb",
    "published_at": "2016-12-12T16:15:19Z",
    "status": "read",
    "starred": false,
    "feed": {
        "id": 42,
        "user_id": 123,
        "title": "New Feed Title",
        "site_url": "http://example.org",
        "feed_url": "http://example.org/feed.atom",
        "rewrite_rules": "",
        "scraper_rules": "",
        "crawler": false,
        "checked_at": "2017-12-22T21:06:03.133839-05:00",
        "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
        "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
        "parsing_error_count": 0,
        "parsing_error_message": "",
        "category": {
            "id": 22,
            "user_id": 123,
            "title": "Another category"
        },
        "icon": {
            "feed_id": 42,
            "icon_id": 84
        }
    }
}

Note

  • The field comments_url is available since Miniflux v2.0.5.

Get Entry

Request:

GET /v1/entries/888

Response:

{
    "id": 888,
    "user_id": 123,
    "feed_id": 42,
    "title": "Entry Title",
    "url": "http://example.org/article.html",
    "comments_url": "",
    "author": "Foobar",
    "content": "<p>HTML contents</p>",
    "hash": "29f99e4074cdacca1766f47697d03c66070ef6a14770a1fd5a867483c207a1bb",
    "published_at": "2016-12-12T16:15:19Z",
    "status": "read",
    "starred": false,
    "feed": {
        "id": 42,
        "user_id": 123,
        "title": "New Feed Title",
        "site_url": "http://example.org",
        "feed_url": "http://example.org/feed.atom",
        "rewrite_rules": "",
        "scraper_rules": "",
        "crawler": false,
        "checked_at": "2017-12-22T21:06:03.133839-05:00",
        "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
        "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
        "parsing_error_count": 0,
        "parsing_error_message": "",
        "category": {
            "id": 22,
            "user_id": 123,
            "title": "Another category"
        },
        "icon": {
            "feed_id": 42,
            "icon_id": 84
        }
    }
}

Get Feed Entries

Request:

GET /v1/feeds/42/entries?limit=1&order=id&direction=asc

Available filters:

  • status: Entry status (read, unread or removed)
  • offset
  • limit
  • order: "id", "status", "published_at", "category_title", "category_id"
  • direction: "asc" or "desc"
  • before (unix timestamp, available since Miniflux 2.0.9)
  • after (unix timestamp, available since Miniflux 2.0.9)
  • before_entry_id (int64, available since Miniflux 2.0.9)
  • after_entry_id (int64, available since Miniflux 2.0.9)
  • starred (boolean, available since Miniflux 2.0.9)

Response:

{
    "total": 10,
    "entries": [
        {
            "id": 888,
            "user_id": 123,
            "feed_id": 42,
            "title": "Entry Title",
            "url": "http://example.org/article.html",
            "comments_url": "",
            "author": "Foobar",
            "content": "<p>HTML contents</p>",
            "hash": "29f99e4074cdacca1766f47697d03c66070ef6a14770a1fd5a867483c207a1bb",
            "published_at": "2016-12-12T16:15:19Z",
            "status": "read",
            "starred": false,
            "feed": {
                "id": 42,
                "user_id": 123,
                "title": "New Feed Title",
                "site_url": "http://example.org",
                "feed_url": "http://example.org/feed.atom",
                "rewrite_rules": "",
                "scraper_rules": "",
                "crawler": false,
                "checked_at": "2017-12-22T21:06:03.133839-05:00",
                "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
                "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
                "parsing_error_count": 0,
                "parsing_error_message": "",
                "category": {
                    "id": 22,
                    "user_id": 123,
                    "title": "Another category"
                },
                "icon": {
                    "feed_id": 42,
                    "icon_id": 84
                }
            }
        }
    ]

Get Entries

Request:

GET /v1/entries?status=unread&direction=desc

Available filters:

  • status: Entry status (read, unread or removed)
  • offset
  • limit
  • order: "id", "status", "published_at", "category_title", "category_id"
  • direction: "asc" or "desc"
  • before (unix timestamp, available since Miniflux 2.0.9)
  • after (unix timestamp, available since Miniflux 2.0.9)
  • before_entry_id (int64, available since Miniflux 2.0.9)
  • after_entry_id (int64, available since Miniflux 2.0.9)
  • starred (boolean, available since Miniflux 2.0.9)

Response:

{
    "total": 10,
    "entries": [
        {
            "id": 888,
            "user_id": 123,
            "feed_id": 42,
            "title": "Entry Title",
            "url": "http://example.org/article.html",
            "comments_url": "",
            "author": "Foobar",
            "content": "<p>HTML contents</p>",
            "hash": "29f99e4074cdacca1766f47697d03c66070ef6a14770a1fd5a867483c207a1bb",
            "published_at": "2016-12-12T16:15:19Z",
            "status": "unread",
            "starred": false,
            "feed": {
                "id": 42,
                "user_id": 123,
                "title": "New Feed Title",
                "site_url": "http://example.org",
                "feed_url": "http://example.org/feed.atom",
                "rewrite_rules": "",
                "scraper_rules": "",
                "crawler": false,
                "checked_at": "2017-12-22T21:06:03.133839-05:00",
                "etag_header": "KyLxEflwnTGF5ecaiqZ2G0TxBCc",
                "last_modified_header": "Sat, 23 Dec 2017 01:04:21 GMT",
                "parsing_error_count": 0,
                "parsing_error_message": "",
                "category": {
                    "id": 22,
                    "user_id": 123,
                    "title": "Another category"
                },
                "icon": {
                    "feed_id": 42,
                    "icon_id": 84
                }
            }
        }
    ]

Update Entries

Request:

PUT /v1/entries
Content-Type: application/json

{
    "entry_ids": [1234, 4567],
    "status": "read"
}

Note

  • Returns 204 status code for success.

Toggle Entry Bookmark

Request:

PUT /v1/entries/1234/bookmark

Note

  • Returns 204 status code for success.

Get Categories

Request:

GET /v1/categories

Response:

[
    {"title": "All", "user_id": 267, "id": 792},
    {"title": "Engineering Blogs", "user_id": 267, "id": 793}
]

Create Category

Request:

POST /v1/categories
Content-Type: application/json

{
    "title": "My category"
}

Response:

{
    "id": 802,
    "user_id": 267,
    "title": "My category"
}

Update Category

Request:

PUT /v1/categories/802
Content-Type: application/json

{
    "title": "My new title"
}

Response:

{
    "id": 802,
    "user_id": 267,
    "title": "My new title"
}

Delete Category

Request:

DELETE /v1/categories/802

OPML Export

Request:

GET /v1/export

The response is a XML document (OPML file).

Note

This API call is available since Miniflux v2.0.1.

OPML Import

Request:

POST /v1/import

XML data
  • The body is your OPML file (XML).
  • Returns 201 Created if imported successfully.

Response:

{
  "message": "Feeds imported successfully"
}

Note

This API call is available since Miniflux v2.0.7.

Create User

Request:

POST /v1/users
Content-Type: application/json

{
    "username": "bob",
    "password": "test123",
    "is_admin": false
}

Response:

{
    "id": 270,
    "username": "bob",
    "language": "en_US",
    "timezone": "UTC",
    "theme": "default",
    "entry_sorting_direction": "asc"
}

Note

  • You must be an administrator to create users.

Update User

Request:

PUT /v1/users/270
Content-Type: application/json

{
    "username": "joe"
}

Available fields:

  • username: (string)
  • password: (string)
  • is_admin: (boolean)
  • theme: (string)
  • language: (string)
  • timezone: (string)
  • entry_sorting_direction: "desc" or "asc" (available since Miniflux 2.0.9)

Response:

{
    "id": 270,
    "username": "joe",
    "language": "en_US",
    "timezone": "UTC",
    "theme": "default",
    "entry_sorting_direction": "asc"
}

Note

  • You must be an administrator to update users.

Get Current User

Request:

GET /v1/me

Response:

{
    "id": 1,
    "username": "admin",
    "is_admin": true,
    "theme": "default",
    "language": "en_US",
    "timezone": "America/Vancouver",
    "entry_sorting_direction": "desc",
    "last_login_at": "2018-06-01T19:54:30.723051-07:00",
    "extra": {}
}

Note

This API endpoint is available since Miniflux v2.0.8.

Get User

Request:

# Get user by user ID
GET /v1/users/270

# Get user by username
GET /v1/users/foobar

Response:

{
    "id": 270,
    "username": "bob",
    "is_admin": false,
    "language": "en_US",
    "timezone": "UTC",
    "theme": "default",
    "entry_sorting_direction": "asc",
    "last_login_at": "2017-12-27T16:40:58.841841-05:00",
    "extra": {
        "google_id": "42424242424242"
    }
}

Note

  • You must be an administrator to fetch users.
  • The extra field is a dictionary of optional values.

Get Users

Request:

GET /v1/users

Response:

[
    {
        "id": 270,
        "username": "bob",
        "is_admin": false,
        "language": "en_US",
        "timezone": "UTC",
        "theme": "default",
        "entry_sorting_direction": "asc",
        "last_login_at": "2017-12-27T16:40:58.841841-05:00",
        "extra": {}
    }
]

Note

  • You must be an administrator to fetch users.
  • The extra field is a dictionary of optional values.

Delete User

Request:

DELETE /v1/users/270

Note

  • You must be an administrator to delete users.

Healthcheck

The healthcheck endpoint is useful for monitoring and load-balancer configuration.

Request:

GET /healthcheck

Response:

OK

Return a status code 200 when the service is up.