---
title: "New from Zuplo - April 2026"
description: ""
canonicalUrl: "https://zuplo.com/changelog/2026/05/01/monthly-changelog"
pageType: "changelog"
date: "2026-05-01"
tags: "runtime, dev-portal, portal, cli, performance"
---
April 2026 ships the long-awaited **OpenAPI security schemes** support in the
Dev Portal, the most-requested feature from Dev Portal users, alongside a
**redesigned API Catalog** with full-text search and category filtering, and
**full custom domain lifecycle management** in the Zuplo CLI.

## Highlights

### OpenAPI Security Schemes in the Dev Portal

The Dev Portal now fully supports
[OpenAPI security schemes](https://spec.openapis.org/oas/v3.1.0#security-scheme-object).
APIs that define `securitySchemes` in their OpenAPI spec automatically display
security badges on operations, show scheme details in tooltips, and allow users
to authorize directly in the API playground.

**Key capabilities:**

- **All five scheme types supported**: API Key, HTTP (Bearer/Basic), OAuth2,
  OpenID Connect, and Mutual TLS
- **Interactive playground authorization**: Users can enter credentials,
  complete OAuth flows (Authorization Code with PKCE, Client Credentials), and
  test authenticated endpoints directly in the playground
- **Persistent credentials**: Credentials are stored per session so users don't
  need to re-authenticate on every page
- **Operation-level overrides**: Individual operations can override global
  security requirements, including marking endpoints as public

If your OpenAPI spec already defines `securitySchemes`, security badges appear
automatically on upgrade. To enable interactive OAuth flows in the playground,
configure an
[authentication provider](https://zuplo.com/docs/dev-portal/zudoku/configuration/authentication)
in your `zudoku.config.ts`. To disable security display entirely, set
`disableSecurity: true` in your API options.

See the
[OAuth Security Schemes documentation](https://zuplo.com/docs/dev-portal/zudoku/configuration/oauth-security-schemes)
for setup instructions.

![Security schemes in API playground](../public/media/changelog/2026-05/security-schemes-playground.png)

---

### Redesigned API Catalog

The Dev Portal's API Catalog has been completely redesigned with a modern card
layout, full-text search, and category filtering. For teams managing multiple
APIs, the catalog is now the best way to help developers discover and navigate
your API surface.

**Key improvements:**

- **Responsive card grid**: APIs are displayed in a 1/2/3-column card layout
  (mobile/tablet/desktop) with avatars, version badges, and operation counts
- **Full-text search**: Press `/` to search across API names, descriptions,
  categories, and tags
- **Category filter chips**: Toggle categories with filter chips, with overflow
  handling for large category sets
- **Status badges**: Mark APIs as Stable, Beta, or Alpha using the new
  `stability` field in your API configuration

```typescript
// zudoku.config.ts
const config: ZudokuConfig = {
  apis: [
    {
      type: "file",
      input: "./openapi.json",
      path: "/api",
      stability: "stable",
      categories: [{ label: "Core", tags: ["REST"] }],
    },
  ],
  catalogs: {
    path: "/catalog",
    label: "API Catalog",
  },
};
```

See the
[API Catalog documentation](https://zuplo.com/docs/dev-portal/zudoku/configuration/api-catalog)
for all configuration options.

![Redesigned API Catalog](../public/media/changelog/2026-05/api-catalog-redesign.png)

---

### Custom Domains CLI Commands

The Zuplo CLI now supports full custom domain lifecycle management. Create,
list, update, and delete custom domains directly from the command line. Perfect
for CI/CD automation and infrastructure-as-code workflows.

```bash
# Create a custom domain assigned to a deployment
zuplo custom-domain create \
  --hostname api.example.com \
  --deployment-name production-deployment

# List all custom domains
zuplo custom-domain list --output json

# Reassign a domain to a different deployment
zuplo custom-domain update \
  --hostname api.example.com \
  --deployment-name staging-deployment

# Delete a custom domain
zuplo custom-domain delete --hostname api.example.com
```

All commands support `--output json` for machine-readable output and `--account`
for multi-account workflows. Error messages now include the full server
response, so you can see exactly why a command failed.

See the
[Custom Domain CLI documentation](https://zuplo.com/docs/cli/custom-domain-create)
for all commands and options.

---

## Dev Portal Updates

### Custom JSX Components in OpenAPI Descriptions

Custom JSX components registered via `mdx.components` in `zudoku.config.ts` now
render inside OpenAPI description fields. Embed rich, interactive components
like callouts, warnings, or custom UI directly in your OpenAPI spec
descriptions: the same components that work in your `.mdx` documentation pages.

```typescript
// zudoku.config.ts
const config: ZudokuConfig = {
  mdx: {
    components: {
      SpaceWarning: ({ children }) => (
        <div className="warning-box">{children}</div>
      ),
    },
  },
};
```

Then use the component in your OpenAPI description:

```yaml
paths:
  /spaces:
    get:
      description: |
        Returns all available spaces.
        <SpaceWarning>Spaces are region-specific.</SpaceWarning>
```

**Limitation:** Only HTML-like JSX tags work. JavaScript expressions and imports
within description fields are not supported.

### Support for x-code-samples Extension

The Dev Portal now supports the
[`x-code-samples`](https://zuplo.com/docs/dev-portal/zudoku/openapi-extensions/x-code-samples)
OpenAPI extension. Add custom code snippets (cURL, Python, JavaScript, etc.) to
individual API operations, and they replace the auto-generated examples in the
sidecar panel. The language selector adapts automatically to show only the
languages you've defined.

```yaml
paths:
  /users:
    get:
      x-code-samples:
        - lang: curl
          label: cURL
          source: |
            curl -X GET https://api.example.com/users \
              -H "Authorization: Bearer $TOKEN"
        - lang: python
          label: Python
          source: |
            import requests
            response = requests.get(
              "https://api.example.com/users",
              headers={"Authorization": f"Bearer {token}"},
            )
```

Operations without custom samples continue to show auto-generated snippets.

### Linked Schema References in Property Lists

Properties that reference a named component schema now render the schema name
(e.g., `Address`, `Package[]`) as a clickable link instead of showing a generic
`object` type label. Click the link to jump directly to the schema definition.
Response and request bodies that resolve to a named schema also display the root
schema name at the top of the properties panel. This makes complex API schemas
much easier to explore, especially for APIs with deeply nested object
hierarchies.

Also released this month:

- **Vite 8 with Rolldown**: Dev Portal builds now run on Vite 8 with the new
  Rust-powered Rolldown bundler. Client and SSR builds run in parallel for
  significantly faster builds. Minimum Node.js raised from 22.7 to 22.12 for
  Node 22 users; default browser targets updated (Chrome 111+, Firefox 114+,
  Safari 16.4+)
- **Customizable 404 Page**: Provide a custom React component for the 404 page
  via `site.notFoundPage` in your Zudoku configuration
- **Robots Metadata Configuration**: Control search engine indexing via the new
  `metadata.robots` option (e.g., `"noindex, nofollow"` for staging)
- **MCP Server Security Schemes**: MCP server configurations now automatically
  include authentication headers when the underlying API defines security
  requirements; OpenAI Codex added as a supported MCP client
- **Custom OIDC Claims**: Users of custom OIDC providers (like Keycloak) can now
  access all custom claims through the user profile via an index signature on
  `UserProfile`
- **Accessibility improvements**: ARIA labels added to icon-only buttons,
  improved callout semantics, and fixed invisible dark-mode `<select>` text in
  Chrome and Edge

---

## Runtime Improvements

### Configurable Signing Algorithms for JwtServicePlugin

The
[JWT Service Plugin](https://zuplo.com/docs/programmable-api/jwt-service-plugin)
now supports configurable signing algorithms beyond the default EdDSA. If your
backend or downstream services require RSA or ECDSA keys, specify the algorithm
directly in the plugin options.

**Supported algorithms:** `EdDSA` (default), `RS256`, `RS384`, `RS512`, `PS256`,
`PS384`, `PS512`, `ES256`, `ES384`, `ES512`

```typescript
// modules/zuplo.runtime.ts
import { RuntimeExtensions, JwtServicePlugin } from "@zuplo/runtime";

export function runtimeInit(runtime: RuntimeExtensions) {
  const jwtService = new JwtServicePlugin({
    algorithm: "RS256",
  });
  runtime.addPlugin(jwtService);
}
```

Existing deployments are unaffected. The default remains `EdDSA`. A new exported
type `JwtServiceAlgorithm` is available for TypeScript users. The plugin's
OpenID configuration endpoint now correctly advertises the configured algorithm
in `id_token_signing_alg_values_supported`.

Also released this month:

- **Timer leak fixes**: Fixed `setTimeout` leaks in rate-limiting fetch abort
  controllers and JWKS fetch error paths. Both now use `try/catch/finally` to
  ensure timers are always cleaned up. Relevant for high-traffic deployments
  using rate-limiting or OpenID JWT authentication policies

---

## Portal & CLI Updates

### Inline JSON Editor for OpenAPI Operations

The Zuplo Portal's route designer now includes an inline JSON editor for
individual OpenAPI operations. A Designer/JSON toggle switches the operation
editor panel into a Monaco JSON editor, letting you edit the raw JSON of any
operation without switching to the full file view. Parse errors are caught
immediately with inline error indicators, and a crosshair button navigates to
the corresponding line in the raw OpenAPI file.

This is especially useful for setting advanced OpenAPI properties not exposed in
the visual designer, or for developers who prefer a code-first workflow.

![Inline JSON editor for operations](../public/media/changelog/2026-05/inline-json-editor.png)

### Tag Management UI for OpenAPI Operations

The Zuplo Portal now includes a full tag management system for organizing API
operations. A new Routes/Tags tab switcher in the sidebar opens a tag management
panel where you can create, edit, rename, and delete tags globally. Each
operation editor includes a tag assignment popover for adding and removing tags
per operation.

Tags flow through to the Dev Portal for end-consumer navigation, making it easy
to categorize endpoints by domain, version, or audience directly from the portal
UI. No raw spec editing required.

![Tag management UI](../public/media/changelog/2026-05/tag-management-ui.png)

### CLI Ergonomics Improvements

Several improvements make the Zuplo CLI significantly more productive for
day-to-day use:

- **`zuplo link` remembers your project**: After running `zuplo link`, the
  account, project, and environment are saved locally. Subsequent commands
  automatically use the linked values instead of prompting you to select each
  time. In CI/CD (non-TTY) mode, linked values are used silently.
  ([docs](https://zuplo.com/docs/cli/link))
- **`zuplo info` command**: A new command that displays your current project
  context: project name, account, portal link, environment, and connected git
  repository, at a glance. ([docs](https://zuplo.com/docs/cli/info))
- **Create projects from the picker**: When any CLI command prompts for a
  project, you can now choose "Create a new project" right from the list. The
  default name is inferred from `package.json`.
- **`zuplo list --show-details`**: The list command now supports a
  `--show-details` (`-d`) flag to display project and deployment names alongside
  URLs, and `--output json` for scripting.
  ([docs](https://zuplo.com/docs/cli/list))
- **Improved error messages**: CLI error messages now include the server's
  response body, making it clear exactly what went wrong.

Also released this month:

- **Custom domain verification warnings**: The custom domains page now shows a
  red warning triangle next to hostnames with DNS or SSL issues, with the exact
  error message in a popover. Page redesigned with card-based layout showing
  environment labels, branch info, and Default/Alias badges
- **Monetization UI**: Payment failure indicators surface on subscriber list,
  customer detail, and subscription detail; phase duration and rate card
  cadences now support increments as short as 1 hour; meter selection dropdown
  shows both name and slug; Stripe payment provider config redesigned
- **Consumer filtering**: Search and filter API consumers by name or email in
  the Portal and via the [Zuplo Developer API](https://zuplo.com/docs/api)
- **CLI git-prefix fix**: Projects created via the CLI can now be connected to a
  private Git repository from the Portal (a stale `user:` prefix in the storage
  path hash blocked this previously)

---

## Documentation Updates

- [Certificate Pinning](https://zuplo.com/docs/articles/certificate-pinning):
  New guide explaining why TLS certificate pinning is discouraged on
  Zuplo-managed custom domains, with recommended alternatives
- [API Errors](https://zuplo.com/docs/concepts/api-errors): New concept document
  explaining Zuplo's default Problem Details (RFC 7807) error format and how to
  customize error responses
- [Custom API Identity Plugin](https://zuplo.com/docs/dev-portal/auth-provider-api-identities):
  New guide for building custom API identity plugins for the Dev Portal with
  OAuth JWT token examples
- [Private Networking](https://zuplo.com/docs/dedicated/networking): New
  cloud-specific private networking guides for AWS, Azure, and GCP managed
  dedicated deployments
- [Environment Variables](https://zuplo.com/docs/articles/environment-variables):
  Major expansion covering `$env()` interpolation, `${env.VAR_NAME}` syntax for
  URL handlers, and `ZUPLO_PUBLIC_` prefixes