Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
269 changes: 197 additions & 72 deletions seerr-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -577,21 +577,9 @@ components:
example: false
baseUrl:
type: string
activeProfileId:
type: number
example: 1
activeProfileName:
type: string
example: 720p/1080p
activeDirectory:
type: string
example: '/movies'
is4k:
type: boolean
example: false
minimumAvailability:
type: string
example: 'In Cinema'
isDefault:
type: boolean
example: false
Expand All @@ -610,11 +598,7 @@ components:
- port
- apiKey
- useSsl
- activeProfileId
- activeProfileName
- activeDirectory
- is4k
- minimumAvailability
- isDefault
SonarrSettings:
type: object
Expand All @@ -640,31 +624,6 @@ components:
example: false
baseUrl:
type: string
activeProfileId:
type: number
example: 1
activeProfileName:
type: string
example: 720p/1080p
activeDirectory:
type: string
example: '/tv/'
activeLanguageProfileId:
type: number
example: 1
activeAnimeProfileId:
type: number
nullable: true
activeAnimeLanguageProfileId:
type: number
nullable: true
activeAnimeProfileName:
type: string
example: 720p/1080p
nullable: true
activeAnimeDirectory:
type: string
nullable: true
is4k:
type: boolean
example: false
Expand All @@ -689,9 +648,6 @@ components:
- port
- apiKey
- useSsl
- activeProfileId
- activeProfileName
- activeDirectory
- is4k
- enableSeasonFolders
- isDefault
Expand Down Expand Up @@ -2083,11 +2039,138 @@ components:
type: string
native_name:
type: string
OverrideRule:
RoutingRule:
type: object
properties:
id:
type: number
readOnly: true
name:
type: string
example: 'Anime Content'
serviceType:
type: string
enum:
- radarr
- sonarr
is4k:
type: boolean
priority:
type: number
users:
type: string
nullable: true
description: Comma-separated user IDs
genres:
type: string
nullable: true
description: Comma-separated genre IDs
languages:
type: string
nullable: true
description: Pipe-separated language codes (e.g. "ja|ko")
keywords:
type: string
nullable: true
description: Comma-separated keyword IDs
targetServiceId:
type: number
description: ID of the target Radarr/Sonarr instance
activeProfileId:
type: number
nullable: true
rootFolder:
type: string
nullable: true
minimumAvailability:
type: string
nullable: true
enum:
- announced
- inCinemas
- released
- null
seriesType:
type: string
nullable: true
enum:
- standard
- daily
- anime
- null
tags:
Comment on lines +2086 to +2101
Copy link

@coderabbitai coderabbitai bot Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Drop "null" from nullable enums to avoid string values.

minimumAvailability and seriesType are already nullable: true. Keeping "null" in the enum makes the string "null" appear valid and can lead generated clients to send "null" instead of JSON null. Remove the "null" entries.

💡 Suggested patch
         minimumAvailability:
           type: string
           nullable: true
           enum:
             - announced
             - inCinemas
             - released
-            - null
         seriesType:
           type: string
           nullable: true
           enum:
             - standard
             - daily
             - anime
-            - null
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type: string
nullable: true
enum:
- announced
- inCinemas
- released
- null
seriesType:
type: string
nullable: true
enum:
- standard
- daily
- anime
- null
tags:
type: string
nullable: true
enum:
- announced
- inCinemas
- released
seriesType:
type: string
nullable: true
enum:
- standard
- daily
- anime
tags:
🤖 Prompt for AI Agents
In `@seerr-api.yml` around lines 2086 - 2101, The enums for minimumAvailability
and seriesType currently include the literal string "null" which allows clients
to send the string instead of a JSON null; remove the "null" entries from the
enum arrays for minimumAvailability and seriesType while keeping nullable: true
so null is still valid, i.e., edit the enum values under minimumAvailability and
seriesType to only list the actual options (e.g., announced, inCinemas, released
and standard, daily, anime) and delete the "null" tokens.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason not having null as an enum value ends up failing validation

