Catalog / ToolMint OpenAPI Normalize
ToolMint OpenAPI Normalize
Normalize OpenAPI 3 / Swagger 2 specs from URL or posted text into a flat operations pack. SSRF-guarded https fetch.
Routes and prices
| Route | Price | What it does | Parameters (* required) |
|---|---|---|---|
GET /normalize | $0.02 | Normalize OpenAPI/Swagger from URL | url*, tag, includeDeprecated |
POST /normalize | $0.02 | Normalize from posted URL or text | — |
Free routes: /, /health, /openapi.json, /.well-known/x402.
Try it
Call it with no payment. You get 402 and a base64 PAYMENT-REQUIRED header. Decoded, it looks like this (captured from the live tool on 2026-10-31 17:32 UTC):
curl -i "https://toolmint-openapi-normalize.toolmint.workers.dev/normalize?url=https://petstore3.swagger.io/api/v3/openapi.json"
{
"x402Version": 2,
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"amount": "20000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xfbF7413bcB3a604936775C96FDbe0b0C9c9E37F5",
"maxTimeoutSeconds": 300,
"extra": {
"name": "USD Coin",
"version": "2"
}
}
],
"resource": {
"url": "https://toolmint-openapi-normalize.toolmint.workers.dev/normalize?url=https://petstore3.swagger.io/api/v3/openapi.json",
"description": "Normalize OpenAPI/Swagger from URL (url, tag, includeDeprecated)",
"mimeType": "application/json",
"serviceName": "ToolMint OpenAPI Norm",
"tags": [
"openapi",
"swagger",
"normalize",
"api",
"toolmint"
],
"iconUrl": "https://toolmint.toolmint.workers.dev/icon.png"
}
}
amount is in USDC base units (6 decimals): 20000 = $0.02. Repeat the same request with a PAYMENT-SIGNATURE header from any x402 client.
What question it answers
"What can I call on this API, and how?" without reading a 500 KB spec file.
When to use it
- An agent has a spec URL and needs a compact operations list.
- You want one shape for both OpenAPI 3 and Swagger 2 specs.
- You want to filter by tag, or include deprecated operations.
When not to use it
- For request and response body schemas. Those are not returned; you get content types, parameter names and types, and response status codes.
- For specs behind login, on private networks, or not on https.
- To validate a spec. It only checks that the root looks like an OpenAPI or Swagger document.
- Specs over 2 MB when posted as text (413), or over 5 MB when fetched by URL (502).
Example
curl -i "https://toolmint-openapi-normalize.toolmint.workers.dev/normalize?url=https%3A%2F%2Fpetstore.swagger.io%2Fv2%2Fswagger.json"
# 402 + PAYMENT-REQUIRED. Pay with an x402 client, repeat with PAYMENT-SIGNATURE.
Response after payment (trimmed; a small demo spec, shape from the Worker code):
{
"tool": "openapi-normalize",
"version": "0.2.0",
"sourceUrl": "https://example.com/openapi.json",
"openapi": "3.0.0",
"title": "Demo API",
"apiVersion": "1.0.0",
"servers": [],
"globalSecurity": [],
"securitySchemes": {},
"schemaCount": 0,
"schemaNames": [],
"operationCount": 3,
"byTag": { "pets": 2 },
"operations": [
{
"method": "GET",
"path": "/pets/{id}",
"operationId": "getPet",
"tags": [],
"parameters": [{ "name": "id", "in": "path", "required": true, "schemaType": "string" }],
"responseCodes": ["200"],
"deprecated": false
}
],
"cached": false
}
Swagger 2 specs return swagger instead of openapi. requestBodyContentTypes, summary and security appear when the spec has them. byTag counts tagged operations only.
Data source and licence
Whatever public spec you point it at, or text you send. The tool returns structure only (paths, names, short summaries), not the spec file. You are responsible for having the right to read the spec you submit.
Freshness and limits
- URL results are cached 6 hours in memory per URL, tag and flag on one server instance.
cachedshows a cache hit. Posted text is not cached. There is nofetchedAt. - Only local
#/...references are resolved, to 5 levels, for path items, operations and parameters. A parameter type may come back as the$refstring. - All operations are returned, so large specs give large responses.
- If it runs out, paid calls fail and are not charged.
Errors are not charged
Payment settles only on a successful answer. Any response with status 400 or higher (bad input, not found, upstream failure) is never settled.