Zuplo
OpenAPI Support

Your spec is the gateway

Routes, policies, request validation, the developer portal, and exported client SDKs all derive from one OpenAPI document. OpenAPI 3.0/3.1, YAML or JSON, with first-class overlays for environment-specific config — and edge-enforced request validation that rejects malformed traffic before it touches your origin.

OpenAPI · one spec, three artifacts
OpenAPI 3.1 · YAML or JSON

openapi.json

Single source of truth

Routes

Auto-derived

Validation

Edge-enforced

Dev portal

Auto-generated

Edge validation in action

invalid requests blocked before origin
POST/v1/orders 200 OK

{ "items": [{ "id": "abc", "qty": 2 }] }

policy: open-api-validation-inbound · spec: openapi.json
OpenAPI 3.0/3.1 · spec is config
Edge validation · 400 before origin
Auto-docs · dev portal
Why this matters

When the spec is just a doc, every artifact drifts

OpenAPI works when it's the source of truth — for routes, validation, docs, SDKs, and tests. The moment it becomes "the file we wrote for the SDK generator," the rest of your stack stops trusting it.

×

Spec, gateway, and docs disagree

The OpenAPI spec is for clients. The gateway config is for routing. The portal is hand-curated. Three definitions of "the API" — when one of them drifts, customers feel it.

×

Bad payloads reach your origin

Clients send malformed JSON, missing required fields, wrong types. The gateway forwards everything. Your service spends compute returning 400s the gateway should have caught.

×

Hand-edited routes file

Engineers maintain `routes.json` next to the OpenAPI spec, copy-pasting paths and praying nobody forgets. The next API change touches three files instead of one.

×

Vendor-locked spec extensions

Your gateway adds proprietary fields the rest of the OpenAPI ecosystem doesn't understand. Spectral lints fail, Speakeasy generators choke, the spec only works in the gateway's own portal.

What you get

One spec. Many artifacts. Always in sync.

One spec drives everything

Routes, request validation, the developer portal, and exported client SDKs all read from `routes.oas.json`. Update the spec once — every artifact stays in lockstep. No drift between docs and behavior.

Edge-enforced validation

The `request-validation-inbound` policy checks bodies, query params, path params, and headers against your schema before the request reaches your origin. Reject, log-only, or both — per-route. Bad payloads get a structured 400 with field-level errors.

Vendor-neutral by default

Any valid OpenAPI document is valid Zuplo config. `x-zuplo-*` extensions are optional. Export a clean spec via the `openApiSpecHandler` and feed Spectral, Speakeasy, RateMyOpenAPI, or any other OpenAPI-aware tool.

Vendor-neutral OpenAPI · enforced at the edge

Validate at the edge. Overlay per environment.

Attach `request-validation-inbound` to reject malformed payloads before they touch your origin. Use overlays in CI to produce environment-specific variants from one canonical spec.

JSONEdge validation policy
{
  "name": "open-api-validation-inbound",
  "policyType": "request-validation-inbound",
  "handler": {
    "export": "RequestValidationInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "validateBody": "reject-and-log",
      "validateQueryParameters": "reject-and-log",
      "validatePathParameters": "reject-and-log",
      "validateHeaders": "log-only"
    }
  }
}

# Reject response (HTTP 400):
# {
#   "type": ".../validation",
#   "title": "Request body is invalid",
#   "status": 400,
#   "errors": [{ "field": "items[0].id", "message": "is required" }]
# }
TerminalEnvironment overlay · CI
# package.json
"scripts": {
  "build:openapi:dev":
    "zuplo openapi overlay -i routes.oas.json \
      -o overlays/dev.yaml -O dist/dev.oas.json",
  "build:openapi:prod":
    "zuplo openapi overlay -i routes.oas.json \
      -o overlays/prod.yaml -O dist/prod.oas.json"
}

# overlays/prod.yaml
overlay: 1.0.0
actions:
  - target: $.paths.*.*.x-zuplo-route.policies.inbound
    update:
      - rate-limit-prod
      - audit-log-export

# CI deploys dist/prod.oas.json
# Both share the same canonical spec.
OpenAPI 3.0 / 3.1
YAML or JSON
Edge validation
OpenAPI overlays
Spec export endpoint
Auto-generated dev portal
What makes Zuplo different

OpenAPI as the contract, not as a side artifact

OpenAPI Overlays in CI

Run `npx zuplo openapi overlay --input … --overlay … --output …` to apply ordered actions via JSONPath. Inject `x-zuplo-route` into upstream specs you don't own. Produce dev/staging/prod variants from one canonical file. Watch mode for local iteration.

Spec drives the developer portal

Your OpenAPI doc drives a React-based developer portal — interactive playground, named examples, schema browser, multi-version support, custom MDX pages. Every spec change you'd make for documentation hygiene is a documentation upgrade automatically.

Spec export for client SDKs

Attach the `openApiSpecHandler` to a route and Zuplo serves a clean, vendor-neutral OpenAPI document — `x-zuplo-*` stripped, auth headers inferred from applied policies. Plug it into Speakeasy, OpenAPI Generator, or your team's preferred SDK pipeline.

MCP via the same spec

Mark an operation with `x-zuplo-route.mcp = { type: "tool" }` and the same spec that drives your routes and docs becomes the source of truth for your remote MCP server too. One artifact for human consumers, machine consumers, and AI consumers.

Real questions, real answers

What teams use this for

“Our team designs APIs in Stoplight. Can we ship the same spec to Zuplo?”

Yes. The Stoplight-authored spec is a valid Zuplo config as-is. Add `x-zuplo-route` extensions in an overlay file and run the overlay in CI. Stoplight stays the source of truth for design; Zuplo gets a runtime-ready spec without polluting the upstream repo.

“Our backend is rejecting bad payloads at runtime. Move that to the edge.”

Add the `request-validation-inbound` policy to the affected routes, set `validateBody: reject-and-log`, and the gateway returns 400 with field-level errors before the request hits your service. Origin compute drops, error rates clean up, real bugs become easier to spot in your logs.

“The team wants generated TypeScript clients for our internal services.”

Attach the `openApiSpecHandler` to `GET /openapi` and run Speakeasy or OpenAPI Generator against the URL. SDKs match what the gateway actually serves — including auth headers inferred from applied policies — without anyone hand-maintaining a separate client config.

“We need different rate limits in dev vs. prod, but one spec.”

Maintain `routes.oas.json` as the canonical spec. Build `dev.overlay.yaml` and `prod.overlay.yaml` with environment-specific `x-zuplo-route.policies` blocks. Wire `build:openapi:dev` and `build:openapi` into `package.json` and CI applies the right overlay per environment.

Frequently Asked Questions

Common questions about OpenAPI on Zuplo.

Stop maintaining three definitions of one API

Free Zuplo project, import your OpenAPI spec, and watch routes, validation, and the developer portal generate themselves.