{
  "message": "request.body.seriesType should be equal to one of the allowed values: standard, daily, anime",
  "errors": [
    {
      "path": ".body.seriesType",
      "message": "should be equal to one of the allowed values: standard, daily, anime",
      "errorCode": "enum.openapi.validation"
    }
  ]
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fallenbagel, thank you for testing this! You've encountered a known quirk with certain OpenAPI validation middleware implementations.

What's happening: Some validators (like express-openapi-validator) treat enum as a strict whitelist and validate against it before checking nullable. This means even though you've set nullable: true, the validator rejects null values because null isn't explicitly listed in the enum array.

Your workaround is correct: Keeping the literal string "null" in the enum array is the pragmatic solution when using validators with this behavior. While it's not the cleanest approach from a spec perspective, it ensures your validation actually works in practice.

If you want to explore alternatives in the future, you could:

  • Use oneOf: [{ type: "string", enum: [...] }, { type: "null" }] (more verbose but spec-compliant)
  • Switch to a different validation library with better nullable handling
  • Configure your current validator to handle nullable enums differently (if supported)

For now, keeping "null" in the enum is the right call given your validation constraints. 👍

type: string
nullable: true
description: Comma-separated tag IDs
isFallback:
type: boolean
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
RoutingRuleRequest:
type: object
required:
- name
- serviceType
- targetServiceId
properties:
name:
type: string
serviceType:
type: string
enum:
- radarr
- sonarr
is4k:
type: boolean
priority:
type: number
users:
type: string
nullable: true
genres:
type: string
nullable: true
languages:
type: string
nullable: true
keywords:
type: string
nullable: true
targetServiceId:
type: number
activeProfileId:
type: number
nullable: true
minimumAvailability:
type: string
nullable: true
enum:
- announced
- inCinemas
- released
- null
rootFolder:
type: string
nullable: true
seriesType:
type: string
nullable: true
enum:
- standard
- daily
- anime
- null
tags:
Comment on lines 2151 to +2169
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Same nullable-enum issue in RoutingRuleRequest.

The request schema repeats "null" in enums; use nullable: true alone to avoid implying the string "null" is valid.

💡 Suggested patch
         minimumAvailability:
           type: string
           nullable: true
           enum:
             - announced
             - inCinemas
             - released
-            - null
         seriesType:
           type: string
           nullable: true
           enum:
             - standard
             - daily
             - anime
-            - null
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type: string
nullable: true
enum:
- announced
- inCinemas
- released
- null
rootFolder:
type: string
nullable: true
seriesType:
type: string
nullable: true
enum:
- standard
- daily
- anime
- null
tags:
type: string
nullable: true
enum:
- announced
- inCinemas
- released
rootFolder:
type: string
nullable: true
seriesType:
type: string
nullable: true
enum:
- standard
- daily
- anime
tags:
🤖 Prompt for AI Agents
In `@seerr-api.yml` around lines 2151 - 2169, The RoutingRuleRequest schema
wrongly includes the literal string "null" in enum lists (e.g. the enum for the
status field and seriesType) while also using nullable: true; remove the "null"
entries from those enum arrays and keep nullable: true so the fields can be
null, updating the enum for status (announced, inCinemas, released) and
seriesType (standard, daily, anime) to omit "null" and ensure other fields that
use the pattern follow the same change.

type: string
nullable: true
isFallback:
type: boolean
Certification:
type: object
properties:
Expand Down Expand Up @@ -7807,61 +7890,72 @@ paths:
message:
type: string
example: Unable to retrieve TV certifications.
/overrideRule:
/routingRule:
get:
summary: Get override rules
description: Returns a list of all override rules with their conditions and settings
summary: Get all routing rules
description: Returns all routing rules ordered by priority (highest first).
tags:
- overriderule
- settings
responses:
'200':
description: Override rules returned
description: Routing rules returned
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/OverrideRule'
$ref: '#/components/schemas/RoutingRule'
post:
summary: Create override rule
description: Creates a new Override Rule from the request body.
summary: Create a new routing rule
description: Creates a new routing rule. Priority is auto-assigned (highest existing + 10).
tags:
- overriderule
- settings
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RoutingRuleRequest'
responses:
Comment on lines +7909 to 7919
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify priority behavior on create vs. update.

POST /routingRule says priority is auto-assigned, but the request schema still allows priority. Clarify whether provided priority is ignored on create (or split create vs update schemas) to avoid client confusion.

🤖 Prompt for AI Agents
In `@seerr-api.yml` around lines 7909 - 7919, The OpenAPI spec is ambiguous about
priority on create: update the spec so clients know whether a supplied priority
is used. Either remove the priority property from the POST payload by creating a
distinct schema (e.g., RoutingRuleCreateRequest) without priority and reference
it in the POST /routingRule requestBody, and keep RoutingRuleRequest (or
RoutingRuleUpdateRequest) with priority for PUT/PATCH; or explicitly state in
the POST /routingRule description that any provided priority in
RoutingRuleRequest is ignored and the server auto-assigns (highest existing +
10). Update the POST summary/description and the referenced schema name
(RoutingRuleRequest → RoutingRuleCreateRequest if creating a new schema) so the
behavior is unambiguous.

'200':
description: 'Values were successfully created'
'201':
description: Routing rule created
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/OverrideRule'
/overrideRule/{ruleId}:
$ref: '#/components/schemas/RoutingRule'

/routingRule/{ruleId}:
put:
summary: Update override rule
description: Updates an Override Rule from the request body.
summary: Update a routing rule
description: Updates an existing routing rule by ID.
tags:
- overriderule
- settings
parameters:
- in: path
name: ruleId
required: true
schema:
type: number
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RoutingRuleRequest'
responses:
'200':
description: 'Values were successfully updated'
description: Routing rule updated
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/OverrideRule'
$ref: '#/components/schemas/RoutingRule'
'404':
description: Routing rule not found
delete:
summary: Delete override rule by ID
description: Deletes the override rule with the provided ruleId.
summary: Delete a routing rule
description: Deletes a routing rule by ID.
tags:
- overriderule
- settings
parameters:
- in: path
name: ruleId
Expand All @@ -7870,11 +7964,42 @@ paths:
type: number
responses:
'200':
description: Override rule successfully deleted
description: Routing rule deleted
content:
application/json:
schema:
$ref: '#/components/schemas/OverrideRule'
$ref: '#/components/schemas/RoutingRule'
'404':
description: Routing rule not found

/routingRule/reorder:
post:
summary: Reorder routing rules
description: Bulk update priorities by providing an ordered list of rule IDs (highest priority first).
tags:
- settings
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- ruleIds
properties:
ruleIds:
type: array
items:
type: number
responses:
'200':
description: Rules reordered
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/RoutingRule'
security:
- cookieAuth: []
- apiKey: []
Loading
Loading