Open an Article 17 erasure request
const url = 'https://api.aerandil.com/v1/erasure-requests';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"object_id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","object_type":"example","reason":"example"}'};
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/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.
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
API name of the object to erase (e.g. hospitality.person).
Free text naming the data subject or legal basis. Recorded on the request row under the internal.restricted marking.
Examplegenerated
{ "object_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "object_type": "example", "reason": "example"}Responses
Section titled “Responses”Pending erasure request opened.
object
The hospitality.erasure_request row id — the durable audit record. Readable via the generic object routes; decided via .../approve / .../reject.
true on a cached Idempotency-Key replay.
Example
{ "status": "pending"}Headers
Section titled “Headers”Always no-store.
No object with that (object_type, object_id) for this tenant.
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" }}