1. Examples
  2. API Linting

API Linting

Enforce API design standards and consistency across your team with automated linting.

Deploy to Zuplo
Deploy to Zuplo

Prerequisite: You need a Zuplo account to run this example. Sign up for free

This example demonstrates how to lint your Zuplo API using Vacuum, an OpenAPI linter. It includes both built-in OpenAPI rules and custom rules specific to Zuplo projects, such as requiring certain policies on all routes.

Prerequisites

  • A Zuplo account. You can sign up for free.
  • Node.js installed locally

Working with this Example

Locally

Working locally is the best way to explore and understand the code for this example. You can get a local version by using the Zuplo CLI:

Terminalbash
npx create-zuplo-api@latest --example api-linting

Then, in the project directory run the following commands:

Terminalbash
npm install
npm run lint

Deploy this example to Zuplo

It is also possible to deploy this example directly to your Zuplo account and work with it via the Zuplo Portal. You can do this by clicking the Deploy to Zuplo button anywhere on this page.

How It Works

Ruleset Configuration

The linting rules are defined in config/api-ruleset.yaml. This file configures both standard OpenAPI rules and custom Zuplo-specific rules.

Built-in Rules

Standard OpenAPI validation rules can be enabled:

YAMLyaml
rules:
  oas3-schema: true
  oas3-api-servers: false
  oas3-unused-component: false

Custom Zuplo Rules

This example includes custom rules that enforce Zuplo-specific requirements:

1. Valid Path Mode

Ensures x-zuplo-path.pathMode is either open-api or url-pattern:

YAMLyaml
zuplo-valid-path-mode:
  description: Zuplo pathMode must be 'open-api' or 'url-pattern'
  given: $.paths.*.x-zuplo-path
  severity: error
  then:
    field: pathMode
    function: pattern
    functionOptions:
      match: "^(open-api|url-pattern)$"

2. Required Route Configuration

Ensures all operations have x-zuplo-route with required properties:

YAMLyaml
zuplo-route-required-properties:
  description: Zuplo route must have required properties
  given: "$.paths[*]['get','put','post','delete','options','head','patch','trace'].x-zuplo-route"
  severity: error
  then:
    - field: corsPolicy
      function: truthy
    - field: handler
      function: truthy
    - field: policies
      function: truthy

3. Required Policy

Ensures all routes have a specific policy (e.g., authentication):

YAMLyaml
zuplo-require-policy:
  description: Require all routes have a specific zuplo policy
  severity: error
  given: "$.paths[*]['get','put','post','delete','options','head','patch','trace'].x-zuplo-route.policies.inbound"
  then:
    function: zuploRequiredPolicy
    functionOptions:
      policyName: "my-auth-policy"

4. Path Prefix

Ensures all paths start with a specific value (e.g., /v1):

YAMLyaml
path-starts-with:
  description: Require all paths to start with a specific value
  severity: error
  given: "$.paths"
  then:
    function: pathStartsWithPolicy
    functionOptions:
      startsWith: "/v1"

Project Structure

text
├── config/
│   ├── api-ruleset.yaml     # Linting rules configuration
│   ├── policies.json        # Policy configurations
│   └── routes.oas.json      # Route definitions to lint
└── lint-functions/
    ├── zuploRequiredPolicy.js   # Custom function: require specific policy
    └── pathStartsWithPolicy.js  # Custom function: validate path prefix

Running the Linter

Run the linter against your routes:

Terminalbash
npm run lint

Example output when rules fail:

text
ERROR: zuplo-require-policy - Require all routes have a specific zuplo policy
  at $.paths./v1/todos.post.x-zuplo-route.policies.inbound

ERROR: path-starts-with - Require all paths to start with a specific value
  at $.paths./users

Customizing Rules

Change Required Policy Name

Edit config/api-ruleset.yaml:

YAMLyaml
zuplo-require-policy:
  then:
    function: zuploRequiredPolicy
    functionOptions:
      policyName: "api-key-auth"  # Change to your policy name

Change Required Path Prefix

YAMLyaml
path-starts-with:
  then:
    function: pathStartsWithPolicy
    functionOptions:
      startsWith: "/api/v2"  # Change to your prefix

Add More Custom Functions

Create a new JavaScript file in lint-functions/ and reference it in your ruleset:

Javascriptjavascript
// lint-functions/myCustomRule.js
export default function (input, options) {
  // Return array of errors, or empty array if valid
  return [];
}

CI/CD Integration

Add linting to your CI pipeline to catch issues before deployment:

YAMLyaml
# GitHub Actions example
- name: Lint API
  run: npm run lint

Learn More

  • Vacuum Documentation
  • OpenAPI Specification
  • Zuplo OpenAPI Extensions

Quick Links

View on GitHubDocumentation

Run Locally

Clone and run this example:

npx create-zuplo-api --example api-linting

On This Page

Related Examples

Explore more examples in this category

HTTP Deprecation

API Governance

Signal deprecated endpoints and sunset dates to API clients with standards-based Deprecation, Sunset, and Link headers.

View Example
Check all of our Examples

Scale your APIs with
confidence.

Start for free or book a demo with our team.
Book a demoStart for Free
SOC 2 TYPE 2High Performer Spring 2025Momentum Leader Spring 2025Best Estimated ROI Spring 2025Easiest To Use Spring 2025Fastest Implementation Spring 2025

Get Updates From Zuplo

Zuplo logo
© 2026 zuplo. All rights reserved.
Products & Features
API ManagementAI GatewayMCP ServersMCP GatewayDeveloper PortalRate LimitingOpenAPI NativeGitOpsProgrammableAPI Key ManagementMulti-cloudAPI GovernanceMonetizationSelf-Serve DevX
Developers
DocumentationBlogLearning CenterCommunityChangelogIntegrations
Product
PricingSupportSign InCustomer Stories
Company
About UsMedia KitCareersStatusTrust & Compliance
Privacy PolicySecurity PoliciesTerms of ServiceTrust & Compliance
Docs
Pricing
Sign Up
Login
ContactBook a demoFAQ
Zuplo logo
DocsPricingSign Up
Login