Pincer termination is R4's license teardown API for machine clients. Start a termination, poll the job, and R4 coordinates provider cleanup plus backend archival.
Catalog-admin provisioning routes and provider-specific automation details are internal implementation details. They are not part of the public Pincer API.
All paths are relative to https://r4.dev and require machine authentication.
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/machine/licenses/terminate | POST | Start license termination |
/api/v1/machine/licenses/terminations/:terminationId/status | GET | Poll termination status |
/api/v1/machine/licenses/terminations/:terminationId/resume | POST | Resume a failed termination |
POST /terminate and termination resume require machine.license.write.
Termination status polling requires machine.license.read. The machine key must
also be allowed to operate on the tenant that owns the license instance.
POST /api/v1/machine/licenses/terminate with the provisioned
licenseInstanceId.GET /api/v1/machine/licenses/terminations/:terminationId/status.failedStep and errorMessage, then resume the
same termination when appropriate.POST /api/v1/machine/licenses/terminate
Content-Type: application/json
X-API-Key: <access-key>.<secret>{
"licenseInstanceId": "license_instance_123"
}Request fields:
| Field | Required | Description |
|---|---|---|
licenseInstanceId | Yes | Provisioned R4 license instance to terminate. |
The response returns immediately with a termination job:
{
"terminationId": "job_456",
"status": "in_progress",
"licenseInstanceId": "license_instance_123",
"orderId": "order_123",
"orderItemId": "order_item_123",
"attempts": 1,
"startedAt": "2026-05-28T09:00:00.000Z",
"updatedAt": "2026-05-28T09:00:00.000Z",
"finishedAt": null,
"failedStep": null,
"errorMessage": null
}GET /api/v1/machine/licenses/terminations/job_456/status
X-API-Key: <access-key>.<secret>Poll until status is succeeded or failed.
| Status | Meaning |
|---|---|
in_progress | R4 is still tearing down the provider resources. Keep polling. |
succeeded | Provider cleanup succeeded and R4 archived the license records. |
failed | The job stopped. Use failedStep and errorMessage, then resume if appropriate. |
{
"terminationId": "job_456",
"status": "succeeded",
"licenseInstanceId": "license_instance_123",
"orderId": "order_123",
"orderItemId": "order_item_123",
"attempts": 1,
"startedAt": "2026-05-28T09:00:00.000Z",
"updatedAt": "2026-05-28T09:01:00.000Z",
"finishedAt": "2026-05-28T09:01:00.000Z",
"failedStep": null,
"errorMessage": null
}R4 archives the license instance, closes the current license period, and archives linked vault items only after provider cleanup succeeds. Until then, the license remains active in R4.
POST /api/v1/machine/licenses/terminations/job_456/resume
X-API-Key: <access-key>.<secret>Resume only after the status endpoint returns failed. Provider cleanup steps
are designed to be idempotent, so resuming the same termination can safely
re-check provider state before retrying R4 archival.
The resume call returns the same termination status shape, usually with
status: "in_progress" and attempts incremented.
The status response is deliberately compact. It does not expose provider automation settings, provider logs, or internal cleanup state.