| name | api-spec-validator |
| description | This skill should be used when the user asks to "validate API spec", "check OpenAPI spec", "lint OAS", "review API specification", "convert RAML to OAS", or mentions validating, checking, or reviewing OpenAPI/OAS/Swagger/RAML specifications against best practices. |
| metadata | {"version":"2.0.0","author":"Mariano de Achaval"} |
API Spec Validator
This skill validates OpenAPI Specification (OAS) files against a comprehensive set of rules designed to ensure API specifications are AI-agent-friendly and production-ready.
API Project structure.
Every api specification should be organized as an Anypoint API Project with the following structure:
├── api.yaml
├── README.md
├── docs/
├── exchange.json
Exchange.json needs to have the following shape:
{
"main": "api.yaml",
"name": "<name-of-the-api>",
"organizationId": "8bfc8bbf-5508-419e-aadc-77dfe18a8172",
"groupId": "f1e97bc6-315a-4490-82a7-23abe036327a.anypoint-platform",
"assetId": "<same-as-the-folder>",
"version": "<any-semver-version default 1.0.0>",
"apiVersion": "v1",
"classifier": "oas",
"dependencies": [],
"originalFormatVersion": "3.0"
}
When to Use This Skill
Use this skill when:
- Validating or reviewing OpenAPI/OAS/Swagger specifications
- Checking API specs for completeness and best practices
- Ensuring API specs are optimized for AI agent consumption
- Auditing API documentation quality
Validation Rules
Rule 1: OAS Format Required
All API specifications must be written in OpenAPI Specification (OAS) format in YAML. Supported versions:
Translation: All APIs should be written in OAS 3 or bigger and in YAML format.
Rule 2: API Title Must End with "API"
The info.title field must end with the word "API" to ensure consistent naming across the portal.
Valid: Secrets Manager API, Object Store API, API Manager API
Invalid: Tokenization, ObjectStore, ARM REST services, Exchange - XAPI Service
Rule 3: Semantic Versioning Required
The info.version field must use strict Semantic Versioning with three numeric components: MAJOR.MINOR.PATCH.
Valid: 1.0.0, 2.1.3, 0.7.0
Invalid: v1, V1, 1.0, 1, v1.0.0, v2
This ensures consistent version formatting across all API specifications, enabling reliable version comparison and tooling support.
Rule 4: Operation IDs Required
Every endpoint operation must have an operationId that is:
- Descriptive and specific: Clearly indicates what the operation does
- Avoids generic names: ❌
get_data, update, post_item, fetch
- Follows verb-noun pattern: ✅
calculateTaxRate, provisionCloudServer, getUserPreferences, cancelSubscription
Good examples:
calculateTaxRate - specific action + specific domain
provisionCloudServer - clear verb + clear resource
getUserPaymentHistory - specific action + specific data
Bad examples:
get_data - too generic
update - missing context
create - which resource?
fetch - fetch what?
Rule 5: Descriptions Required with Context
Every endpoint operation must have a description field. Apply special handling for:
Legacy Field Mapping
If a field name is cryptic or legacy (e.g., v1_status_code, legacy_tier, old_category), override its description with clear mapping:
description: "INTERNAL MAPPING: This represents the customer's loyalty tier. Map 'A' to Gold, 'B' to Silver, 'C' to Bronze."
Contextual Warnings
Add "WARNING" notes in descriptions for important operational considerations:
description: "WARNING: This endpoint is slow. Expect a 5-second delay. Do not retry before 10 seconds."
description: "WARNING: This endpoint is rate-limited to 10 requests per minute per user."
AI Aliases for Cryptic Paths
If the path is cryptic (e.g., POST /rpc/v2/action_4, GET /api/v1/proc/17), use the summary field to give it a human-readable "AI Alias":
summary: "Create Support Ticket"
description: "Creates a new support ticket in the system."
Legacy Error Response Handling
For legacy 400 Bad Request responses, add recovery instructions in the response description to help AI agents parse error bodies and retry correctly:
responses:
'400':
description: "Bad Request. RECOVERY INSTRUCTIONS: If the response contains 'ERR_04', the date format was wrong. Re-try using YYYY-MM-DD format. If 'ERR_12', the amount exceeded maximum limit - reduce amount to under $10,000."
content:
application/json:
schema:
type: object
properties:
errorCode:
type: string
enum: [ERR_04, ERR_12, ERR_15]
description: "Error code indicating the type of validation failure"
message:
type: string
description: "Human-readable error message"
examples:
dateFormatError:
summary: Date format error
value:
errorCode: "ERR_04"
message: "Invalid date format"
Pattern for recovery instructions:
- Start with "RECOVERY INSTRUCTIONS:" in the 400 response description
- Map each error code to specific corrective action
- Be explicit about what to change (format, value range, required fields, etc.)
- Prevent unnecessary retries by being specific about the fix needed
Rule 6: Examples Required
Every endpoint operation must have at least one example demonstrating:
- Request parameters (if applicable)
- Request body (if applicable)
- Successful response (200/201)
Use the examples field in request bodies and responses:
requestBody:
content:
application/json:
examples:
createUser:
summary: Create new user
value:
name: "John Doe"
email: "john@example.com"
Rule 7: Type Documentation Required
All schema properties must include a description field explaining:
- What the field represents
- Valid values or ranges
- Business logic or constraints
properties:
status:
type: string
description: "Current order status. Transitions from 'pending' → 'processing' → 'shipped' → 'delivered'."
Rule 8: Output Types Documentation Required
All response schemas must be fully documented with:
- Description for each property
- Data types clearly specified
- Nullable fields explicitly marked
Rule 9: No Naked Strings
If a field has a limited set of options, it must have an enum defined. Never use plain string type for constrained values.
Bad:
status:
type: string
description: "Order status (pending, shipped, or delivered)"
Good:
status:
type: string
enum: [pending, shipped, delivered]
description: "Current order status"
Rule 10: Required Fields Explicit
Always explicitly list required fields in the schema's required array to prevent AI agents from "guessing" optional parameters.
properties:
name:
type: string
email:
type: string
age:
type: integer
required:
- name
- email
Rule 11: API-Level Identity (info.description)
The info.description field is the first signal an AI agent uses for API-level discovery. When choosing among many APIs, this description determines whether the agent selects the right one.
Every API must have a non-empty info.description that explains the API's domain, capabilities, and intended use cases.
Bad:
info:
title: Core Services API Reference
version: 1.0.0
Good:
info:
title: Secrets Manager API
version: 1.0.0
description: >
Manages secrets, shared secrets, and TLS contexts for Anypoint Platform.
Provides operations to create, retrieve, update, and delete secrets
including symmetric keys, certificates, and keystores used by Mule
applications and API gateways.
Fix Instructions
When validation finds violations, use the following instructions to fix each rule. Fixes fall into two categories: mechanical (can be scripted) and semantic (require understanding the API's domain).
Fixing api-title-ends-with-api (mechanical + semantic)
- Open the API spec and find the
info.title field
- If it already ends with 'API', no change needed
- Otherwise, rename to a clear, descriptive title ending with 'API':
Tokenization → Tokenization API
ObjectStore → Object Store API
ARM REST services → ARM REST Services API
Exchange - XAPI Service → Exchange Experience API
Edge Security Policies → Anypoint Security Policies API
Core Services API Reference → Access Management API
- Avoid trailing suffixes like 'Service', 'Reference', 'xAPI', or version numbers before 'API'
- Use title case for the name
Fixing api-version-semver (mechanical)
- Open the API spec and find the
info.version field
- Convert the current value to
MAJOR.MINOR.PATCH format:
v1 or V1 or "1" → 1.0.0
v2 → 2.0.0
1.0 or "1.0" → 1.0.0
0.1 → 0.1.0
1.23 → 1.23.0
v1.0 → 1.0.0
v1.0.0 → 1.0.0 (strip the v prefix)
v2.1.3 → 2.1.3 (strip the v prefix)
- Remove any
v or V prefix — semver does not use letter prefixes
- Ensure exactly three dot-separated numeric components
Fixing api-info-description (semantic)
- Read the API spec to identify: the
info.title, all paths, and the main operations
- Determine the API's domain (e.g., security, deployment, monitoring, API management)
- Write a 2-3 sentence description that answers: What does this API manage? What are its key capabilities? Who or what consumes it?
- Add the
description field under info using YAML block scalar (>) for readability
- Avoid generic descriptions like "This API provides endpoints" — be specific about the domain
Fixing operation-id-camel-case (mechanical + semantic)
- If
operationId is missing: generate one from the HTTP method + path (e.g., GET /users/{id} → getUserById)
- If
operationId exists but is snake_case or generic: rename to descriptive camelCase
- Use the pattern:
verbNoun or verbNounQualifier (e.g., listEnvironments, createDeployment, getApplicationStatus)
- The helper script
scripts/add_operation_ids.py can generate initial IDs; scripts/improve_operation_ids.py can improve existing ones
Fixing operation-description (semantic)
- Read the operation's path, method, parameters, and request/response schemas
- Write a description that explains what the operation does, not just restating the path
- Include relevant business context: preconditions, side effects, related operations
- The helper script
scripts/add_descriptions.py can add placeholder descriptions that should then be reviewed
Fixing operation-examples (mechanical + semantic)
- For each operation missing examples, look at the response schema to understand the shape
- Create a realistic example that covers the main fields
- Add it under the response's
content.application/json.examples (or the appropriate media type)
- The helper script
scripts/add_examples.py can generate examples from schemas
- The helper script
scripts/fix_delete_head_examples.py handles DELETE/HEAD operations that may not need response body examples
Fixing input-types-described (semantic)
- For each parameter missing a description, examine its name, type, and where it's used
- Write a description that explains what the parameter controls and valid values
- For path parameters: explain what resource it identifies
- For query parameters: explain filtering/pagination behavior and defaults
Fixing output-response-description (semantic)
- For each response missing a description, examine the status code and response schema
- Write a description that explains what the response represents and when it's returned
- For error responses (4xx/5xx): include what triggers the error and how to resolve it
Fixing request-body-description (semantic)
- For each request body missing a description, examine the schema and the operation's purpose
- Write a description that explains what data the caller must provide and any constraints
Fixing output-types-described (semantic)
Same approach as output-response-description — ensure every response has a description explaining the returned data.
General Fix Workflow
When fixing violations across multiple APIs:
- Run Pass 2 validation on the target API
- Parse the JSON output to identify violations grouped by rule
- Fix violations one rule type at a time (batch similar fixes)
- Re-run Pass 2 to verify fixes — iterate until clean
- Move to the next API
Validation Process
Prerequisites
Install the Anypoint CLI tool and API project plugin:
npm install -g anypoint-cli-v4
anypoint-cli-v4 plugins:install anypoint-cli-api-project-plugin
Automated Validation
Validation should be performed in two passes to ensure both syntax correctness and AI-agent compliance:
Pass 1: Basic OAS Format Validation
First, validate that the OAS file is syntactically correct:
anypoint-cli-v4 api-project validate --json --location=./path/to/folder/with/oas
This validates:
- OpenAPI specification structure and syntax
- Valid YAML/JSON format
- Required OAS fields present
- Basic schema correctness
Important: Only proceed to Pass 2 if Pass 1 succeeds. Fix any syntax errors first.
Pass 2: Full Compliance Validation
After Pass 1 succeeds, validate against all AI-agent-friendly rules:
anypoint-cli-v4 api-project validate --json --location=./path/to/folder/with/oas --local-ruleset skills/api-spec-validator/scripts/ruleset.yaml
This validates:
- API title ends with 'API' (Rule 2)
- Semantic versioning in info.version (Rule 3)
- Descriptive operation IDs (Rule 4)
- Comprehensive descriptions with context (Rule 5)
- Examples in requests and responses (Rule 6)
- Type documentation for all properties (Rule 7)
- Output types fully documented (Rule 8)
- No naked strings - enums required (Rule 9)
- Required fields explicitly listed (Rule 10)
- API-level identity - info.description present (Rule 11)
The tool will:
- Parse the OAS file
- Check all validation rules
- Generate a detailed report with violations
- Exit with status code 0 (pass) or 1 (fail)
Complete Validation Workflow
The recommended workflow for validating an API specification:
- Check format: Ensure spec is OAS (not RAML) - convert if needed
- Pass 1 - Basic validation: Run
anypoint-cli-v4 api-project validate --json --location=./path
- Fix syntax errors: Address any errors from Pass 1 before continuing
- Pass 2 - Compliance validation: Run with
--local-ruleset skills/api-spec-validator/scripts/ruleset.yaml
- Review violations: Check the detailed report for rule violations
- Fix violations: Update spec to address each violation
- Re-run Pass 2: Verify all violations are resolved
Manual Review Checklist
When reviewing specs manually:
- Check if spec is in RAML format - if so, translate to OAS first
- Check each endpoint has
operationId, description, and examples
- Verify operation IDs are descriptive (not generic)
- Look for legacy field names requiring mapping explanations
- Identify slow/rate-limited endpoints needing warnings
- Check for cryptic paths needing AI aliases in
summary
- Check 400 responses for error codes - add recovery instructions
- Ensure all string fields with limited options use
enum
- Verify all schemas have explicit
required arrays
- Confirm all properties have meaningful descriptions
Running Validation with Claude
Claude will automatically run both validation passes when you ask:
"Validate my API spec at path/to/api-spec.yaml"
"Check this OpenAPI specification for AI-agent compliance"
"Review my OAS file at specs/my-api.yaml"
Claude will:
- Run Pass 1 (basic OAS validation)
- If Pass 1 succeeds, run Pass 2 (compliance validation)
- Provide a summary of violations and recommendations
Best Practices
Creating AI-Friendly Specs
When authoring or reviewing specs, optimize for AI agent consumption:
- Use OAS format: Convert RAML specs to OAS for compatibility
- Be explicit: Don't assume the AI knows implicit conventions
- Add context: Explain business rules, state transitions, constraints
- Warn proactively: Surface gotchas (rate limits, slow endpoints, deprecated fields)
- Map legacy fields: Translate internal codes to human-readable meanings
- Document error recovery: Add recovery instructions for 400 responses with error codes
- Use examples liberally: Show don't tell - examples are worth a thousand words
Common Issues to Fix
- Missing API description: Add
info.description explaining domain and capabilities
- RAML format: Convert RAML specs to OAS before validation
- Generic operation IDs: Replace
getData with getUserProfile
- Missing enums: Add enums for status codes, types, categories
- Undocumented fields: Add descriptions explaining purpose and usage
- Missing required arrays: Explicitly list which fields are mandatory
- Cryptic paths: Add summary aliases for
/rpc/ or /action/ style paths
- Undocumented 400 errors: Add recovery instructions for error codes
Output Format
When validating with anypoint-cli-v4, the tool provides a structured report:
Validating API specification...
✓ oas-only: Valid OpenAPI 3.0.2 format
✓ operation-examples: All operations have examples
⚠ Violations found:
1. operation-id-camel-case
- GET /users: operationId 'get_data' must be in camelCase
- Use descriptive names like 'getUserProfile' or 'calculateTaxRate'
2. no-naked-strings
- POST /orders (request): Property 'status' must have enum
- Avoid naked strings with no constraints
3. schema-required-block
- POST /users: Schema must explicitly list required fields
Validation completed with 3 violations
When summarizing results for users, organize by rule type and provide actionable fixes.
Related Skills
- api-schema-inferrer - Infer and generate schemas from examples in OAS specs
- api-doc-generator - Generate markdown documentation with curl examples from OAS specs
References
For detailed examples and guides:
references/example-good-spec.yaml - Example of a fully compliant spec with all best practices
references/example-violations.yaml - Common mistakes and how to fix them