docs / concepts
Per-PR exceptions
Let a single pull request through a freeze with a reason, a time limit, and a record of who decided. The dashboard steps, the API call, and when a grant is refused.
complete · updated 1 september 2026
An exception lets one pull request through an active freeze without lifting it for everyone else. It requires a reason, it expires, and both the grant and the expiry land in the audit log with the actor who decided. Per-PR exceptions start at Team.
Grant one in the dashboard
- Exceptions → Grant an exception.
- Pull request. Paste the URL, or
owner/repo#123, or a bare number. Fwozen resolves it and shows which freeze it is about to cut through. - Reason. Eight characters minimum, and the field an auditor reads first. Name the incident or the fix rather than the fact that it is urgent.
- Expires. One hour, four hours, until the freeze ends, or a custom number of minutes between 5 minutes and 7 days.
- Policy override, when this one has to differ from the organisation default. Sticky survives new commits; strict revokes the exception the moment a new commit lands on the pull request.
The fwozen check on that pull request flips to passing, and it alone. Every other pull request on the branch stays blocked.
From the API
curl -X POST https://api.fwozen.com/v1/exceptions \
-H "Authorization: Bearer $FWOZEN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"repo": "acme/api-server",
"prNumber": 4821,
"reason": "Hotfix for the checkout 500s",
"expiresInMinutes": 60
}'Send repoId instead of repo if you hold Fwozen’s ids: one or the other, never both. Leave expiresInMinutes out and the exception ends with the freeze itself. The key needs exception:write. There is no freezeId field, on purpose: one grant covers every freeze currently blocking that pull request, so a repository caught by an org freeze and a release window at the same time does not need two.
POST /v1/exception-requests is the other half. Someone without the authority to grant asks, an approver decides with POST /v1/exception-requests/{id}/decide, and the audit log carries both names. An organisation that turns on two-person approval gets that flow for every grant.
Revoking, and when one cannot be granted
- Revoke ends it immediately (
POST /v1/exceptions/{id}/revoke), and the check goes red again on the next write. - A freeze created with exceptions turned off refuses every grant while it is in force, with exceptions_not_permitted. That is the setting to reach for during a real incident, rather than a sterner reason string.
- An exception is about merging. It never unblocks a deploy: the deploy gate reads the freeze, and letting one pull request merge is not a freeze-wide decision.