Zuplo
API Developer Portal

One Portal Isn't Enough: How to Run Multiple Developer Portals for Different API Audiences

Nate TottenNate Totten
May 11, 2026
9 min read

Learn when a single developer portal becomes a bottleneck and how to architect multi-portal strategies for partners, internal teams, and public developers.

Your first developer portal is a win. Developers find your API docs, grab a key, and start building. But as your API program grows — more audiences, more business units, more compliance requirements — that single portal starts to buckle under competing demands.

Partner teams want a private portal with OIDC-based authentication and enterprise-grade SLAs. Your public developer community wants a self-service portal with API key signup and sandbox access. Internal teams want a portal stripped of marketing copy that just shows them the endpoints. And your compliance team wants to make sure the regulated-market portal doesn’t expose endpoints it shouldn’t.

A single portal can’t serve all of these audiences without becoming a confusing mess of conditional content, auth workarounds, and one-size-fits-none navigation. The answer is multiple developer portals — each tailored to a specific audience — powered by the same underlying API products.

Why a single portal stops scaling

The friction usually starts in one of four places:

Authentication conflicts. Your public portal uses API keys for self-service onboarding, but your partner portal needs OAuth/OIDC integration with their identity provider. Bolting both auth flows into one portal creates a confusing sign-up experience and messy conditional logic in your frontend.

Branding and audience mismatch. An enterprise partner expects a co-branded portal that matches their visual identity. Your public developer community expects your brand. Trying to theme-switch inside a single portal is fragile and hard to maintain.

Content sprawl. Different audiences need different subsets of your API surface. Internal teams need every endpoint, including admin routes. Public developers should only see the consumer-facing API. Compliance-sensitive portals (Open Banking, healthcare) may need to exclude certain endpoints entirely. Managing all of this with feature flags or role-based content hiding adds complexity that compounds over time.

Regulatory and compliance boundaries. Some industries require strict separation of documentation environments — EU GDPR data residency, PSD2 Open Banking, HIPAA in healthcare. A single portal can’t easily satisfy auditors who want to see clear environment boundaries.

Common multi-portal patterns

Not every organization needs five portals. But most API programs that reach moderate scale end up needing at least two. Here are the patterns that come up most often:

Internal vs. external

The most common split. Your internal portal documents every endpoint, includes admin APIs, and links to internal runbooks. Your external portal only exposes the consumer-facing API surface with polished onboarding flows. Internal developers get faster access to the information they need, and external developers aren’t overwhelmed by endpoints they can’t use.

Partner vs. public developer

Partner portals serve a smaller, higher-value audience. They often require OAuth/OIDC authentication tied to the partner’s identity provider, expose premium API tiers or private endpoints, and include integration guides specific to that partnership. Public developer portals prioritize self-service: instant API key signup, sandbox environments, and broad documentation coverage.

Brand-segmented portals

Companies that sell API access under multiple brands or product lines benefit from separate portals per brand. Each portal gets its own logo, color scheme, domain, and content — even though the underlying API products are the same. This is especially common in fintech, SaaS platforms, and companies with white-labeled API offerings.

Environment-separated (sandbox vs. production)

Separating developer onboarding from production access reduces risk. A sandbox portal lets developers experiment with test data and relaxed rate limits. The production portal requires stricter authentication, enforces compliance controls, and points to live infrastructure. This pattern is common in financial services and payments APIs.

Per-business-unit

Large organizations with multiple API teams often deploy portals per business unit — one for the payments team, one for logistics, one for identity. Each team owns their portal’s content, branding, and release cadence without stepping on each other.

How to architect multi-portal deployments

The key architectural principle is straightforward: your API products are centralized, your portals are decentralized. Each portal is a frontend that consumes the same underlying OpenAPI specifications and connects to the same API gateway — but presents a tailored experience to its audience.

Here’s what that looks like in practice:

Shared API source, separate portal frontends

Your OpenAPI specification is the single source of truth. Whether you have one portal or five, each one generates its API reference documentation from the same spec. This eliminates content drift — when you add a new endpoint or update a schema, every portal picks it up automatically.

With Zudoku, the open-source developer portal framework that powers Zuplo’s Developer Portal, each portal is a separate deployment with its own zudoku.config.tsx. All portals can reference the same OpenAPI files, and Zudoku supports configuring multiple APIs within a single portal — so you can choose whether a given portal shows all of your APIs or just a subset.

