Svix · API Governance Rules

Svix API Rules

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

14 Rules error 4 warn 8 info 2
View Rules File View on GitHub

Rule Categories

svix

Rules

warn
svix-operation-summary-title-case
Operation summaries are in Title Case ("Create Application", not "create application").
#AllOperations
error
svix-operation-id-camel-case
operationId values are lowerCamelCase (e.g. v1ApplicationCreate).
#AllOperations
error
svix-schema-pascal-case
Schema component names are PascalCase (ApplicationIn, EndpointOut).
$.components.schemas[*]~
warn
svix-property-camel-case
Schema properties are camelCase (createdAt, throttleRate, eventType).
$.components.schemas[*].properties[*]~
error
svix-path-version-prefix
Every path starts with /api/v1/ or /ingest/api/v1/.
$.paths[*]~
warn
svix-path-kebab-case
Path segments are kebab-case or snake_case templated IDs ({app_id}).
$.paths[*]~
error
svix-security-bearer-required
HTTP Bearer auth must be defined in components.securitySchemes.
$.components.securitySchemes
warn
svix-security-applied
Every non-health operation requires HTTPBearer auth.
$.paths[?([email protected](/health/))][get,put,post,delete,patch]
warn
svix-app-id-pattern
app_id path params have the prefixed-KSUID pattern `^app_[A-Za-z0-9]{27}$`.
$.components.schemas.ApplicationOut.properties.id
warn
svix-endpoint-id-pattern
endpoint_id values have the prefixed-KSUID pattern `^ep_[A-Za-z0-9]{27}$`.
$.components.schemas.EndpointOut.properties.id
warn
svix-msg-id-pattern
msg_id values have the prefixed-KSUID pattern `^msg_[A-Za-z0-9]{27}$`.
$.components.schemas.MessageOut.properties.id
info
svix-list-pagination
List responses use iterator-based pagination with `data`, `iterator`, `prevIterator`, `done`.
$.components.schemas[?(@property.match(/ListResponse_/))]
warn
svix-error-response-shape
4xx responses reference the standard HTTPError or HttpValidationError schemas.
$.paths[*][get,put,post,delete,patch].responses[?(@property.match(/^4\d\d$/))]
info
svix-post-idempotency-key
POST operations accept an Idempotency-Key header (Svix-wide idempotency support).
$.paths[*].post

Spectral Ruleset

Raw ↑
extends:
  - spectral:oas

documentationUrl: https://api.svix.com/docs

# Spectral ruleset enforcing the conventions observed in the Svix
# hosted OpenAPI (svix-openapi.json, info.version 1.84.0). These
# rules are descriptive — they describe what Svix does — and
# prescriptive — they fail builds for new endpoints that drift.

aliases:
  AllOperations:
    - "$.paths[*][get,put,post,delete,patch]"

rules:
  # ---------------------------------------------------------------
  # Naming & casing
  # ---------------------------------------------------------------
  svix-operation-summary-title-case:
    description: Operation summaries are in Title Case ("Create Application", not "create application").
    severity: warn
    given: "#AllOperations"
    then:
      field: summary
      function: pattern
      functionOptions:
        match: "^([A-Z][A-Za-z0-9]*)(\\s[A-Z0-9][A-Za-z0-9]*)*$"

  svix-operation-id-camel-case:
    description: operationId values are lowerCamelCase (e.g. v1ApplicationCreate).
    severity: error
    given: "#AllOperations"
    then:
      field: operationId
      function: pattern
      functionOptions:
        match: "^[a-z][a-zA-Z0-9]+$"

  svix-schema-pascal-case:
    description: Schema component names are PascalCase (ApplicationIn, EndpointOut).
    severity: error
    given: "$.components.schemas[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^[A-Z][A-Za-z0-9]+$"

  svix-property-camel-case:
    description: Schema properties are camelCase (createdAt, throttleRate, eventType).
    severity: warn
    given: "$.components.schemas[*].properties[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^[a-z][a-zA-Z0-9]*$"

  # ---------------------------------------------------------------
  # URL & versioning conventions
  # ---------------------------------------------------------------
  svix-path-version-prefix:
    description: Every path starts with /api/v1/ or /ingest/api/v1/.
    severity: error
    given: "$.paths[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^/(api|ingest/api)/v1/"

  svix-path-kebab-case:
    description: Path segments are kebab-case or snake_case templated IDs ({app_id}).
    severity: warn
    given: "$.paths[*]~"
    then:
      function: pattern
      functionOptions:
        match: "^/[a-z0-9_/\\-{}]+$"

  # ---------------------------------------------------------------
  # Authentication
  # ---------------------------------------------------------------
  svix-security-bearer-required:
    description: HTTP Bearer auth must be defined in components.securitySchemes.
    severity: error
    given: "$.components.securitySchemes"
    then:
      field: HTTPBearer
      function: truthy

  svix-security-applied:
    description: Every non-health operation requires HTTPBearer auth.
    severity: warn
    given: "$.paths[?([email protected](/health/))][get,put,post,delete,patch]"
    then:
      field: security
      function: truthy

  # ---------------------------------------------------------------
  # Resource identifier patterns
  # ---------------------------------------------------------------
  svix-app-id-pattern:
    description: app_id path params have the prefixed-KSUID pattern `^app_[A-Za-z0-9]{27}$`.
    severity: warn
    given: "$.components.schemas.ApplicationOut.properties.id"
    then:
      field: pattern
      function: pattern
      functionOptions:
        match: "^\\^app_"

  svix-endpoint-id-pattern:
    description: endpoint_id values have the prefixed-KSUID pattern `^ep_[A-Za-z0-9]{27}$`.
    severity: warn
    given: "$.components.schemas.EndpointOut.properties.id"
    then:
      field: pattern
      function: pattern
      functionOptions:
        match: "^\\^ep_"

  svix-msg-id-pattern:
    description: msg_id values have the prefixed-KSUID pattern `^msg_[A-Za-z0-9]{27}$`.
    severity: warn
    given: "$.components.schemas.MessageOut.properties.id"
    then:
      field: pattern
      function: pattern
      functionOptions:
        match: "^\\^msg_"

  # ---------------------------------------------------------------
  # Pagination
  # ---------------------------------------------------------------
  svix-list-pagination:
    description: List responses use iterator-based pagination with `data`, `iterator`, `prevIterator`, `done`.
    severity: info
    given: "$.components.schemas[?(@property.match(/ListResponse_/))]"
    then:
      field: properties
      function: schema
      functionOptions:
        schema:
          type: object
          required: [data, iterator, prevIterator, done]

  # ---------------------------------------------------------------
  # Errors
  # ---------------------------------------------------------------
  svix-error-response-shape:
    description: 4xx responses reference the standard HTTPError or HttpValidationError schemas.
    severity: warn
    given: "$.paths[*][get,put,post,delete,patch].responses[?(@property.match(/^4\\d\\d$/))]"
    then:
      field: content.application/json.schema.$ref
      function: pattern
      functionOptions:
        match: "(HTTPError|HttpValidationError)$"

  # ---------------------------------------------------------------
  # Idempotency
  # ---------------------------------------------------------------
  svix-post-idempotency-key:
    description: POST operations accept an Idempotency-Key header (Svix-wide idempotency support).
    severity: info
    given: "$.paths[*].post"
    then:
      field: parameters
      function: truthy