OpenAPI Validator & Converter API
Validate OpenAPI 3.0, 3.1, 3.2 and Swagger 2.0 against the official schemas, lint common mistakes, list endpoints, YAML ↔ JSON, upgrade Swagger 2 to OAS 3.
Send an API definition as spec (YAML or JSON text, or a JSON object), as a text body, or give its url. With action=validate (default) the document is checked against the official JSON Schema of its version published by the OpenAPI Initiative (Swagger 2.0, OpenAPI 3.0, 3.1 and 3.2, refreshed weekly) and errors are reduced to the useful ones: for oneOf alternatives only the variant you most likely meant is reported, with the JSON pointer of each problem.
A built-in linter adds what the schema cannot see: $ref that do not resolve, duplicate operationId, path parameters missing from parameters or not in the template, path parameters without required: true, equivalent paths (/a/{id} vs /a/{name}), undefined security schemes, operations without a 2xx response, GET with a request body, server URLs ending with a slash, unused components, and missing descriptions, tags, contact or licence (as info). stats counts paths, operations by method, schemas and servers.
action=endpoints lists every operation (method, path, operationId, summary, tags, parameters, request body content types, response codes, security); action=convert turns YAML into JSON and back (to); action=upgrade converts Swagger 2.0 into OpenAPI 3.0.3 (servers from host / basePath / schemes, requestBody from body and formData parameters, components, security flows, $ref rewriting, x-nullable) and validates the result. External $ref files are not fetched. Up to 10 MB.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
spec | body | string | no | The OpenAPI / Swagger document: YAML or JSON text, or a JSON object. Or a raw text body. | |
url | body|query | string | no | Public URL of the document, instead of spec. | |
action | body|query | string | no | validate | validate (schema + lint + stats), endpoints, convert (YAML ↔ JSON) or upgrade (Swagger 2.0 → OpenAPI 3.0.3). |
to | body|query | string | no | json or yaml for convert / upgrade (default: the other format for convert, the same for upgrade). | |
lint | body|query | boolean | no | true | false skips the lint rules. |
Example
curl -X POST "https://apibox.io.vn/v1/openapi-tools" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"spec":"openapi: 3.0.3\ninfo:\n title: Shop API\n version: 1.0.0\npaths:\n /orders/{id}:\n get:\n summary: Get an order\n responses:\n '\''200'\'':\n description: The order\n"}'const res = await fetch('https://apibox.io.vn/v1/openapi-tools', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"spec": "openapi: 3.0.3\ninfo:\n title: Shop API\n version: 1.0.0\npaths:\n /orders/{id}:\n get:\n summary: Get an order\n responses:\n '200':\n description: The order\n"
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://apibox.io.vn/v1/openapi-tools",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"spec": "openapi: 3.0.3\ninfo:\n title: Shop API\n version: 1.0.0\npaths:\n /orders/{id}:\n get:\n summary: Get an order\n responses:\n '200':\n description: The order\n"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/openapi-tools');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => '{"spec":"openapi: 3.0.3\\ninfo:\\n title: Shop API\\n version: 1.0.0\\npaths:\\n /orders/{id}:\\n get:\\n summary: Get an order\\n responses:\\n \'200\':\\n description: The order\\n"}',
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"openapi_version": "3.0.3",
"format": "yaml",
"title": "Shop API",
"api_version": "1.0.0",
"valid": false,
"schema_valid": true,
"errors": [],
"lint": {
"errors": 1,
"warnings": 2,
"infos": 4,
"issues": [
{
"rule": "servers-defined",
"severity": "warning",
"path": "/servers",
"message": "No servers: clients will use the document location as base URL"
},
{
"rule": "operation-operationId",
"severity": "warning",
"path": "/paths/~1orders~1{id}/get",
"message": "GET /orders/{id} has no operationId"
},
{
"rule": "path-params-defined",
"severity": "error",
"path": "/paths/~1orders~1{id}/get",
"message": "Path parameter {id} of GET /orders/{id} is not defined in parameters"
},
"…"
]
},
"stats": {
"paths": 1,
"operations": 1,
"by_method": {
"GET": 1
},
"tags": [],
"schemas": 0,
"security_schemes": [],
"servers": [],
"deprecated_operations": 0
},
"schema_used": "https://spec.openapis.org/oas/3.0/schema/2024-10-18"
}
Use cases
- Check an OpenAPI file in CI before publishing documentation or generating SDKs
- Find broken $ref and duplicate operationId in a large specification
- Migrate a Swagger 2.0 definition to OpenAPI 3
- List all endpoints of a third-party API from its openapi.json URL
FAQ
Which versions are supported?
Swagger 2.0 and OpenAPI 3.0.x, 3.1.x and 3.2.x, each with its official JSON Schema from spec.openapis.org.
Are Schema Objects validated in 3.1?
The 3.1 / 3.2 schemas check the document structure; schemas inside it are checked for structure by the lint rules and $ref resolution, not against the full JSON Schema meta-schema.
Does it follow external $ref?
No. References to other files or URLs are listed as info and not fetched; local references (#/...) are all resolved and checked.
Related APIs
UUID Generator
Generate up to 1,000 UUID v4, time-ordered UUID v7, ULID, Nano ID or random hex IDs per request. Secure randomness, optional uppercase.
⏱Cron Expression Parser
Validate a cron expression and get its next run times in any timezone, with a plain-English description. Supports 5, 6 and 7-field cron syntax.
🕒Time & Timezone Converter
Get the current time in any timezone, convert between timezones and Unix timestamps (seconds or ms), with UTC offset and weekday for up to 30 zones.