Skip to content

Open an Article 17 erasure request

POST
/v1/erasure-requests
curl --request POST \
--url https://api.aerandil.com/v1/erasure-requests \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "object_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "object_type": "example", "reason": "example" }'

Open a pending erasure_request for one (object_type, object_id) — the durable audit record of a right-to-erasure demand. Nothing is deleted yet: a second, separately-scoped principal decides the request via .../approve (which performs the hard delete) or .../reject (e.g. an Art. 17(3) retention carve-out applies).

Scope erasure:write opens requests; erasure:approve decides them — the separation is the dual-control seam.

Tenant-scoped. Naming another tenant’s object returns 404, indistinguishable from “no such id”.

Pending requests are ordinary ontology objects: list them via the generic search route on hospitality.erasure_request. 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
object_id
required
string format: uuid
object_type
required

API name of the object to erase (e.g. hospitality.person).

string
reason

Free text naming the data subject or legal basis. Recorded on the request row under the internal.restricted marking.

string
Examplegenerated
{
"object_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"object_type": "example",
"reason": "example"
}

Pending erasure request opened.

Media typeapplication/json
object
id
required

The hospitality.erasure_request row id — the durable audit record. Readable via the generic object routes; decided via .../approve / .../reject.

string format: uuid
idempotent_replay

true on a cached Idempotency-Key replay.

boolean
object_id
required
string format: uuid
object_type
required
string
status
required
Allowed value: pending
Example
{
"status": "pending"
}
Cache-Control
string
Allowed value: no-store

Always no-store.

No object with that (object_type, object_id) for this tenant.

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