Pincer: Terminate

Pincer termination is R4's license teardown surface for machine clients. Callers start a termination and poll status while R4 coordinates provider cleanup, shared backend cleanup, and archival on the server.

Website catalog endpoints, product detail pages, product vault-field metadata, and catalog-admin provisioning routes are internal implementation details. They are not part of the public Pincer API.

Endpoints

All paths are relative to https://r4.dev and require machine authentication.

EndpointMethodPurpose
/api/v1/machine/licenses/terminatePOSTTerminate a provisioned license
/api/v1/machine/licenses/terminations/:terminationId/statusGETPoll the termination until it succeeds or fails
/api/v1/machine/licenses/terminations/:terminationId/resumePOSTResume 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.

Terminate A License

POST /api/v1/machine/licenses/terminate
Content-Type: application/json
X-API-Key: <access-key>.<secret>
{
  "licenseInstanceId": "license_instance_123"
}

Important request fields:

FieldTypeDescription
licenseInstanceIdstringProvisioned license instance to terminate

Termination starts provider teardown using the product automation Lambda. For CrowdStrike v1, R4 cancels the Pax8 subscription, deletes the provisioned CrowdStrike admin user when the stored CID and user UUID are available, removes the Resend receiving domain for the license email, and then archives the R4 license instance plus its linked vault item.

Shared cleanup such as Pax8, Resend, and Namecheap work is delegated back to the R4 backend. Product Lambdas orchestrate product-specific teardown and call those backend cleanup endpoints instead of carrying shared provider credentials or duplicated cleanup logic.

Pax8 cancellation is requested immediately. R4 records the Pax8 subscription status plus any returned subscription start and end dates in the termination job result for invoice reconciliation.

Termination Response

The termination call returns immediately with a termination status object:

{
  "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
}

Check Status

GET /api/v1/machine/licenses/terminations/job_456/status
X-API-Key: <access-key>.<secret>

Poll until status is succeeded or failed. R4 archives the license and linked vault item only after provider cleanup succeeds.

{
  "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
}

If status is failed, failedStep and errorMessage explain the blocker. The license remains active in R4 until the provider cleanup succeeds and backend archival completes.

Resume A Failed Termination

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 a failed termination can safely re-check Pax8, CrowdStrike, and Resend 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, provisioner logs, vault field payloads, or Lambda step details.

pincer-terminate - R4 Docs