Breaking Bad · API Governance Rules

Breaking Bad API Rules

Spectral linting rules defining API design standards and conventions for Breaking Bad.

32 Rules error 10 warn 13 info 9
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

delete get info openapi operation parameter paths response schema security servers tag tags

Rules

warn
info-title-format
Title must begin with "Breaking Bad".
$.info.title
warn
info-description-required
Info description must be present and meaningful.
$.info
error
info-version-required
Info version must be present.
$.info
info
info-license-required
A license should be declared for community APIs.
$.info
error
openapi-version-3
Spec must be OpenAPI 3.x.
$.openapi
warn
servers-defined
At least one server must be defined.
$.servers
warn
servers-https-or-noted
Server URLs should use HTTPS.
$.servers[*].url
error
paths-no-trailing-slash
Paths must not end with a trailing slash.
$.paths[*]~
warn
paths-kebab-case
Path segments should be kebab-case (lowercase, hyphen-separated).
$.paths[*]~
error
operation-summary-required
Every operation must have a summary.
$.paths[*][get,post,put,patch,delete]
warn
operation-description-required
Every operation must have a description.
$.paths[*][get,post,put,patch,delete]
error
operation-operationid-required
Every operation must have an operationId.
$.paths[*][get,post,put,patch,delete]
warn
operation-operationid-camelcase
operationId must be camelCase.
$.paths[*][get,post,put,patch,delete].operationId
info
operation-operationid-verb-prefix
operationId should start with a known verb (get, list, create, update, delete).
$.paths[*][get,post,put,patch,delete].operationId
info
operation-summary-title-case
Summary should use Title Case.
$.paths[*][get,post,put,patch,delete].summary
error
operation-tags-required
Every operation must have at least one tag.
$.paths[*][get,post,put,patch,delete]
info
operation-microcks-extension
Each operation should declare an x-microcks-operation extension.
$.paths[*][get,post,put,patch,delete]
warn
tags-global-defined
Global tags array must be defined.
$
warn
tag-title-case
Tag names should use Title Case.
$.tags[*].name
warn
tag-description-required
Each tag must have a description.
$.tags[*]
warn
parameter-description-required
Each parameter must have a description.
$.paths[*][*].parameters[*]
info
parameter-snake-case
Parameter names should be snake_case (matches upstream conventions).
$.paths[*][*].parameters[*].name
error
response-2xx-required
Every operation must declare a 2xx response.
$.paths[*][get,post,put,patch,delete].responses
info
response-rate-limit-documented
List endpoints should document a 429 response (the upstream enforced 10k/day).
$.paths[/characters,/quotes,/episodes,/deaths][get].responses
error
response-description-required
Every response must have a description.
$.paths[*][*].responses[*]
warn
schema-snake-case-properties
Schema property names should be snake_case (matches the upstream JSON contract).
$.components.schemas[*].properties[*]~
info
schema-property-description
Every schema property should have a description.
$.components.schemas[*].properties[*]
error
schema-property-type
Every schema property must declare a type or $ref.
$.components.schemas[*].properties[*]
info
security-not-required
Breaking Bad API was anonymous-access; security blocks are optional.
$
error
get-no-request-body
GET operations must not declare a requestBody.
$.paths[*].get
warn
delete-no-request-body
DELETE operations must not declare a requestBody.
$.paths[*].delete
info
info-deprecation-noted
Deprecated APIs must declare x-status and x-deprecation-note.
$.info

Spectral Ruleset

Raw ↑
extends:
  - spectral:oas

functions: []

