Skip to content

Deactivate Device ​

Release (revoke) a device activation so its seat is freed. There are two ways to do this, for two different callers:

  1. App self-service release (Integration API) — the licensed application releases the seat it activated (e.g. on uninstall / deregister / hardware change). This is the recommended, automated path and the one that lets a activations.max: 1 license move to a new device without manual help.
  2. Administrative revoke (Tenant / Admin API) — the account owner (or a ValidonX admin) force-revokes a specific activation by id from the dashboard.

Revocation is non-destructive: the activation record is preserved (status = "revoked", deactivated_at set) for audit purposes, and the seat it held no longer counts against the license's activations.max.


1. App self-service release (Integration API) ​

The application releases the activation it created, identified by the same license_key + instance_id it activated with — no activation id required.

Endpoint ​

POST /api/v1/integration/activations/deactivate

Headers ​

HeaderRequiredValue
X-API-KeyYesYour API key
Content-TypeYesapplication/json

Request Body ​

json
{
  "license_key": "VX-ACME-abc123def456",
  "instance_id": "server-prod-01",
  "device_fingerprint": "sha256-hash-of-device-info"
}
FieldRequiredTypeDescription
license_keyYesstringThe license key the seat was activated against
instance_idYesstringThe instance identifier used at activation
device_fingerprintNostringIf supplied, further narrows the match to a specific device

Response (200 OK) ​

json
{
  "data": {
    "activation": {
      "id": "9a1b7c2d-3e4f-5a6b-7c8d-9e0f1a2b3c4d",
      "license_key_id": "1f2e3d4c-5b6a-7988-a0b1-c2d3e4f5a6b7",
      "instance_id": "server-prod-01",
      "device_fingerprint": "sha256-hash...",
      "status": "revoked",
      "deactivated_at": "2026-07-06T10:00:00.000000Z"
    }
  },
  "meta": { "request_id": "uuid", "api_version": "1" }
}

Idempotency ​

Releasing a seat that is already released returns 200 with the same revoked activation — safe to retry, and safe to call on every uninstall even if a previous attempt already succeeded.

Freeing a single-seat license ​

For a license with activations.max: 1, a second device is refused with ACTIVATION.LIMIT_EXCEEDED while the first seat is active. Releasing the first activation frees the seat, and the next device can then activate — the intended device-transfer flow.

Error Responses ​

CodeHTTPDescription
LICENSE.NOT_FOUND404License key not found for your tenant
ACTIVATION.INVALID400No activation exists for that license_key + instance_id
VALIDATION.FAILED422license_key or instance_id missing
AUTH.INVALID_API_KEY401Invalid API key

2. Administrative revoke (Tenant / Admin API) ​

The account owner force-revokes a specific activation by id — e.g. to reclaim a lost, stolen, or stuck seat. Activation ids come from GET /api/v1/tenant/activations (see the Activation Lifecycle guide).

Endpoint ​

DELETE /api/v1/tenant/activations/{activationId}

Platform admins can revoke on behalf of a tenant at:

DELETE /api/v1/admin/tenants/{tenantId}/activations/{activationId}

Headers ​

HeaderRequiredValue
AuthorizationYesBearer {token} (token needs the tenant ability)

This path uses a tenant Bearer token, not an API key — it is an account-management action, not something the distributed application performs.

Response (200 OK) ​

json
{
  "data": {
    "id": "9a1b7c2d-3e4f-5a6b-7c8d-9e0f1a2b3c4d",
    "status": "revoked",
    "deactivated_at": "2026-07-06T10:00:00.000000Z"
  },
  "meta": { "request_id": "uuid", "api_version": "1" }
}

Idempotent — revoking an already-revoked activation still returns 200. An activation that belongs to another tenant is reported as not found (ACTIVATION.INVALID), never revealed or revoked.

Error Responses ​

CodeHTTPDescription
ACTIVATION.INVALID400Activation not found (or not owned by your tenant)
AUTH.TOKEN.REQUIRED401Missing / invalid Bearer token

Activation States ​

StatusDescription
activeCurrently active, counts against activations.max
suspendedTemporarily suspended
revokedDeactivated — deactivated_at set; no longer counts against the limit