Per-portal authentication strategies

Different portals need different auth. Your public portal might use API key authentication with self-service key management through the Developer Portal. Your partner portal might use OpenID Connect JWT authentication tied to the partner’s identity provider.

The API gateway layer is where this works cleanly. In Zuplo, you can configure multiple authentication policies on the same route — so the same API endpoint can accept both an API key from a public developer and a JWT from a partner, validating whichever credential is present. Your backend code never needs to know which portal the request came from.

JSONjson
{
  "policies": [
    {
      "name": "api-key-auth",
      "policyType": "api-key-inbound",
      "handler": {
        "export": "ApiKeyInboundPolicy",
        "module": "$import(@zuplo/runtime)",
        "options": {
          "allowUnauthenticatedRequests": true
        }
      }
    },
    {
      "name": "jwt-auth",
      "policyType": "open-id-jwt-auth-inbound",
      "handler": {
        "export": "OpenIdJwtInboundPolicy",
        "module": "$import(@zuplo/runtime)",
        "options": {
          "allowUnauthenticatedRequests": true,
          "issuer": "$env(JWT_ISSUER)",
          "audience": "$env(JWT_AUDIENCE)",
          "jwkUrl": "$env(JWT_JWKS_URL)"
        }
      }
    },
    {
      "name": "require-auth",
      "policyType": "custom-code-inbound",
      "handler": {
        "export": "default",
        "module": "$import(./modules/require-auth)"
      }
    },
    {
      "name": "dual-auth",
      "policyType": "composite-inbound",
      "handler": {
        "export": "CompositeInboundPolicy",
        "module": "$import(@zuplo/runtime)",
        "options": {
          "policies": ["api-key-auth", "jwt-auth", "require-auth"]
        }
      }
    }
  ]
}

The require-auth guard is a short custom policy that rejects any request where neither authentication method succeeded:

TypeScripttypescript
// modules/require-auth.ts
import { HttpProblems, ZuploContext, ZuploRequest } from "@zuplo/runtime";

export default async function (request: ZuploRequest, context: ZuploContext) {
  if (!request.user?.sub) {
    return HttpProblems.unauthorized(request, context, {
      detail: "Authentication required.",
    });
  }
  return request;
}

With both allowUnauthenticatedRequests: true, each policy validates only its credential type and passes through otherwise. A composite inbound policy chains them together, and a short custom guard at the end rejects any request where neither method succeeded. The result: one API route, multiple auth methods, and a unified request.user object downstream regardless of how the caller authenticated.

Per-portal branding and customization

Each portal deployment gets its own theme. In Zudoku, branding is controlled through the site configuration — logos, titles, banners — and the theme system based on shadcn/ui and Tailwind CSS. You can set completely different colors, fonts, and layouts for each portal:

TypeScripttypescript
// Partner portal — zudoku.config.tsx
const config = {
  site: {
    title: "Acme Partner API Portal",
    logo: {
      src: {
        light: "/images/partner-logo-light.svg",
        dark: "/images/partner-logo-dark.svg",
      },
      alt: "Acme Partners",
    },
  },
  theme: {
    light: {
      primary: "#1a365d",
      accent: "#e2e8f0",
    },
    dark: {
      primary: "#63b3ed",
      accent: "#2d3748",
    },
  },
};

Because each portal is its own deployment, there’s no risk of theme leaking between audiences. Your partner sees their co-branded experience. Your public developers see yours.

API key management across portals

Zuplo’s API key system is organized around buckets, consumers, and keys. Each environment gets its own API key bucket by default, and enterprise customers can share buckets across projects. This means you can set up separate key issuance flows per portal while still validating all keys at the gateway layer.

Your public portal offers self-service key signup — developers create an account, get an API key, and start making calls. Your partner portal provisions keys through a managed process, potentially with higher rate limits and different metadata attached to the consumer record. Both sets of keys validate against the same gateway, but the consumer metadata lets you apply different rate limits, quotas, or access controls per audience.

Operational tradeoffs to watch for

Running multiple portals isn’t free of complexity. Here’s what to plan for:

Content duplication. If you copy Markdown pages between portals instead of sharing them, you’ll eventually have conflicting versions of the same guide. Solve this by keeping shared content in a common location — a Git submodule, a shared npm package, or a monorepo structure — and importing it into each portal’s build.

