ColorfulClouds · API Governance Rules

ColorfulClouds API Rules

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

39 Rules error 12 warn 22 info 5
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

caiyun examples get info no openapi operation parameter paths response schema security servers tags

Rules

error
info-title-required
API title must be present and start with the provider prefix.
$.info
warn
info-description-min-length
API description must be present and detailed (>= 80 chars).
$.info
error
info-version-required
API version must be present.
$.info
warn
info-contact-required
Contact object must be present with a URL.
$.info.contact
error
openapi-version-3
Spec must target OpenAPI 3.x.
$.openapi
error
servers-required
Servers array must be defined.
$
error
servers-https-only
All server URLs must use HTTPS.
$.servers[*]
warn
servers-canonical-host
Servers should target api.caiyunapp.com.
$.servers[*]
error
paths-no-trailing-slash
Paths must not end with a trailing slash.
$.paths
warn
paths-lowercase
Path segments must be lowercase (kebab-case allowed).
$.paths
warn
paths-token-in-path
Caiyun encodes the API token as a path segment. Forecast paths must include the {token} parameter immediately after the version prefix.
$.paths
error
operation-operationId-required
Every operation must have an operationId.
$.paths[*][get,post,put,patch,delete]
warn
operation-operationId-camel
operationId must be camelCase.
$.paths[*][get,post,put,patch,delete]
error
operation-summary-required
Every operation must have a summary.
$.paths[*][get,post,put,patch,delete]
warn
operation-summary-prefix
Summaries must begin with "Caiyun Weather".
$.paths[*][get,post,put,patch,delete]
warn
operation-description-required
Every operation must have a description.
$.paths[*][get,post,put,patch,delete]
warn
operation-tags-required
Every operation must declare at least one tag.
$.paths[*][get,post,put,patch,delete]
info
operation-microcks-extension
Each operation should declare x-microcks-operation for mock parity.
$.paths[*][get,post,put,patch,delete]
warn
tags-global-defined
Global tags array must be defined with descriptions.
$
warn
tags-title-case
Global tag names must use Title Case (no kebab, no snake).
$.tags[*]
info
tags-description-required
Global tags must have descriptions.
$.tags[*]
warn
parameter-description-required
Every parameter must have a description.
$..parameters[*]
warn
parameter-snake-case
Query and path parameters must use snake_case (lng, lat, dailysteps, hourlysteps, alert, begin, granu).
$..parameters[?(@.in == 'query')]
error
parameter-schema-required
Every parameter must declare a schema with a type.
$..parameters[*]
error
response-2xx-required
Each operation must declare at least one 2xx response.
$.paths[*][get,post,put,patch,delete].responses
warn
response-401-on-token-paths
Token-bearing endpoints should document 401 Unauthorized responses.
$.paths[?(@property.match(/\{token\}/))][get].responses
warn
response-429-on-token-paths
Token-bearing endpoints should document 429 Too Many Requests responses.
$.paths[?(@property.match(/\{token\}/))][get].responses
warn
response-description-required
Every response object must have a description.
$.paths[*][get,post,put,patch,delete].responses[*]
info
response-json-content
Successful responses should be application/json (except precipitation map tiles).
$.paths[?(!@property.match(/precipitation/))][get].responses.200.content
warn
schema-property-snake-case
Schema property names must use snake_case to match Caiyun's JSON wire format (precipitation_2h, apparent_temperature, life_index, air_quality, cloudrate, dswrf, etc.). Exemptions are made for life-index sub-keys that ship in camelCase from the upstream API (carWashing, coldRisk).
$.components.schemas[*].properties
warn
schema-type-required
Top-level schemas must declare a type.
$.components.schemas[*]
info
schema-description-required
Top-level schemas should carry a description.
$.components.schemas[*]
warn
schema-skycon-enum
SkyCon enum must include the canonical Caiyun phenomena.
$.components.schemas.SkyCon
warn
security-defined
Global security must be declared.
$
error
security-schemes-defined
Security schemes must be defined.
$.components.securitySchemes
error
get-no-request-body
GET operations must not declare a request body.
$.paths[*].get
warn
caiyun-get-only-api
The Caiyun Weather API is read-only — operations should use GET.
$.paths[*]
warn
no-empty-descriptions
Descriptions must not be empty strings.
$..description
info
examples-on-parameters
Parameters should carry an example value.
$..parameters[*]