rules:
  # ── INFO / METADATA ───────────────────────────────────────────────
  info-title-format:
    description: Title must begin with "Breaking Bad".
    severity: warn
    given: "$.info.title"
    then:
      function: pattern
      functionOptions:
        match: "^Breaking Bad"

  info-description-required:
    description: Info description must be present and meaningful.
    severity: warn
    given: "$.info"
    then:
      field: description
      function: truthy

  info-version-required:
    description: Info version must be present.
    severity: error
    given: "$.info"
    then:
      field: version
      function: truthy

  info-license-required:
    description: A license should be declared for community APIs.
    severity: info
    given: "$.info"
    then:
      field: license
      function: truthy

  # ── OPENAPI VERSION ──────────────────────────────────────────────
  openapi-version-3:
    description: Spec must be OpenAPI 3.x.
    severity: error
    given: "$.openapi"
    then:
      function: pattern
      functionOptions:
        match: "^3\\."

  # ── SERVERS ──────────────────────────────────────────────────────
  servers-defined:
    description: At least one server must be defined.
    severity: warn
    given: "$.servers"
    then:
      function: truthy

  servers-https-or-noted:
    description: Server URLs should use HTTPS.
    severity: warn
    given: "$.servers[*].url"
    then:
      function: pattern
      functionOptions:
        match: "^https?://"

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

  paths-kebab-case:
    description: Path segments should be kebab-case (lowercase, hyphen-separated).
    severity: warn
    given: "$.paths[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^(/[a-z0-9-]+(/\\{[a-zA-Z0-9_]+\\})?)+$"

  # ── OPERATIONS ───────────────────────────────────────────────────
  operation-summary-required:
    description: Every operation must have a summary.
    severity: error
    given: "$.paths[*][get,post,put,patch,delete]"
    then:
      field: summary
      function: truthy

  operation-description-required:
    description: Every operation must have a description.
    severity: warn
    given: "$.paths[*][get,post,put,patch,delete]"
    then:
      field: description
      function: truthy

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

  operation-operationid-camelcase:
    description: operationId must be camelCase.
    severity: warn
    given: "$.paths[*][get,post,put,patch,delete].operationId"
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-zA-Z0-9]*$"

  operation-operationid-verb-prefix:
    description: operationId should start with a known verb (get, list, create, update, delete).
    severity: info
    given: "$.paths[*][get,post,put,patch,delete].operationId"
    then:
      function: pattern
      functionOptions:
        match: "^(get|list|create|update|delete|search)"

  operation-summary-title-case:
    description: Summary should use Title Case.
    severity: info
    given: "$.paths[*][get,post,put,patch,delete].summary"
    then:
      function: pattern
      functionOptions:
        match: "^([A-Z][A-Za-z0-9]*)(\\s+(By|Of|In|On|For|To|A|An|The|And|Or)?\\s*[A-Z][A-Za-z0-9]*)*$"

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

  operation-microcks-extension:
    description: Each operation should declare an x-microcks-operation extension.
    severity: info
    given: "$.paths[*][get,post,put,patch,delete]"
    then:
      field: x-microcks-operation
      function: truthy

  # ── TAGS ─────────────────────────────────────────────────────────
  tags-global-defined:
    description: Global tags array must be defined.
    severity: warn
    given: "$"
    then:
      field: tags
      function: truthy

  tag-title-case:
    description: Tag names should use Title Case.
    severity: warn
    given: "$.tags[*].name"
    then:
      function: pattern
      functionOptions:
        match: "^[A-Z][A-Za-z]*$"

  tag-description-required:
    description: Each tag must have a description.
    severity: warn
    given: "$.tags[*]"
    then:
      field: description
      function: truthy

  # ── PARAMETERS ───────────────────────────────────────────────────
  parameter-description-required:
    description: Each parameter must have a description.
    severity: warn
    given: "$.paths[*][*].parameters[*]"
    then:
      field: description
      function: truthy

  parameter-snake-case:
    description: Parameter names should be snake_case (matches upstream conventions).
    severity: info
    given: "$.paths[*][*].parameters[*].name"
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-z0-9_]*$|^id$"

  # ── RESPONSES ────────────────────────────────────────────────────
  response-2xx-required:
    description: Every operation must declare a 2xx response.
    severity: error
    given: "$.paths[*][get,post,put,patch,delete].responses"
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          patternProperties:
            "^2\\d\\d$": { type: object }
          minProperties: 1

  response-rate-limit-documented:
    description: List endpoints should document a 429 response (the upstream enforced 10k/day).
    severity: info
    given: "$.paths[/characters,/quotes,/episodes,/deaths][get].responses"
    then:
      field: "429"
      function: truthy

  response-description-required:
    description: Every response must have a description.
    severity: error
    given: "$.paths[*][*].responses[*]"
    then:
      field: description
      function: truthy

  # ── SCHEMAS ──────────────────────────────────────────────────────
  schema-snake-case-properties:
    description: Schema property names should be snake_case (matches the upstream JSON contract).
    severity: warn
    given: "$.components.schemas[*].properties[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-z0-9_]*$"

  schema-property-description:
    description: Every schema property should have a description.
    severity: info
    given: "$.components.schemas[*].properties[*]"
    then:
      field: description
      function: truthy

  schema-property-type:
    description: Every schema property must declare a type or $ref.
    severity: error
    given: "$.components.schemas[*].properties[*]"
    then:
      function: schema
      functionOptions:
        schema:
          anyOf:
            - required: [type]
            - required: ["$ref"]

  # ── SECURITY ─────────────────────────────────────────────────────
  security-not-required:
    description: Breaking Bad API was anonymous-access; security blocks are optional.
    severity: info
    given: "$"
    then:
      field: security
      function: defined

  # ── HTTP METHOD CONVENTIONS ──────────────────────────────────────
  get-no-request-body:
    description: GET operations must not declare a requestBody.
    severity: error
    given: "$.paths[*].get"
    then:
      field: requestBody
      function: falsy

  delete-no-request-body:
    description: DELETE operations must not declare a requestBody.
    severity: warn
    given: "$.paths[*].delete"
    then:
      field: requestBody
      function: falsy

  # ── DEPRECATION ──────────────────────────────────────────────────
  info-deprecation-noted:
    description: Deprecated APIs must declare x-status and x-deprecation-note.
    severity: info
    given: "$.info"
    then:
      field: x-status
      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/breaking-bad-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.