# Seerr AutoApprove Automatically approves a configurable number of movie and series requests per user in [Seerr](https://github.com/seerr-team/seerr). Requests over the limit stay pending for manual approval. ## How it works - Polls Seerr for pending requests every `PollIntervalSeconds`, and immediately when Seerr calls the `/webhook` endpoint. - Pending requests are evaluated oldest first. A request is approved when the user still has quota left for that category (movie, series, 4K movie, 4K series). - Only approvals made by this service count towards the quota. They are tracked in a small SQLite database in `/data`. - Series requests are never partially approved: if a request contains more seasons than the user has quota left, it stays pending. ## Setup ### 1. Get a Seerr API key In Seerr go to **Settings → General** and copy the **API Key**. ### 2. Configure Copy the example environment file and edit it: ```sh cp .env.example .env ``` At minimum set `Seerr__BaseUrl` and `Seerr__ApiKey`. See [Configuration](#configuration) for all options. > Tip: start with `AutoApprove__DryRun=true` and check the logs to verify the behaviour before letting it approve anything. ### 3. Run with Docker Compose ```yaml services: seerr-autoapprove: image: git.arnemoerman.be/arne/seerr-autoapprove:latest container_name: seerr-autoapprove restart: unless-stopped env_file: .env ports: - "8080:8080" # only needed if Seerr is not on the same Docker network volumes: - ./data:/data ``` ```sh docker compose up -d docker compose logs -f ``` Keep the `/data` volume: it holds the approval history used to calculate quotas. ### 4. Configure the Seerr webhook (recommended) Without the webhook, requests are picked up on the next poll. With it, they are handled right away. 1. In Seerr go to **Settings → Notifications → Webhook**. 2. Enable the agent. 3. **Webhook URL**: `http://seerr-autoapprove:8080/webhook` (same Docker network) or `http://:8080/webhook`. 4. **Authorization Header**: the same value as `AutoApprove__WebhookSecret` (leave both empty to disable). 5. **Notification types**: enable **Request Pending Approval**. 6. Leave the JSON payload as default — the payload content is ignored, the call only triggers a run. 7. Save and use **Test** — the service log should show a run. ## Configuration All settings are environment variables (see [.env.example](.env.example)). | Variable | Default | Description | |---|---|---| | `Seerr__BaseUrl` | — | Seerr URL, e.g. `http://seerr:5055` (required) | | `Seerr__ApiKey` | — | Seerr API key (required) | | `AutoApprove__MovieLimit` | `5` | Movies per user per period. `-1` = unlimited, `0` = never auto-approve | | `AutoApprove__SeriesLimit` | `5` | Series per user per period | | `AutoApprove__Movie4kLimit` | `0` | 4K movies per user per period | | `AutoApprove__Series4kLimit` | `0` | 4K series per user per period | | `AutoApprove__SeriesCountMode` | `PerSeason` | `PerSeason`: each requested season counts as 1. `PerRequest`: each series request counts as 1 | | `AutoApprove__PeriodType` | `Rolling` | `Rolling` or `Calendar` | | `AutoApprove__RollingDays` | `30` | Window length for `Rolling` | | `AutoApprove__CalendarPeriod` | `Month` | `Day`, `Week` (starts Monday), `Month` or `Year` for `Calendar` | | `AutoApprove__ReevaluateSkippedRequests` | `true` | `true`: requests left pending due to the quota are approved once quota is available again. `false`: they stay pending for manual review | | `AutoApprove__PollIntervalSeconds` | `300` | Fallback poll interval (10–86400) | | `AutoApprove__DryRun` | `false` | Log what would be approved without approving | | `AutoApprove__WebhookSecret` | empty | Required `Authorization` header value for `/webhook` | | `TZ` | container default | Time zone used for calendar periods, e.g. `Europe/Brussels` | ## Endpoints | Method | Path | Description | |---|---|---| | `GET` | `/health` | Health check | | `POST` | `/webhook` | Triggers an immediate run (Seerr webhook target) | ## Development Requires the .NET 10 SDK. ```sh dotnet test dotnet run --project src/SeerrAutoApprove ``` For local runs, set `Seerr__BaseUrl` and `Seerr__ApiKey` as environment variables or in `src/SeerrAutoApprove/appsettings.Development.json`. ## CI [.gitea/workflows/build.yml](.gitea/workflows/build.yml) runs the tests and pushes `git.arnemoerman.be/arne/seerr-autoapprove:latest` plus a datetime tag on every push to `main`. It needs a `PAT_TOKEN` secret with access to the package registry.