Skip to content

Operator-level erasure of a full tenant

POST
/v1/tenant-erasure-requests
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.

Idempotency-Key
string
>= 1 characters

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.

Media typeapplication/json
object
tenant_id
required

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).

string format: uuid
Examplegenerated
{
"tenant_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}

Tenant decommissioned. Counts surface for the operator’s audit log; the response is mostly informational since the action is irreversible.

Media typeapplication/json
object
idempotent_replay
boolean
links_removed
required
integer
objects_removed
required
integer
status
required
Allowed value: erased
tenant_id
required
string format: uuid
Example
{
"status": "erased"
}
Cache-Control
string
Allowed value: no-store

Always no-store.

Missing the tenant_admin:write scope. Tenant- level tokens MUST NOT carry this scope.

Media typeapplication/json

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
error
required
object
code
required

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).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

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.

Media typeapplication/json

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
error
required
object
code
required

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).

string
instance_id

Request-id correlation handle echoed on the request-id response header — support teams correlate without scraping logs.

string
message
required

Human-readable explanation of the failure.

string
parameters

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