Overview

A zone app is a separate Next.js application that provides a custom UI for a single agent. Zones are useful when the agent needs richer interaction than the platform's built-in input/output pages can provide — interactive review screens, complex multi-step inputs, custom dashboards.

How it works

  1. You build and deploy a Next.js app — your zone.
  2. A platform admin registers the zone's URL and a shared JWT secret against an agent.
  3. When a user navigates to /{orgSlug}/{agentSlug}/app/* on the platform, the platform mints a per-request JWT signed with the agent's zone_jwt_secret and rewrites the request to your zone.
  4. Your zone verifies the JWT (via createZoneMiddleware), reads the claims (via getSession), and calls platform endpoints on the user's behalf (via createZoneClient).

From the user's perspective, the zone feels like a native part of the platform — same URL, same auth, same navigation.

Request flow

Browser
  │  GET https://platform.tld/{orgSlug}/{agentSlug}/app[/...]
  ▼
Platform middleware
  • reads the platform session → { userId, orgId, agentId, role }
  • mints a per-request HS256 JWT with the agent's zone_jwt_secret
  • rewrites to the zone, forwarding the JWT as `x-zone-token`
  ▼
Zone middleware (createZoneMiddleware)
  • verifies `x-zone-token` against ZONE_JWT_SECRET
  • attaches decoded claims on `x-zone-claims`
  ▼
Zone page or server component
  • reads { claims, token } via getSession()
  ▼
Zone server action
  • forwards `token` as `Authorization: Bearer` to a platform zone endpoint
  ▼
Platform `/api/zones/agents/{agentId}/runs[…]`
  • re-verifies the token, cross-checks agentId in the URL against the claim,
    then executes the requested operation

The zone owns the entire /app/* subtree — /app, /app/runs, /app/settings, and any other routes it defines. The platform reserves only the /app/* prefix.

Static assets are served on the same origin: the browser fetches /assets/{orgSlug}/{agentSlug}/_next/* from the platform, which proxies to the zone. Same-origin asset delivery is load-bearing — see Deploy for why.

Deep-linking

Anything that needs to link to a specific run from outside the zone (HITL emails, Slack notifications, dashboards) uses:

/{orgSlug}/{agentSlug}/app?run=<runId>

Honour this query param in your landing page — the platform's HITL notification system routes zone-backed agents to /app?run=<runId> automatically, and dropping the convention breaks those links.

What lives in the zone vs. the platform

In the zoneIn the platform
Bespoke UI for this agentOrg / user / role management
Domain-specific workflowsRun history and observability
Run triggering via createZoneClientRun execution via the runtime
Custom layouts and componentsAuth, RBAC, billing, settings

The zone never holds long-lived platform credentials. Every request comes with a fresh JWT scoped to the agent and the user.

Prerequisites

  • Node 20+
  • A registered agent on the platform (a platform admin will share zone_jwt_secret and audience).
  • Familiarity with Next.js App Router.

Walkthrough

The remaining pages in this section walk through a complete zone build:

  1. Scaffold — Next.js project setup, basePath, assetPrefix, allowedOrigins.
  2. Auth — verifying the zone JWT.
  3. Session — reading claims in server components.
  4. Platform client — triggering runs, resolving credentials.
  5. Deploy — registering the zone and going live.