---
title: "Apply exact-string find/replace edits to the persisted source"
method: PATCH
path: "/app/{id}/source"
---

# Apply exact-string find/replace edits to the persisted source

`PATCH /app/{id}/source`

## Request

- Base URL: `https://charm.ing`
- URL: `https://charm.ing/app/{id}/source`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Applies an edits[] array to desired module/ui/styles. ESM saves require Idempotency-Key, return 202, and preserve active output until publication. An exact request-key replay returns the original operation before stale revision or edit matching checks. Each edit names a `bucket`, an exact `old_string` to match, and a `new_string` replacement. Requires `If-Match: "<N>"` carrying revision N from a fresh source response or ETag. A stale value returns 412 and surfaces the current ETag. Same auth as PUT.

## Headers

- `Idempotency-Key` string
- `If-Match` string, required

## Request body

- object
  - `migrate_contract` boolean: Explicitly migrate when the edited source selects a new contract. ESM requires the exact schema, a request key and If-Match.
  - `edits` object[], required
    - `bucket` 'module' | 'ui' | 'styles', required
    - `old_string` string, required
    - `new_string` string, required
    - `replace_all` boolean

## Response `200`

Edits applied; committed server revision returned.

- object
  - `ok` boolean, required
  - `id` string, required
  - `revision` integer, required: Server-owned app source revision. New apps start at 1, each successful source write advances it once, and historical null counters project as 0. `If-Match: "<N>"` and `expected_revision` carry this revision through its canonical concurrency grammar.
  - `warnings` string[]: Non-blocking publish feedback (#1126), present only when static validation found UI/backend contract mismatches. The write succeeded.

## Other responses

- `202`: ESM source accepted for a background build. This response does not mean the app has published. Poll statusUrl until a terminal state; new creation has no runnable app or URL until published.
- `400`: Body malformed (missing edits, invalid bucket, malformed If-Match).
- `401`: Authentication required.
- `403`: Token does not authorize this app.
- `404`: App not found.
- `409`: Idempotency conflict, or old_string matched more than once; refine or set replace_all.
- `412`: If-Match did not match the current server revision; response carries the current ETag.
- `413`: Payload too large: too many edits, an oversize old_string/new_string (`edits_too_large`), or the post-edit module/ui breaches the 256 KiB cap (`module_too_large` / `ui_too_large`).
- `422`: Edit match failed, source/import validation failed, or explicit migration is required.
- `428`: If-Match header required; GET /source for the fresh revision and ETag.
- `429`: Build capacity is full; retry after the returned delay.

---

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