---
title: "Update mutable settings for a saved package: hidden search-discovery, publish lock (`changes.locked: true`; agents ca..."
method: PATCH
path: "/v1/packages/{package_id}"
tags: ["packages"]
---

# Update mutable settings for a saved package: hidden search-discovery, publish lock (\`changes.locked: true\`; agents ca...

`PATCH /v1/packages/{package_id}`

## Request

- Base URL: `https://api.kody.codes`
- URL: `https://api.kody.codes/v1/packages/{package_id}`
- Auth: HTTP bearer

Update mutable settings for a saved package: hidden search-discovery, publish lock (`changes.locked: true`; agents cannot unlock), repo visibility / forkable (`changes.visibility`), and internet-visible app serving (`changes.internet_visible`). Making a package public lists it on /community with full source and fork. Before setting visibility public, review source, README, Intent, description, tags, examples, and hardcoded identifiers for overly personal material. If anything looks personal or household-specific, do not publish yet — tell the user what you found, suggest how to generalize, and wait for explicit go-ahead. No MIT, logo, or Intent platform gates. Making it private unlists it (public URLs 404; forks keep their copies) — pass confirm_name matching the package slug after the owner typed that name. Internet-visible is independent of forkable and requires owner capability approval on the website. Canonical package metadata such as name, description, and tags remains derived from package.json. Visibility is not package.json#private.

Org permission: `package:write`.

## Path parameters

- `package_id` string, required: Saved package id.

## Request body

- object
  - `changes` object, required
    - `hidden` boolean: When true, hide the package from ranked search discovery by default.
    - `locked` boolean: When true, lock publishes so later agent publishes need a website click. Agents can lock but cannot unlock; send the owner to the package page (/@{username}/{kodyId}) to unlock.
    - `visibility` 'public' | 'private': Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Before setting public, review the package for overly personal content (package_authoring visibility). If anything looks personal, stop, tell the user, suggest generalizing, and wait for explicit go-ahead. Private is owner-only. Changing to private unlists the catalog entry; existing forks keep their copies. Independent of internet_visible.
    - `internet_visible` boolean: Internet-visible app serving. Independent of visibility/forkable. Setting true makes the package internet-visible right away when either (1) self-publish applies (the resolved capability set is empty, nothing in the dependency tree declares a credential or another capability, a security audit with verdict pass is recorded for the current published commit + fingerprint, and the caller may package:publish), or (2) the owner already approved the current capability set (matching pin) — then went_public is approved without another Approve click. An unpublished package is refused with an error: publish it first. Otherwise agents cannot approve the capability set: it returns an approval_url for the owner website and self_publish_blocker (or self_publish_error when applying a matching pin failed) says why. When the published version has no security audit, it also returns security_audit: run that audit and record it with packageSecurityAuditRecord using security_audit.args. Recording verdict pass re-evaluates the pending request and self-publishes when everything else allows it; otherwise hand the owner approval_url. Calling this again with internet_visible true also re-evaluates. Setting false turns off public app serving (requires confirm_name).
  - `confirm_name` string: Required when changes.visibility is private or changes.internet_visible is false. Must equal the package slug (URL name). Confirm with the user first.

## Response `200`

Success.

- object
  - `ok` true, required
  - `package` object, required
    - `package_id` string, required
    - `kody_id` string, required: Package name leaf (same value as `slug`). Kept as a compatibility alias; prefer `slug` or `name`.
    - `slug` string, required: Package name leaf (the path segment after the scope). Same value as `kody_id`.
    - `name` string, required
    - `description` string, required
    - `tags` string[], required
    - `has_app` boolean, required
    - `hidden` boolean, required
    - `visibility` 'public' | 'private', required: Repo visibility / forkable. Public means default-branch HEAD is world-readable and forkable and the package appears on /community. Private is owner-only. Independent of internet_visible.
    - `internet_visible` boolean, required: When true, the hosted package app may be served on the public internet after capability approval. Independent of visibility/forkable. Defaults false.
    - `locked_at` string, nullable, required: When set, publishes require a website click at /@{username}/{kodyId}/approve-publish?commit=<full 40-character SHA>. Agents may lock via packageUpdate (`changes.locked: true`). Unlocking is website-only at /@{username}/{kodyId}/settings. Do not abbreviate the commit.
    - `source_id` string, required
    - `created_at` string, required
    - `updated_at` string, required
  - `approval_url` string: Present when internet_visible was requested and is waiting on owner Approve (went_public). One Approve on that page records the capability set and turns internet-visible on.
  - `internet_visible_pending` boolean: True when other package changes applied but internet-visible is waiting on owner Approve.
  - `security_audit` object: Present when internet-visible is pending and the published version has no security audit. Do this before handing the owner approval_url: audit, then record with packageSecurityAuditRecord.
    - `next_step` string, required
    - `operation` 'packageSecurityAuditRecord', required
    - `http_route` string, required
    - `args` object, required: Exact values for packageSecurityAuditRecord. Add verdict ("pass" or "concerns"), summary, and optionally auditor.
      - `package_id` string, required
      - `published_commit` string, required
      - `fingerprint` string, required
    - `audit_prompt` string, required: What to review and how to record it, as the owner would ask.
  - `self_published` true: Present when internet_visible was turned on without owner Approve because the package declares no credential or capability. The package cannot use any credential while public this way.
  - `self_publish_blocker` 'unpublished' | 'stale_dependencies' | 'declares_credentials' | 'declares_capabilities' | 'not_audited' | 'audit_concerns' | 'not_permitted': Why internet_visible waits on owner Approve instead of self-publishing: the capability set has credentials or storage to approve, a package in the tree is unpublished, a dependency republished since this package's publish (stale_dependencies: publish this package again), the tree declares credentials, the tree declares other capabilities, the current published commit + fingerprint has no security audit (not_audited) or one with verdict concerns (audit_concerns), or the caller may not publish this package. For not_audited: audit, record verdict pass with packageSecurityAuditRecord; that re-evaluates the pending request.
  - `self_publish_error` string: Present when self-publish applied but its approval failed; internet_visible waits on owner Approve at approval_url instead.

## Other responses

- `400`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `401`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `403`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `404`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `409`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `413`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `429`: Too many requests (edge IP/token limit) or an entitlement / plan-cap limit. Wait at least `Retry-After` seconds before retrying.
- `500`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `503`: Error envelope `{ "error": { "code", "message", "details"? } }`.
- `default`: Error envelope `{ "error": { "code", "message", "details"? } }`.

---

[API](https://skmtc.dev/kody/apis/kody-api.md) · [All operations](https://skmtc.dev/kody/apis/kody-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kody/apis/kody-api/revisions/a020ecedb82b?raw)
