TVmaze · API Governance Rules

TVmaze API Rules

Spectral linting rules defining API design standards and conventions for TVmaze.

14 Rules error 4 warn 7 info 3
Authorship not recorded No authorship marker is recorded for this file. It is not presented as the provider's; it was most likely written by an API Evangelist pass before outputs were stamped.
View Rules File View on GitHub

Rule Categories

components info operation path paths premium response

Rules

warn
operation-summary-title-case
Operation summaries should be in Title Case.
$.paths[*][get,post,put,delete,patch].summary
error
operation-id-required
Every operation must declare an operationId.
$.paths[*][get,post,put,delete,patch]
warn
operation-id-lower-camel
operationId should be lowerCamelCase.
$.paths[*][get,post,put,delete,patch].operationId
warn
operation-tags-required
Every operation must declare at least one tag.
$.paths[*][get,post,put,delete,patch]
error
paths-no-extension
Paths should not include a file extension.
$.paths[*]~
error
paths-no-trailing-slash
Paths should not end with a trailing slash.
$.paths[*]~
warn
path-segment-lowercase
Path segments should be lowercase, with no underscores.
$.paths[*]~
warn
path-id-integer
Path parameters named `id` (or `*_id`) should be integers.
$.paths[*].parameters[?(@.in=='path' && (@.name=='id' || @.name=~/_id$/))].schema
warn
response-json-required
2xx responses must offer application/json content.
$.paths[*][get,post,put,delete,patch].responses[?(@property.match(/^2/))]
info
response-rate-limit-documented
GET endpoints should document 429 because TVmaze rate-limits at 20 req / 10 sec / IP.
$.paths[*].get.responses
info
premium-paths-namespace
Premium endpoints should live under /v1/user, /v1/scrobble, or /v1/auth.
$.paths[*]~
error
info-license-required
info.license is required.
$.info
info
info-license-creative-commons
TVmaze data is CC BY-SA 4.0; the license field should reflect that.
$.info.license
warn
components-schemas-required
components.schemas should be defined so payloads are reusable.
$.components

Spectral Ruleset

Raw ↑
# Spectral ruleset enforcing TVmaze API conventions.
#
# Derived from analyzing the public and premium TVmaze OpenAPI specifications.
# These rules codify the patterns the provider already follows so contributors and
# downstream consumers stay aligned with the published surface.
extends:
  - spectral:oas

functions:
  - length

rules:
  # All operations should have descriptive Title Case summaries.
  operation-summary-title-case:
    description: Operation summaries should be in Title Case.
    message: "{{property}} summary should be Title Case"
    given: $.paths[*][get,post,put,delete,patch].summary
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[A-Z0-9][A-Za-z0-9 /()_'-]*$"

  # Every operation must have an operationId.
  operation-id-required:
    description: Every operation must declare an operationId.
    given: $.paths[*][get,post,put,delete,patch]
    severity: error
    then:
      field: operationId
      function: truthy

  # operationIds are lowerCamelCase verbs like getShow, listShows, searchPeople.
  operation-id-lower-camel:
    description: operationId should be lowerCamelCase.
    given: $.paths[*][get,post,put,delete,patch].operationId
    severity: warn
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][A-Za-z0-9]*$"

  # Every operation must declare at least one tag.
  operation-tags-required:
    description: Every operation must declare at least one tag.
    given: $.paths[*][get,post,put,delete,patch]
    severity: warn
    then:
      field: tags
      function: truthy

  # Public TVmaze uses RESTful collection / item paths — disallow .json suffix or trailing slashes.
  paths-no-extension:
    description: Paths should not include a file extension.
    given: $.paths[*]~
    severity: error
    then:
      function: pattern
      functionOptions:
        notMatch: "\\.(json|xml|yaml|yml)$"

  paths-no-trailing-slash:
    description: Paths should not end with a trailing slash.
    given: $.paths[*]~
    severity: error
    then:
      function: pattern
      functionOptions:
        notMatch: "/$"

  # Public TVmaze uses lowercase, hyphen-free path segments (singlesearch, episodebynumber).
  path-segment-lowercase:
    description: Path segments should be lowercase, with no underscores.
    given: $.paths[*]~
    severity: warn
    then:
      function: pattern
      functionOptions:
        notMatch: "[A-Z]"

  # IDs are integers in TVmaze.
  path-id-integer:
    description: "Path parameters named `id` (or `*_id`) should be integers."
    given: "$.paths[*].parameters[?(@.in=='path' && (@.name=='id' || @.name=~/_id$/))].schema"
    severity: warn
    then:
      field: type
      function: enumeration
      functionOptions:
        values: [integer]

  # All success responses should declare an application/json content type.
  response-json-required:
    description: 2xx responses must offer application/json content.
    given: "$.paths[*][get,post,put,delete,patch].responses[?(@property.match(/^2/))]"
    severity: warn
    then:
      field: content.application/json
      function: truthy

  # 429 should be a documented response anywhere — TVmaze applies 20 req / 10 sec / IP.
  response-rate-limit-documented:
    description: GET endpoints should document 429 because TVmaze rate-limits at 20 req / 10 sec / IP.
    given: $.paths[*].get.responses
    severity: info
    then:
      field: "429"
      function: truthy

  # Premium API: every authenticated path lives under /v1/user, /v1/scrobble or /v1/auth.
  premium-paths-namespace:
    description: Premium endpoints should live under /v1/user, /v1/scrobble, or /v1/auth.
    given: $.paths[*]~
    severity: info
    then:
      function: pattern
      functionOptions:
        match: "^/(search|singlesearch|lookup|shows|seasons|episodes|people|schedule|updates|user|scrobble|auth)(/|$)"

  # info.license is required and should be CC BY-SA for TVmaze.
  info-license-required:
    description: info.license is required.
    given: $.info
    severity: error
    then:
      field: license
      function: truthy

  info-license-creative-commons:
    description: TVmaze data is CC BY-SA 4.0; the license field should reflect that.
    given: $.info.license
    severity: info
    then:
      field: name
      function: pattern
      functionOptions:
        match: "CC BY-SA"

  # Components.schemas should be defined and operations should reference them, not inline blobs.
  components-schemas-required:
    description: components.schemas should be defined so payloads are reusable.
    given: $.components
    severity: warn
    then:
      field: schemas
      function: truthy

Work with this as data

Every ruleset here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for spectral rules

4 MCP tools reach this
  • find_rulesBrowse and filter every ruleset in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This ruleset
curl "https://apis.io/api/v1/rules/tvmaze-rules"
All spectral rules
curl "https://apis.io/api/v1/rules?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.