Spectral Ruleset

Raw ↑
# Caiyun Weather API (ColorfulClouds) — Spectral Ruleset
#
# Opinionated ruleset enforcing the conventions observed across the
# Caiyun Weather v2.6 OpenAPI spec. Path-embedded token, lng,lat tuple
# in path, snake_case JSON properties, camelCase operationIds, and
# Title Case tags prefixed with "Caiyun Weather".

rules:

  # ── INFO / METADATA ──────────────────────────────────────────────
  info-title-required:
    description: API title must be present and start with the provider prefix.
    severity: error
    given: $.info
    then:
      - field: title
        function: truthy
      - field: title
        function: pattern
        functionOptions:
          match: '^Caiyun Weather'

  info-description-min-length:
    description: API description must be present and detailed (>= 80 chars).
    severity: warn
    given: $.info
    then:
      - field: description
        function: truthy
      - field: description
        function: length
        functionOptions:
          min: 80

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

  info-contact-required:
    description: Contact object must be present with a URL.
    severity: warn
    given: $.info.contact
    then:
      - field: url
        function: truthy

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

  # ── SERVERS ──────────────────────────────────────────────────────
  servers-required:
    description: Servers array must be defined.
    severity: error
    given: $
    then:
      field: servers
      function: truthy

  servers-https-only:
    description: All server URLs must use HTTPS.
    severity: error
    given: $.servers[*]
    then:
      field: url
      function: pattern
      functionOptions:
        match: '^https://'

  servers-canonical-host:
    description: Servers should target api.caiyunapp.com.
    severity: warn
    given: $.servers[*]
    then:
      field: url
      function: pattern
      functionOptions:
        match: 'api\.caiyunapp\.com'

  # ── PATHS ────────────────────────────────────────────────────────
  paths-no-trailing-slash:
    description: Paths must not end with a trailing slash.
    severity: error
    given: $.paths
    then:
      field: '@key'
      function: pattern
      functionOptions:
        notMatch: '.+/$'

  paths-lowercase:
    description: Path segments must be lowercase (kebab-case allowed).
    severity: warn
    given: $.paths
    then:
      field: '@key'
      function: pattern
      functionOptions:
        match: '^[/{}a-z0-9._\-,]+$'

  paths-token-in-path:
    description: >-
      Caiyun encodes the API token as a path segment. Forecast paths must
      include the {token} parameter immediately after the version prefix.
    severity: warn
    given: $.paths
    then:
      field: '@key'
      function: pattern
      functionOptions:
        match: '^/(\{token\}/|precipitation/)'

  # ── OPERATIONS ───────────────────────────────────────────────────
  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-camel:
    description: operationId must be camelCase.
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: operationId
      function: pattern
      functionOptions:
        match: '^[a-z][a-zA-Z0-9]+$'

  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-summary-prefix:
    description: Summaries must begin with "Caiyun Weather".
    severity: warn
    given: $.paths[*][get,post,put,patch,delete]
    then:
      field: summary
      function: pattern
      functionOptions:
        match: '^Caiyun Weather '

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

  operation-microcks-extension:
    description: Each operation should declare x-microcks-operation for mock parity.
    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 with descriptions.
    severity: warn
    given: $
    then:
      field: tags
      function: truthy

  tags-title-case:
    description: Global tag names must use Title Case (no kebab, no snake).
    severity: warn
    given: $.tags[*]
    then:
      field: name
      function: pattern
      functionOptions:
        match: '^[A-Z][A-Za-z0-9]*( [A-Z][A-Za-z0-9]*)*$'

  tags-description-required:
    description: Global tags must have descriptions.
    severity: info
    given: $.tags[*]
    then:
      field: description
      function: truthy

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

  parameter-snake-case:
    description: Query and path parameters must use snake_case (lng, lat, dailysteps, hourlysteps, alert, begin, granu).
    severity: warn
    given: $..parameters[?(@.in == 'query')]
    then:
      field: name
      function: pattern
      functionOptions:
        match: '^[a-z][a-z0-9_]*$'

  parameter-schema-required:
    description: Every parameter must declare a schema with a type.
    severity: error
    given: $..parameters[*]
    then:
      - field: schema
        function: truthy

  # ── RESPONSES ────────────────────────────────────────────────────
  response-2xx-required:
    description: Each operation must declare at least one 2xx response.
    severity: error
    given: $.paths[*][get,post,put,patch,delete].responses
    then:
      function: schema
      functionOptions:
        schema:
          anyOf:
            - required: ['200']
            - required: ['201']
            - required: ['202']
            - required: ['204']

  response-401-on-token-paths:
    description: Token-bearing endpoints should document 401 Unauthorized responses.
    severity: warn
    given: $.paths[?(@property.match(/\{token\}/))][get].responses
    then:
      field: '401'
      function: truthy

  response-429-on-token-paths:
    description: Token-bearing endpoints should document 429 Too Many Requests responses.
    severity: warn
    given: $.paths[?(@property.match(/\{token\}/))][get].responses
    then:
      field: '429'
      function: truthy

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

  response-json-content:
    description: Successful responses should be application/json (except precipitation map tiles).
    severity: info
    given: $.paths[?(!@property.match(/precipitation/))][get].responses.200.content
    then:
      field: application/json
      function: truthy

  # ── SCHEMAS ──────────────────────────────────────────────────────
  schema-property-snake-case:
    description: >-
      Schema property names must use snake_case to match Caiyun's JSON wire
      format (precipitation_2h, apparent_temperature, life_index, air_quality,
      cloudrate, dswrf, etc.). Exemptions are made for life-index sub-keys
      that ship in camelCase from the upstream API (carWashing, coldRisk).
    severity: warn
    given: $.components.schemas[*].properties
    then:
      field: '@key'
      function: pattern
      functionOptions:
        match: '^([a-z][a-z0-9_]*|carWashing|coldRisk)$'

  schema-type-required:
    description: Top-level schemas must declare a type.
    severity: warn
    given: $.components.schemas[*]
    then:
      field: type
      function: truthy

  schema-description-required:
    description: Top-level schemas should carry a description.
    severity: info
    given: $.components.schemas[*]
    then:
      field: description
      function: truthy

  schema-skycon-enum:
    description: SkyCon enum must include the canonical Caiyun phenomena.
    severity: warn
    given: $.components.schemas.SkyCon
    then:
      field: enum
      function: schema
      functionOptions:
        schema:
          type: array
          contains:
            enum:
              - CLEAR_DAY
              - CLEAR_NIGHT
              - PARTLY_CLOUDY_DAY
              - PARTLY_CLOUDY_NIGHT
              - CLOUDY
              - LIGHT_RAIN
              - HEAVY_RAIN

  # ── SECURITY ─────────────────────────────────────────────────────
  security-defined:
    description: Global security must be declared.
    severity: warn
    given: $
    then:
      field: security
      function: truthy

  security-schemes-defined:
    description: Security schemes must be defined.
    severity: error
    given: $.components.securitySchemes
    then:
      function: truthy

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

  caiyun-get-only-api:
    description: >-
      The Caiyun Weather API is read-only — operations should use GET.
    severity: warn
    given: $.paths[*]
    then:
      function: schema
      functionOptions:
        schema:
          not:
            anyOf:
              - required: [post]
              - required: [put]
              - required: [patch]
              - required: [delete]

  # ── GENERAL QUALITY ─────────────────────────────────────────────
  no-empty-descriptions:
    description: Descriptions must not be empty strings.
    severity: warn
    given: $..description
    then:
      function: truthy

  examples-on-parameters:
    description: Parameters should carry an example value.
    severity: info
    given: $..parameters[*]
    then:
      field: example
      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/colorfulclouds-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.