---
title: "Sync project skills from the lock file"
method: POST
path: "/api/v1beta/skills/sync"
tags: ["skills"]
---

# Sync project skills from the lock file

`POST /api/v1beta/skills/sync`

Restore a project's installed skills to match toolhive.lock.yaml

## Request body

- union
  - object
  - PkgApiV1SyncSkillsRequest — Request to restore a project's installed skills to match its lock file
    - `adopt` boolean — Adopt writes lock entries for existing unmanaged project-scope installs
    - `allow_unsigned` boolean — AllowUnsigned permits adopting skills whose signature state cannot be established, recording them as unsigned
    - `check` boolean — Check verifies on-disk content against the lock file without installing or writing anything
    - `clients` string[] — Clients lists target client identifiers. Empty means every skill-supporting client detected on this host.
    - `project_root` string — ProjectRoot is the project root path whose lock file should be synced
    - `prune` boolean — Prune removes project-scoped skills installed but not present in the lock file

## Response `200`

OK

- GithubComStacklokToolhivePkgSkillsSyncResult
  - `already_current` string[] — AlreadyCurrent lists skills that already matched the lock file.
  - `drifted` string[] — Drifted lists skills whose on-disk contentDigest differed from the lock file. Normally these are reinstalled to match it; when Check is set, nothing is written and this field reports the drift only.
  - `failed` GithubComStacklokToolhivePkgSkillsSyncFailure[] — Failed lists skills that could not be synced, with the reason for each. Drift alone is never reported here — see Drifted.
    - `error` string — Error is a human-readable description of the failure.
    - `name` string — Name is the skill name that failed.
    - `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.
  - `installed` string[] — Installed lists skills that were installed or reinstalled to match the lock file.
  - `missing` string[] — Missing lists lock entries with no corresponding install record at all — the fresh-clone state. Normally these are installed at their pinned reference; when Check is set, nothing is written and this field reports the gap only.
  - `never_managed` string[] — NeverManaged lists project-scoped skills never recorded as lock-managed.
  - `pruned` string[] — Pruned lists removed-from-lock skills that were uninstalled because Prune was set.
  - `removed_from_lock` string[] — RemovedFromLock lists previously managed skills absent from the lock file.

## Other responses

- `400` — Bad Request
- `403` — Forbidden (feature not enabled)
- `500` — Internal Server Error
- `501` — Not Implemented

## Changes

> 49 revisions in range; 6 could not be searched.

- **2026-07-29** `3db2b10a01f6` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/stacklok/apis/toolhive-api/changes/api/v1beta/skills/sync/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)
