Operator-level erasure of a full tenant
const url = 'https://api.aerandil.com/v1/tenant-erasure-requests';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"tenant_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.aerandil.com/v1/tenant-erasure-requests \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "tenant_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }'Hard-delete every objects and links row for a single tenant_id in one transaction. The contract-driven offboarding pathway — distinct from the per-row Article 17 endpoint at /v1/erasure-requests.
Operator-level scope: tenant_admin:write. A tenant token cannot legitimately carry this; the caller is an Aerandil operator administering the contract that governs tenant_id’s lifecycle.
events is preserved. The append-only audit log carries no PII (only metadata); retaining it post-tenant-erasure keeps the record-of-action intact for the regulator and the operator’s compliance archive.
Single transaction. A partial decommission would be worse than no decommission — it leaves rows visible after the operator thinks they’re gone.
Idempotent via Idempotency-Key.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”Opaque idempotency token (Stripe-shape). Repeated POSTs with the same key replay the original response within the cache TTL rather than creating a duplicate object.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Tenant to decommission. The caller is an Aerandil operator administering this tenant; the handler does not require the caller’s principal to live inside tenant_id (that would defeat the off-tenant operator semantic).
Examplegenerated
{ "tenant_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"}Responses
Section titled “Responses”Tenant decommissioned. Counts surface for the operator’s audit log; the response is mostly informational since the action is irreversible.
object
Example
{ "status": "erased"}Headers
Section titled “Headers”Always no-store.
Missing the tenant_admin:write scope. Tenant- level tokens MUST NOT carry this scope.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}Body invalid — invalid_body or invalid_idempotency_key.
Structured error wrapper. Every non-2xx response from any Aerandil endpoint serialises to this shape; the HTTP status carries the failure class (4xx/5xx), the body adds a stable code for programmatic dispatch plus a human-readable message.
object
object
Stable, programmatic error code (e.g. unauthorized, forbidden, not_found, invalid_body, invalid_url, precondition_failed, no_secondary_key). Clients dispatch on code, not on the message (which may be localised or contextualised in future versions).
Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.
Human-readable explanation of the failure.
Per-error structured detail. The shape varies by code (e.g. forbidden_action carries {"action": "..."}; precondition_failed carries {"current_version": N}).
Examplegenerated
{ "error": { "code": "example", "instance_id": "example", "message": "example", "parameters": "example" }}