Skip to content

External API, RSS and cached queries

theotherp edited this page Jun 29, 2021 · 5 revisions

External API

Hydra exposes an external API for NZB searches which is compatible with the newznab specification. Access it via <yourFullUrl>/api, e.g. http://127.0.0.1:5076/api.

Additional parameters are: minage, minsize, maxsize and cachetime (see below). You can provide an indexers parameter with a comma separated list of the names of the indexers to be used in the query.

Supported media IDs: tvdbid, rid, tvmazeid, imdbid and tmdbid.

Supported search types: search, tvsearch, movie and book.

Hydra returns all available newznab attributes by default. The value of the parameter extended is ignored.

Caching

Every query can be cached for a configurable amount of time. Just add a parameter with the name of "cachetime" to the query. Its value determines how long this result will be cached for in minutes. Example:

http://127.0.0.1:5076/api?apikey=myapikey&t=tvsearch&cachetime=60 will search for new TV show releases. If the very same query was executed in the last 60 minutes your indexers won't be queried but instead the cached results will be returned. When the cached query results are older than 60 minutes your indexers will be queried and the new results are stored in the cache.

They cache key consists of any other API parameter, i.e. only queries with exactly the same parameters will be matched. If you added a category to the URL above (http://127.0.0.1:5076/api?apikey=myapikey&t=tvsearch&cachetime=60&cat=5040) it would be executed again and stored as a different cache entry.

You may also define a global cache time in the config. This will always be used for any search except API searches that define a cache time in which case the one from the API call will be used.

RSS

As the newznab spec follows RSS standards any search result should be readable from an RSS reader or any tool supporting RSS feeds (e.g. NZBGet). If you want you can use the endpoint /rss but it's effectively the same as /api.

Stats

Search and download history and indexer statistics and statuses can be queried using external API endpoints. Authorization is done via API key (provided as query parameter). Some of the endpoints allow complex request data to be provided in the form of JSON. It's always possible to replace that JSON with dot notation.

If for example an endpoint requires apikey=apikey and someJson={a=123,b=foobar} you can call it either using ?apikey=apikey&someJson={"a"=123,"b"="foobar"} (URL encoded) or ?apikey=apikey&someJson.a=123&someJson.b=foobar.

Further data and examples can be obtained by visiting the stats and history pages in a running instance and observing the sent and received data using your browser's developer tools.

/api/stats

Example request:

{
  "after": "2018-11-28T09:20:50.190Z",
  "before": "2018-12-29T09:20:50.190Z",
  "includeDisabled": true,
  "indexerApiAccessStats": true,
  "avgIndexerSearchResultsShares": true,
  "avgResponseTimes": true,
  "indexerDownloadShares": true,
  "downloadsPerDayOfWeek": true,
  "downloadsPerHourOfDay": true,
  "searchesPerDayOfWeek": true,
  "searchesPerHourOfDay": true,
  "downloadsPerAgeStats": true,
  "successfulDownloadsPerIndexer": true,
  "downloadSharesPerUser": false,
  "searchSharesPerUser": false,
  "downloadSharesPerIp": true,
  "searchSharesPerIp": true,
  "userAgentSearchShares": true,
  "userAgentDownloadShares": true
}

Example response

/api/history/searches

Example request:

{
  "apikey": "apikey",
  "request": {
    "page": 1,
    "limit": 100,
    "filterModel": {
      "query": {
        "filterValue": "1",
        "filterType": "freetext"
      }
    },
    "sortModel": {
      "column": "time",
      "sortMode": 2
    }
  }
}

The sortMode is 1 for ascending, 2 for descending and 0 for neutral. The column (which may also be used as key in filterModel) may be one of: time, query, source, username, ip. Any key not provided will be filled with default values:

"request": {
    "page": 1,
    "limit": 100,
    "filterModel": {},
    "sortModel": {
      "column": "time",
      "sortMode": 2
    }
  }

A response may look like this (entries in content omitted for brevity):

{
  "content": [
    {
      "id": 65,
      "source": "API",
      "searchType": "MOVIE",
      "time": 1544551917.589000000,
      "identifiers": [],
      "categoryName": "All",
      "query": null,
      "season": null,
      "episode": null,
      "title": null,
      "author": null,
      "username": null,
      "ip": "127.0.0.1",
      "userAgent": "Mozilla",
      "comparingHash": 1637389378
    }
  ],
  "pageable": {
    "sort": {
      "sorted": false,
      "unsorted": true
    },
    "pageSize": 100,
    "pageNumber": 0,
    "offset": 0,
    "unpaged": false,
    "paged": true
  },
  "last": false,
  "totalElements": 107,
  "totalPages": 2,
  "sort": {
    "sorted": false,
    "unsorted": true
  },
  "first": true,
  "numberOfElements": 100,
  "number": 0,
  "size": 100
}

/api/history/downloads

Request same as for searches.

Possible table names: time, name, title, status, access_source, age, username, ip.

A response may look like this:

{
  "content": [
    {
      "id": 1253,
      "searchResult": {
        "id": "5032704754818772909",
        "indexer": {
          "id": 9,
          "name": "NZBGeek"
        },
        "firstFound": 1544807785.854000000,
        "title": "indexer2",
        "indexerGuid": "http://127.0.0.1:5080/nzb/21",
        "link": "http://127.0.0.1:5080/nzb/21",
        "details": "http://127.0.0.1:5080/nzb/21",
        "downloadType": "NZB",
        "pubDate": 1544721385.000000000
      },
      "nzbAccessType": "REDIRECT",
      "accessSource": "INTERNAL",
      "time": 1545996726.266000000,
      "status": "REQUESTED",
      "error": null,
      "username": null,
      "ip": "127.0.0.1",
      "userAgent": "Mozilla",
      "age": 1,
      "externalId": null
    }
  ],
  "pageable": {
    "sort": {
      "sorted": false,
      "unsorted": true
    },
    "pageSize": 100,
    "pageNumber": 0,
    "offset": 0,
    "unpaged": false,
    "paged": true
  },
  "last": true,
  "totalElements": 1,
  "totalPages": 1,
  "sort": {
    "sorted": false,
    "unsorted": true
  },
  "first": true,
  "numberOfElements": 1,
  "number": 0,
  "size": 100
}

/api/stats/indexers

Example response:

[
  {
    "indexer": "NZBGeek",
    "state": "ENABLED",
    "level": 0,
    "disabledUntil": null,
    "lastError": null
  },
  {
    "indexer": "6box spotweb",
    "state": "DISABLED_USER",
    "level": 0,
    "disabledUntil": null,
    "lastError": null
  }
]