mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 23:01:29 +00:00
294 lines
7.0 KiB
Markdown
294 lines
7.0 KiB
Markdown
# NNTmux API v2 Specification
|
|
|
|
Code-first reference for the JSON API under `/api/v2`.
|
|
|
|
Primary sources:
|
|
|
|
- `routes/api.php`
|
|
- `app/Http/Controllers/Api/ApiV2Controller.php`
|
|
- `app/Transformers/ApiTransformer.php`
|
|
- `app/Transformers/DetailsTransformer.php`
|
|
- `app/Transformers/CategoryTransformer.php`
|
|
|
|
## Base URL
|
|
|
|
```text
|
|
https://<host>/api/v2
|
|
```
|
|
|
|
## Authentication and Rate Limits
|
|
|
|
- `GET /capabilities` is public.
|
|
- All other v2 routes require `api_token`.
|
|
- Route-level middleware uses token-aware throttling (`apiRateLimit`) and accepts `api_token` or the legacy `apikey` alias when that middleware is reused.
|
|
- `POST /nzbadd` is intentionally exempt from route-level rate limiting and API request quotas, and uploads are not recorded as API usage. Authentication and posting privileges still apply.
|
|
- Controller-level auth errors return a JSON error envelope:
|
|
|
|
```json
|
|
{
|
|
"error": "Missing parameter (api_token)"
|
|
}
|
|
```
|
|
|
|
Common auth/rate-limit statuses:
|
|
|
|
| HTTP | Error |
|
|
|---:|---|
|
|
| 400 | `Missing parameter (api_token)` |
|
|
| 401 | `Incorrect user credentials` |
|
|
| 403 | `Account suspended` |
|
|
| 429 | `Request limit reached` |
|
|
|
|
## Common Query Parameters
|
|
|
|
| Parameter | Type | Default | Notes |
|
|
|---|---|---:|---|
|
|
| `api_token` | string | - | Required except `capabilities`. |
|
|
| `id` | string | `""` | Search text/fallback identifier on search endpoints. |
|
|
| `limit` | int | `100` | Max rows in page. |
|
|
| `offset` | int | `0` | Zero-based pagination offset. |
|
|
| `cat` | csv string | `-1` | Category filter; `TV_WEBDL` auto-add can apply when `TV_HD` is requested. |
|
|
| `group` | string | `-1` | Usenet group filter (where supported). |
|
|
| `maxage` | int | `-1` | Max post age in days. Invalid values return JSON `400`. |
|
|
| `minsize` | int | `0` | Min release size in bytes. |
|
|
| `maxsize` | int | - | Accepted for compatibility; currently not enforced in query layer. |
|
|
| `sort` | string | `posted_desc` | `cat|name|size|files|stats|posted` + `_asc|_desc`. |
|
|
|
|
Sorting examples:
|
|
|
|
- `/api/v2/search?api_token=<token>&id=ubuntu&sort=posted_desc`
|
|
- `/api/v2/search?api_token=<token>&id=ubuntu&sort=name_asc`
|
|
- `/api/v2/tv?api_token=<token>&id=last+week+tonight&season=2025&ep=11/10&sort=posted_desc`
|
|
- `/api/v2/movies?api_token=<token>&imdbid=tt0816692&sort=size_desc`
|
|
|
|
JSON sorting response snippet (`sort=size_desc`):
|
|
|
|
```http
|
|
HTTP/1.1 200 OK
|
|
Content-Type: application/json
|
|
{
|
|
```
|
|
|
|
Releases are ordered largest-to-smallest because `sort=size_desc`.
|
|
|
|
> The legacy `Results` (capital R) Fractal field has been replaced by the
|
|
> lower-case `results` field. Search responses retain pagination and quota
|
|
> metadata in the top-level JSON object. Movie/TV-only fields (`tvdbid`,
|
|
> `imdbid`, `season`, …) are omitted when they do not apply to a release.
|
|
|
|
## Endpoints
|
|
|
|
## 1) Capabilities
|
|
|
|
- `GET /capabilities`
|
|
- Auth: none
|
|
|
|
Returns:
|
|
|
|
- `server`
|
|
- `limits`
|
|
- `searching`
|
|
- `registration`
|
|
- `categories`
|
|
- `groups`
|
|
- `genres`
|
|
|
|
## 2) Search
|
|
|
|
- `GET /search`
|
|
- Auth: required
|
|
|
|
Behavior:
|
|
|
|
- If `id` is present: text search.
|
|
- If `id` is omitted: browse mode.
|
|
- Includes API usage counters via response headers (`X-Api-Current`, `X-Api-Max`, `X-Grab-Current`, `X-Grab-Max`, `X-Api-Oldest-Time`, `X-Grab-Oldest-Time`).
|
|
|
|
## 3) TV Search
|
|
|
|
- `GET /tv`
|
|
- Auth: required
|
|
|
|
Identifiers:
|
|
|
|
- `vid`, `tvdbid`, `traktid`, `rid`, `tvmazeid`, `imdbid`, `tmdbid`
|
|
|
|
Optional filters:
|
|
|
|
- `season`, `ep`, `cat`, `maxage`, `minsize`, `sort`, `offset`, `limit`
|
|
|
|
Daily parsing:
|
|
|
|
- `season=YYYY` and `ep=MM/DD` infers an airdate query.
|
|
|
|
## 4) Movie Search
|
|
|
|
- `GET /movies`
|
|
- Auth: required
|
|
|
|
Identifiers:
|
|
|
|
- `imdbid`, `tmdbid`, `traktid`
|
|
|
|
Optional filters:
|
|
|
|
- `id`, `cat`, `maxage`, `minsize`, `sort`, `offset`, `limit`
|
|
|
|
## 5) Audio Search
|
|
|
|
- `GET /audio`
|
|
- Auth: required
|
|
|
|
Required:
|
|
|
|
- `id` (query string)
|
|
|
|
## 6) Book Search
|
|
|
|
- `GET /books`
|
|
- Auth: required
|
|
|
|
Required:
|
|
|
|
- `id` (query string)
|
|
|
|
## 7) Anime Search
|
|
|
|
- `GET /anime`
|
|
- Auth: required
|
|
|
|
Selectors:
|
|
|
|
- `id` and/or `anidbid` and/or `anilistid`
|
|
|
|
## 8) Get NZB
|
|
|
|
- `GET /getnzb`
|
|
- Auth: required
|
|
- Valid GUID redirects to `/getnzb?r=<api_token>&id=<guid>[&del=1]`
|
|
- Not found returns HTTP `404` JSON.
|
|
|
|
## 9) Details
|
|
|
|
- `GET /details`
|
|
- Auth: required
|
|
- Requires `id` (GUID)
|
|
|
|
## 10) Add NZB
|
|
|
|
- `POST /nzbadd`
|
|
- Auth: required; the user must have posting privileges (`can_post`)
|
|
- Content type: `multipart/form-data`
|
|
|
|
Fields:
|
|
|
|
| Field | Required | Notes |
|
|
|---|---|---|
|
|
| `api_token` | yes | API token for a verified, enabled user. |
|
|
| `nzb` | yes | Valid `.nzb` file staged for deferred import. |
|
|
| `nfo` | no | `.nfo` file with any safe basename, maximum 65,535 bytes. |
|
|
| `cat` | no | Echoed as response metadata; it does not affect import categorization. |
|
|
|
|
When `nfo` is supplied, its basename does not need to match the NZB basename.
|
|
The request is atomic: both files are validated before staging in an isolated
|
|
upload directory, and a partial write is rolled back.
|
|
|
|
NZB-only example:
|
|
|
|
```bash
|
|
curl -X POST -F "api_token=<token>" -F "nzb=@Release.nzb" https://<host>/api/v2/nzbadd
|
|
```
|
|
|
|
Paired example:
|
|
|
|
```bash
|
|
curl -X POST -F "api_token=<token>" -F "cat=5040" -F "nzb=@Release.nzb" -F "nfo=@scene-info.nfo" https://<host>/api/v2/nzbadd
|
|
```
|
|
|
|
Successful staging returns HTTP `201`:
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"status": "staged",
|
|
"name": "Release",
|
|
"category": "5040",
|
|
"files": {
|
|
"nzb": { "filename": "Release.nzb", "type": "nzb" },
|
|
"nfo": { "filename": "scene-info.nfo", "type": "nfo" }
|
|
}
|
|
}
|
|
```
|
|
|
|
Staging does not synchronously create a release. Import the NZB files first,
|
|
then import their paired NFO files using the manifest identity recorded by the
|
|
NZB importer:
|
|
|
|
```bash
|
|
php artisan nntmux:import-nzbs --folder=/path/to/NZB_UPLOAD_FOLDER
|
|
php artisan nntmux:import-nfos --folder=/path/to/NZB_UPLOAD_FOLDER
|
|
```
|
|
|
|
The NFO importer replaces an existing NFO for the resolved release. Add
|
|
`--delete` to remove successfully imported NFO payloads or `--delete-failed`
|
|
to remove payloads that cannot be linked. NZB-only responses set `files.nfo`
|
|
to `null`.
|
|
|
|
## Response Models
|
|
|
|
### Search Envelope (`/search`, `/tv`, `/movies`, `/audio`, `/books`, `/anime`)
|
|
|
|
```json
|
|
{
|
|
"Total": 123,
|
|
"apiCurrent": 2,
|
|
"apiMax": 1000,
|
|
"grabCurrent": 1,
|
|
"grabMax": 100,
|
|
"apiOldestTime": "Wed, 20 Nov 2024 12:00:00 +0000",
|
|
"grabOldestTime": "",
|
|
"results": []
|
|
}
|
|
```
|
|
|
|
### Details Object (`/details`)
|
|
|
|
Returns a single release object (not envelope). Download field name is `link` (not `url`).
|
|
|
|
## Error Response Conventions
|
|
|
|
- Missing token: JSON `400`
|
|
- Invalid token: JSON `401`
|
|
- Disabled account: JSON `403`
|
|
- Invalid `maxage`: JSON `400`
|
|
- Invalid `sort`: JSON `400`
|
|
- Missing required endpoint parameter (`id`, etc.): JSON `400`
|
|
- Missing GUID in `/getnzb`: JSON `404`
|
|
|
|
## Unsupported in v2
|
|
|
|
The following are intentionally not part of v2 JSON API:
|
|
|
|
- `register`
|
|
- `user`
|
|
- `comments`
|
|
- `commentadd`
|
|
- `cartadd`
|
|
- `cartdel`
|
|
|
|
## Postman Collection
|
|
|
|
- `docs/postman/nntmux_api_v2.postman_collection.json`
|