Skip to content
OpenAPI config

backend.openapi is the one block whose options are mandatory. For how it sits alongside the rest of the folder config, see the configuration reference.


Required Options ​

outfile - Path where the spec is written, relative to your kosmo.config.ts.

openapi - OpenAPI version. Use "3.1.0" or any 3.1.x version.

info - API metadata:

  • title (required) - Name of your API
  • version (required) - API version, use semantic versioning

servers - Array of server objects:

  • url (required) - URL the API is served from, including the backend.base prefix. Paths in the spec are relative to this, so getting it wrong is the usual cause of a spec whose endpoints 404 - see Server URLs and Route Paths
  • description (optional) - Human-readable label

Optional Info Properties ​

summary - One-line summary

description - Detailed description, supports markdown

termsOfService - URL to terms of service

contact - name, url, email

license - name (required), identifier (SPDX), url

Complete Example ​

typescript
const openapiConfig = {
  outfile: "openapi.json",
  openapi: "3.1.0",
  info: {
    title: "My SaaS API",
    version: "2.1.0",
    summary: "RESTful API for My SaaS Platform",
    description: `
# API Documentation
This API provides access to all platform features including
user management, billing, and analytics.`,
    termsOfService: "https://myapp.com/terms",
    contact: {
      name: "API Support",
      url: "https://myapp.com/support",
      email: "api@myapp.com",
    },
    license: {
      name: "Apache 2.0",
      url: "https://www.apache.org/licenses/LICENSE-2.0.html",
    },
  },
  // this folder has backend.base "/api", so the dev server carries that prefix -
  // in production the API is deployed at the root of its own host and carries none.
  servers: [
    { url: "http://localhost:4556/api", description: "Development server" },
    { url: "https://staging-api.myapp.com", description: "Staging environment" },
    { url: "https://api.myapp.com", description: "Production server" },
  ],
};

Server URLs and Route Paths ​

Paths in the spec are route names, exactly as they appear under api/. A route at api/users/[id]/index.ts becomes /users/{id}, and the index route becomes / - neither carries the folder's backend.base.

That is deliberate, not an omission. In OpenAPI, paths are relative to servers, and the prefix an API answers on is a deployment decision rather than a property of the route.

The same backend may sit behind /api in development, at the root of a dedicated host in production, and under /v2/api behind a gateway - so the prefix belongs to the server entry, and the paths stay the same in all three.

This is why servers is mandatory: it is the only place the prefix is recorded. Give each entry the full prefix, origin plus backend.base:

ts
// folder with backend.base "/api"
servers: [
  { url: "http://localhost:4556/api", description: "Development server" },
  // deployed at the root of its own host - no prefix to add
  { url: "https://api.myapp.com", description: "Production server" },
];
ts
// folder with backend.base "/admin/api"
servers: [
  { url: "http://localhost:4556/admin/api", description: "Development server" },
  { url: "https://myapp.com/admin/api", description: "Production server" },
];

A client built from the spec resolves /users/{id} against whichever server it is pointed at, requesting http://localhost:4556/api/users/42 in development and https://api.myapp.com/users/42 in production - one spec, no per-environment rebuilds.

TIP

If Try it out in Swagger UI returns 404, check the server URL first. A missing backend.base prefix is the usual cause.

Released under the MIT License.