---
title: "Update portal"
method: POST
path: "/v2/portal.updatePortal"
tags: ["portal"]
---

# Update portal

`POST /v2/portal.updatePortal`

Change a portal's slug, display name, the resource it serves, its enabled
state, or its branding.

Unreleased and subject to change without notice.

Only the fields you send change. Omitting a field leaves it as it is, and for
branding, sending null clears it. Send at most one of `keyspaceId` or `appId`.

Two changes affect your end users immediately:
- Re-pointing at a different resource revokes the portal's live sessions,
  because a session carries the scope it was minted with.
- Disabling stops new sessions but leaves live ones running until they expire.

**Required Permissions**

Your root key must have one of:
- `portal.*.update_portal` (to update any portal in the workspace)
- `portal.<portal_id>.update_portal` (to update a specific portal)

Without the permission this returns **404**, not 403.

## Request body

- V2PortalUpdatePortalRequestBody
  - `portal` string, required — Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
  - `slug` string — New handle for this portal. Omit to leave unchanged.
  - `displayName` string — New human-readable name shown to your end users. Omit to leave unchanged.
  - `keyspaceId` string — The id of the keyspace this portal serves keys for. Must belong to your workspace. A portal serves exactly one resource, so `keyspaceId` and `appId` are mutually exclusive.
  - `appId` string — The id of the app this portal serves keys for. Must belong to your workspace. A portal serves exactly one resource, so `appId` and `keyspaceId` are mutually exclusive.
  - `enabled` boolean — Whether new sessions can be minted. Omit to leave unchanged. Disabling does not end sessions that are already live.
  - `logoUrl` string, uri, nullable — Absolute `https://` URL of the portal logo. Omit to leave unchanged, or set null to remove the logo.
  - `primaryColor` string, nullable — Six-digit hex colour for primary actions. Omit to leave unchanged, or set null to fall back to default styling.

## Response `200`

The portal as it now stands.

- V2PortalUpdatePortalResponseBody
  - `meta` Meta, required — Metadata object included in every API response. This provides context about the request and is essential for debugging, audit trails, and support inquiries. The `requestId` is particularly important when troubleshooting issues with the Unkey support team.
    - `requestId` string, required — A unique id for this request. Always include this ID when contacting support about a specific API request. This identifier allows Unkey's support team to trace the exact request through logs and diagnostic systems to provide faster assistance.
  - `data` Portal, required — A portal you expose to your end users so they can manage their own keys. Exactly one of `keyspaceId` or `appId` is present, naming the single resource the portal serves. Neither is in the required list because which one appears depends on the portal, so a reader checks for the one it cares about.
    - `id` string, required — The unique identifier of the portal, generated by Unkey.
    - `slug` string, required — URL-safe handle for this portal, unique within your workspace.
    - `displayName` string, required — Human-readable name your end users see in the portal header and page titles. Unlike `slug` it is not part of any URL, so it can be changed freely.
    - `enabled` boolean, required — Whether new sessions can be minted for this portal. Disabling a portal stops `portal.createSession` from minting new sessions. It does not end sessions that are already live.
    - `keyspaceId` string — The id of the keyspace this portal serves keys for. Must belong to your workspace. A portal serves exactly one resource, so `keyspaceId` and `appId` are mutually exclusive.
    - `appId` string — The id of the app this portal serves keys for. Must belong to your workspace. A portal serves exactly one resource, so `appId` and `keyspaceId` are mutually exclusive.
    - `branding` PortalBranding — How the portal looks to your end users. Both fields are optional; a portal with neither set renders with default styling.
      - `logoUrl` string, uri — Absolute `https://` URL of the logo shown in the portal header. Loaded by your end users' browsers, so the host you name receives their IP and user agent on every page view.
      - `primaryColor` string — Six-digit hex colour used for primary actions and accents in the portal.
    - `createdAt` integer, required — Unix timestamp in milliseconds when the portal was created.
    - `updatedAt` integer — Unix timestamp in milliseconds when the portal was last changed. Omitted if it has never been changed since creation.

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `404` — No such portal, the named app or keyspace is not in your workspace, or your root key may not update it.
- `409` — The new slug is taken in your workspace, or the named app or keyspace already backs another portal.
- `429` — Too Many Requests
- `500` — Internal server error

## Changes

- **2026-08-25** `4b9df35712fd` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/unkeyed/apis/unkey-api/changes/v2/portal.updatePortal/post.md)

---

[API](https://skmtc.dev/unkeyed/apis/unkey-api.md) · [All operations](https://skmtc.dev/unkeyed/apis/unkey-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/unkeyed/unkey-api/revisions/e88236776ad4/schema)