Portal sprawl. It’s tempting to spin up a new portal for every edge case. Resist this. Each portal is a deployment you need to maintain, update, and monitor. Start with the minimum number of portals that cleanly separate your audiences, and only add more when there’s a clear architectural reason.

Configuration drift. If each portal has its own zudoku.config.tsx and OpenAPI references, they can fall out of sync. Use CI/CD pipelines that build all portals from the same source branch, and run automated checks to verify that shared API specs haven’t diverged.

SEO considerations. Multiple portals covering the same API products can create duplicate content issues if they’re all publicly indexed. Use canonical URLs, noindex directives on internal portals, and distinct content strategies per portal to avoid competing with yourself in search results.

The open-source advantage

The economics of multi-portal architecture depend heavily on your tooling. If your API management platform charges per-portal licensing fees, every new portal is a budget conversation. If spinning up a new portal is just another deployment of an open-source framework, the only cost is your team’s time.

Zudoku is the open-source developer portal framework that powers Zuplo’s Developer Portal. Because it’s open source, you can deploy as many instances as you need — on any infrastructure — without per-portal fees. Each portal is a standalone project with its own configuration, theme, and content, but they all draw from the same OpenAPI specs and connect to the same Zuplo API gateway.

Here’s what a typical multi-portal setup looks like:

  • Public developer portal — deployed to developers.yourcompany.com, self-service API key signup, your brand colors, full API reference from your OpenAPI spec
  • Partner portal — deployed to partners.yourcompany.com, OIDC authentication, co-branded theme, curated subset of endpoints plus partner-specific integration guides
  • Internal portal — deployed to an internal domain, SSO authentication, every endpoint including admin APIs, links to internal monitoring and runbooks

All three portals are Zudoku deployments. All three read from the same OpenAPI spec files. All three connect to the same Zuplo gateway that handles auth validation, rate limiting, and routing. The difference is in what each portal shows and how it authenticates users.

Walkthrough: public and partner portals sharing the same API

Let’s walk through a concrete example. You have a Zuplo-managed API with both public and partner-tier endpoints. Here’s how you’d set up two portals.

Step 1: Define your OpenAPI specs. You might maintain one complete spec and use spec filtering to create subsets — or maintain separate specs for public and partner APIs. Either way, each spec is the source of truth for its portal.

Step 2: Create two Zudoku projects. Each project has its own zudoku.config.tsx that references the appropriate API spec:

TypeScripttypescript
// Public portal — zudoku.config.tsx
const config = {
  apis: [
    {
      type: "file",
      input: "./specs/public-api.json",
      path: "/api",
    },
  ],
  // ...public theme and navigation
};
TypeScripttypescript
// Partner portal — zudoku.config.tsx
const config = {
  apis: [
    {
      type: "file",
      input: "./specs/partner-api.json",
      path: "/api",
    },
  ],
  // ...partner theme and navigation
};

Step 3: Configure authentication per portal. In Zuplo, the same API routes serve both audiences. Set up a composite inbound policy that accepts API keys (from public developers) and JWTs (from partner integrations). Public developers self-serve their keys through the public portal. Partners authenticate through their identity provider.

Step 4: Deploy independently. Each portal deploys to its own domain through your standard CI/CD pipeline. Updates to the shared OpenAPI spec trigger rebuilds of both portals.

The result: two distinct developer experiences, one API backend, and no per-portal licensing costs.

Your portal architecture shouldn’t be gated by your vendor

The principle worth remembering is this: how many portals you run should be an architectural decision, not a licensing decision. If your API management platform makes it expensive or complex to add a second portal, you’ll delay the split long past the point where your developers are suffering from a cramped, one-size-fits-all experience.

With Zuplo and Zudoku, the question shifts from “can we afford another portal?” to “does this audience need its own portal?” That’s the right question to be asking.

If you’re already running a single developer portal and feeling the strain of competing audience needs, start by mapping your audiences to the patterns above. Identify the minimum number of portals that would cleanly separate your content, auth, and branding requirements.

Ready to get started? Zudoku is free and open source — you can scaffold a new portal project in minutes with npx create-zudoku-app@latest. Pair it with Zuplo’s API gateway for built-in API key management, multi-auth policies, and edge-deployed rate limiting, and you have a complete multi-portal architecture without the per-portal price tag.