Update portal
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 and revokes the live ones. Re-enabling does not restore them.
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.
Authorizations
Unkey uses bearer tokens for authentication. Public integrations use root keys, while the dashboard proxy uses short-lived JWTs. To authenticate, include the token in the Authorization header of each request:
Root keys have specific permissions attached to them, controlling what operations they can perform. Legacy permissions use tuple strings like api.*.create_key; resource permissions use Unkey Resource Names plus actions, like unkey:v1:ws_123:keyspaces/*#create_key.
Security best practices:
- Keep root keys secure and never expose them in client-side code
- Use different root keys for different environments
- Rotate keys periodically, especially after team member departures
- Create keys with minimal necessary permissions following least privilege principle
- Monitor key usage with audit logs.
Body
Identifies a resource by either its unique ID or its slug. Accepts a prefixed ID (such as 'proj_' or 'app_') or a slug.
3 - 255^[a-zA-Z0-9_-]+$"proj_1234abcd"
New handle for this portal. Omit to leave unchanged.
3 - 64^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"acme-portal"
New human-readable name shown to your end users. Omit to leave unchanged.
1 - 64^\S(.*\S)?$"Acme"
Re-point the portal at a different keyspace. Omit to leave the resource it serves alone.
Re-pointing revokes the portal's live sessions, because a session carries the keyspace scope it was minted with and would otherwise keep reaching the resource the portal no longer serves.
The new keyspace must belong to the same project as the portal's current resource. A portal cannot move between projects, because its permissions are addressed under the project it belongs to. Re-pointing across projects returns 412; create a portal in the target project instead.
1 - 255^[a-zA-Z0-9_-]+$"ks_1234abcd"
Re-point the portal at a different app. Omit to leave the resource it serves alone.
Re-pointing revokes the portal's live sessions, for the same reason as
keyspaceId.
The same project restriction applies, and it is easy to hit when switching between an app and a keyspace: keyspaces are created in the workspace's default project, while an app belongs to the project you created it in.
1 - 255^[a-zA-Z0-9_-]+$"app_1234abcd"
Whether new sessions can be minted. Omit to leave unchanged.
Disabling also revokes the portal's live sessions. Re-enabling does not restore them.
false
Absolute https:// URL of the portal logo. Omit to leave unchanged, or set
null to remove the logo.
1 - 500^https://"https://cdn.example.com/logo.svg"
Six-digit hex colour for primary actions. Omit to leave unchanged, or set null to fall back to default styling.
^#[0-9a-fA-F]{6}$"#6366f1"
Response
The portal as it now stands.
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.
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.