---
title: "Upgrade project plugins"
method: POST
path: "/api/v1beta/plugins/upgrade"
tags: ["plugins"]
---

# Upgrade project plugins

`POST /api/v1beta/plugins/upgrade`

Re-resolve a project's lock entries and install newer content where available

## Request body

- union
  - object
  - PkgApiV1UpgradePluginsRequest — Request to re-resolve a project's lock entries and install newer content
    - `allow_ref_change` boolean — AllowRefChange permits resolvedReference changes during upgrade
    - `allow_signer_change` boolean — AllowSignerChange permits upgrading to an artifact signed by a different identity than the recorded one
    - `clients` string[] — Clients lists target client identifiers. Empty means every plugin-supporting client detected on this host.
    - `fail_on_changes` boolean — FailOnChanges exits with an error when any mutable source would upgrade
    - `names` string[] — Names restricts the upgrade to specific plugin names. Empty means every entry.
    - `preview` boolean — Preview reports what would change without installing (still fetches to compare digests)
    - `project_root` string — ProjectRoot is the project root path whose lock file should be upgraded

## Response `200`

OK

- GithubComStacklokToolhivePkgPluginsUpgradeResult
  - `outcomes` GithubComStacklokToolhivePkgSkillsUpgradeOutcome[] — Outcomes contains one entry per skill considered for upgrade.
    - `error` string — Error is a human-readable description of the failure, set only when Status is UpgradeStatusFailed.
    - `name` string — Name is the skill name.
    - `new_digest` string — NewDigest is the digest the source currently resolves to. Equal to OldDigest when Status is UpgradeStatusUpToDate.
    - `new_resolved_reference` string — NewResolvedReference is the new resolvedReference when it changed.
    - `new_signer_identity` string — NewSignerIdentity is the candidate's signer identity when it differs from the recorded one (empty when the candidate is unsigned).
    - `old_digest` string — OldDigest is the digest pinned in the lock file before this operation.
    - `reason` 'registry-unreachable' | 'digest-missing' | 'validation-rejected' | 'lock-write-failed' | 'signature-invalid' | 'signer-mismatch' | 'provenance-field-mismatch' | 'unsigned-rejected' | 'unknown' — Reason is a typed failure reason when Status is UpgradeStatusFailed.
    - `status` 'upgraded' | 'up-to-date' | 'not-upgradable' | 'ref-change-blocked' | 'signer-change-blocked' | 'failed' — Status is the outcome of the upgrade attempt.

## Other responses

- `400` — Bad Request
- `403` — Forbidden (feature not enabled)
- `404` — Not Found (a requested name is not in the lock file)
- `500` — Internal Server Error
- `501` — Not Implemented

## Changes

- **2026-08-27** `e9f942effcda` — 1 info
  - added the new optional request property `oneOf[#/components/schemas/pkg_api_v1.upgradePluginsRequest]/allow_signer_change`
- **2026-08-27** `5ba8236d7c1c` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/stacklok/apis/toolhive-api/changes/api/v1beta/plugins/upgrade/post.md)

---

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