When apiweld check finds a breaking change, apiweld heal works out exactly where your code breaks and sets up the fix. The work is split three ways:
- Apiweld does the mechanical parts: it regenerates the client, runs the compiler, and writes the plan. No AI is involved.
- Your coding agent (or you) edits the code that no longer compiles.
- A person reviews the change and merges it. Nothing is ever merged automatically.
You don’t need an agent. Without one, apiweld heal still gives you the regenerated client and a list of every call site that no longer type-checks. That’s most of the fix.
How it works
Regenerate off to the side
Apiweld writes the new client into a temporary git worktree. Your working copy isn’t touched until you decide to apply it.
Find what breaks
The TypeScript compiler checks your project, using your tsconfig.json, against the new client. Each error is matched to the API change that caused it, by endpoint and generated type name.
Write the plan
The plan is saved to .apiweld/reports/<api>-<date>.json, with a Markdown copy next to it. It lists each change, the file and line of each call site it breaks, and hints from the spec, such as a likely renamed field or the replacement for a deprecated endpoint.
Fix the call sites
Your agent reads the plan with get_heal_plan and applies the new client with apiweld heal --apply. It then fixes the call sites and runs verify until the type-check and your tests pass.
Review and merge
Locally, the result is an ordinary diff. In CI, it’s a pull request. Either way, a person merges it.
npx apiweld heal stripe # write the plan
npx apiweld heal stripe --apply # also put the new client in your working tree
npx apiweld verify # type-check, then run your testsWhat a plan looks like
Plans are JSON so agents can read them. The Markdown copy has the same content for people.
{
"api": "stripe",
"from": { "specHash": "sha256:9f2c…", "version": "2026-08-27" },
"to": { "specHash": "sha256:77aa…", "version": "2026-09-15" },
"findings": [
{
"id": "response-property-removed",
"level": "breaking",
"operation": "GET /v1/refunds/{refund}",
"detail": "removed property 'failure_balance_transaction' from the 200 response",
"callSites": [
{
"file": "src/billing/refunds.ts",
"line": 42,
"symbol": "Refund.failure_balance_transaction",
"tsError": "TS2339: Property 'failure_balance_transaction' does not exist on type 'Refund'."
}
],
"hints": ["No replacement field found in the new schema."]
}
],
"verify": { "typecheck": "tsc --noEmit", "test": "bun run test" }
}Each finding says what changed, which endpoint it affects, and where your code breaks, with the exact compiler error. The agent doesn’t have to re-read the spec or guess. Its job is the edit that makes verify pass. If it can’t find one, the plan still works as a precise bug report for a person.
verify lists the commands that must pass. The test command comes from verify.test in your config, and is left out if you haven’t set one.
In CI
The Apiweld GitHub Action runs apiweld check on a schedule. When one of your endpoints drifts, it applies the regenerated client, pushes a branch named apiweld/heal-<date>, and opens a pull request with the heal plan as its description. It runs in your repository with your token, and it never merges.
name: apiweld
on:
schedule:
- cron: "0 8 * * 1" # Mondays at 08:00 UTC
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- uses: apiweld/apiweld/action@main
with:
fail-on: breakingInputs: fail-on (breaking or risky), api to check a single API, command to run Apiweld some other way (for example bun run apiweld), and token if the default GITHUB_TOKEN can’t push branches. The action sets a drift output to true when something changed.
The pull request contains the regenerated client and the plan. The call sites still need fixing, either by you or by an agent working on that branch.
