PlatformXeDocs
Get API Key

Access Overrides

API reference for requesting and processing document deletion overrides.

Some documents are protected by retention policies or restricted deletableBy settings — DELETE /documents/:id on one of these answers DELETE_BLOCKED (see Documents). To delete it anyway, an operator requests a deletion override; a different Super Admin then approves it (and, for documents under LEGAL or PERMANENT retention, a third Super Admin witnesses it) before it can be executed.

This provides an auditable two- (or three-) person approval flow for sensitive document deletion. The document is deleted by executing the approved override — not by retrying the original DELETE call.

Request a deletion override

POST /api/v1/storage/fixed/overrides

Scope: storage:upload (every /storage/* route requires it when the key has scopes)

Request body

FieldTypeRequiredDescription
documentIdstringYesID of the document to delete
overrideReasonstringYesJustification for the deletion — minimum 500 characters, for audit and compliance
authorityReferencestringNoReference to the authority permitting the override (e.g. a legal case number)
authorityTypestringNoType of authority (e.g. COURT_ORDER, LEGAL_COUNSEL)
authorityDocumentstringNoReference to a supporting document for the authority
operatorIdstringNoCaller-scoped identity of the human operator, for four-eyes separation. Always namespaced under your authenticated caller service server-side — it can identify a distinct person for the approve/witness checks below, but can never impersonate another tenant's identity

Response

{
  "success": true,
  "data": {
    "id": "ovr_abc123",
    "documentId": "doc_xyz789",
    "documentTitle": "Employment Contract - Ade Bakare",
    "overrideReason": "Duplicate contract uploaded in error during the 2026 HR migration. Original contract doc_original456 remains the system of record...",
    "authorityReference": null,
    "authorityType": null,
    "requestedById": "service:lettings:admin_001",
    "requestedAt": "2026-04-05T10:00:00.000Z",
    "approvedById": null,
    "approvedAt": null,
    "witnessedById": null,
    "witnessedAt": null,
    "status": "PENDING",
    "rejectionReason": null,
    "executedAt": null
  }
}
FieldTypeDescription
idstringOverride request ID
documentIdstringThe document targeted for deletion
documentTitlestringThe document's title at the time of the request
overrideReasonstringStated justification
authorityReferencestring or nullAuthority reference, if given
authorityTypestring or nullAuthority type, if given
requestedByIdstringIdentity of the requester — service:<callerService> or service:<callerService>:<operatorId>
requestedAtstringISO 8601 request timestamp
approvedByIdstring or nullApprover identity, once approved or rejected
approvedAtstring or nullISO 8601 approval/rejection timestamp
witnessedByIdstring or nullWitness identity, once witnessed
witnessedAtstring or nullISO 8601 witness timestamp
statusstringPENDING, APPROVED, REJECTED, or EXECUTED
rejectionReasonstring or nullNot currently populated by the API (reserved)
executedAtstring or nullNot currently populated by the API (reserved) — check status === "EXECUTED" instead

Process a deletion override

PATCH /api/v1/storage/fixed/overrides/:overrideId

Scope: storage:upload (every /storage/* route requires it when the key has scopes)

One endpoint, four actions. Approve and witness must each be performed by a different Super Admin than the requester (and, for witness, than the approver too) — the API rejects self-approval and self-witnessing.

Request body

FieldTypeRequiredDescription
actionstringYesapprove, reject, witness, or execute
rejectionReasonstringOnly for action: "reject"Reason for rejecting the request
operatorIdstringNoSame caller-scoped operator identity as the request step, for four-eyes separation

approve / reject / witness response

Same shape as the POST response above, reflecting the new status (APPROVED/REJECTED) or the recorded witnessedById/witnessedAt (witnessing does not change status — it stays APPROVED).

execute response

Different shape. Executing performs the soft-delete directly — there's no need to retry DELETE /documents/:documentId afterward.

{
  "success": true,
  "data": {
    "success": true,
    "documentId": "doc_xyz789"
  }
}

Override workflow

1. Operator attempts DELETE /documents/:id
   -> 403 DELETE_BLOCKED (document is retention-protected)

2. Operator requests an override
   POST /overrides { documentId, overrideReason }
   -> status: PENDING

3. A DIFFERENT Super Admin approves it
   PATCH /overrides/:id { action: "approve" }
   -> status: APPROVED

4. Only if the document's retentionType is LEGAL or PERMANENT:
   a THIRD Super Admin (not the requester or approver) witnesses it
   PATCH /overrides/:id { action: "witness" }
   -> witnessedById / witnessedAt recorded (status stays APPROVED)

5. Execute the override — this performs the deletion
   PATCH /overrides/:id { action: "execute" }
   -> { success: true, documentId } — the document is now soft-deleted,
      and the override's status becomes EXECUTED

Examples

Request, approve, and execute an override

curl

# Step 1: Request override
curl -X POST https://api.platformxe.com/api/v1/storage/fixed/overrides \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_your_api_key_here" \
  -d '{
    "documentId": "doc_xyz789",
    "overrideReason": "Duplicate contract uploaded in error during the 2026 HR migration. Original contract doc_original456 remains the system of record. Confirmed with HR lead on 2026-04-05. This satisfies the 500-character minimum required for the audit trail on deletion overrides for retention-protected documents."
  }'

# Step 2: A different Super Admin approves it
curl -X PATCH https://api.platformxe.com/api/v1/storage/fixed/overrides/ovr_abc123 \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_your_api_key_here" \
  -d '{ "action": "approve" }'

# Step 3: Execute — this deletes the document
curl -X PATCH https://api.platformxe.com/api/v1/storage/fixed/overrides/ovr_abc123 \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_your_api_key_here" \
  -d '{ "action": "execute" }'

TypeScript SDK

import { PlatformXeClient } from '@caldera/platformxe-sdk';

const px = new PlatformXeClient({ apiKey: 'pxk_live_your_api_key_here' });

// Request override
const override = await px.documents.requestOverride({
  documentId: 'doc_xyz789',
  overrideReason: 'Duplicate contract uploaded in error... (500+ characters)',
});

console.log(override.status);
// "PENDING"

// A different Super Admin approves it
const approved = await px.documents.processOverride(override.id, {
  action: 'approve',
});

console.log(approved.status);
// "APPROVED"

// Execute — deletes the document as part of this call
const result = await px.documents.executeOverride(override.id);
console.log(result.success, result.documentId);
// true "doc_xyz789"

Python SDK

from platformxe import PlatformXeClient

px = PlatformXeClient(api_key="pxk_live_your_api_key_here")

# Request override
override = px.documents.request_override(
    document_id="doc_xyz789",
    override_reason="Duplicate contract uploaded in error... (500+ characters)",
)

# A different Super Admin approves it
px.documents.process_override(override["id"], action="approve")

# Execute — deletes the document as part of this call
result = px.documents.process_override(override["id"], action="execute")
print(result["success"], result["documentId"])
# True "doc_xyz789"

Reject an override

await px.documents.processOverride('ovr_abc123', {
  action: 'reject',
  rejectionReason: 'This contract is still active, cannot delete',
});

Error responses

CodeStatusDescription
BAD_REQUEST400Missing documentId/overrideReason on request, or missing action on process
VALIDATION_ERROR400overrideReason is shorter than the required 500-character minimum
FORBIDDEN403The API key has scopes but not storage:upload (required on every /storage/* route), the key's organization is inactive, or the approver/witness is the same identity as the requester (or, for witness, the approver). Identity is service:<callerService> plus :<operatorId> when one is sent, so two steps from the same caller service without distinct operatorIds count as self-approval
NOT_FOUND404Document or override does not exist, or belongs to another caller
CONFLICT409An override request already exists for this document, or the override isn't in the right state for this action (approving/rejecting something not PENDING, witnessing before APPROVED, executing before APPROVED or before a required witness signature). execute also answers Override is no longer approved; it may already have been executed when another execute claimed the override first, and Document has already been deleted when the document was deleted some other way — in that case nothing is changed and the override stays APPROVED
RATE_LIMITED429Rate limit exceeded