Skip to Content
Task guidesTechnical: Data-Subject Requests

Data-Subject Requests

Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.

When a person asks for the personal data Orqestra holds about them — or asks you to correct it, delete it, restrict its processing, or objects to it — you handle that as a data-subject request (DSAR). Orqestra gives you a tenant-scoped, evidence-aware workflow that resolves the subject’s records inside one workspace, classifies them, produces a minimized and redacted export, and applies a deletion or restriction action without ever touching the immutable audit chain or crossing a tenant or subject boundary.

This guide walks the operator path: open a request, collect, review and export, and action it. For the full data model, classifications, redaction contract, and audit-action list, see the reference: docs/reference/data-subject-requests.md.

Before you start

DSAR routes are workspace-scoped. You need:

  • data_subject_request.read to list and view requests.
  • data_subject_request.manage to create, collect, export, and action them.

The manage permission is also the authority that erases the subject’s records — you do not need the platform-level retention-purge permission to action a DSAR. The two are deliberately separate: DSAR erases one subject’s records inside one tenant; retention purge is a platform-wide disposal control.

1. Open a request

Create a request with the subject’s bounded identifiers and the request type. Supply at least one of email, actor_ref, or subject_ref — Orqestra stores only these closed keys, never a free-form copy of the subject’s data.

The request type is one of:

  • access_export — return what is held (completed by export).
  • correction — rectify inaccurate records.
  • deletion — erase the subject’s deletable records.
  • restriction — restrict processing without deleting.
  • objection — object to processing.
from orqestra_sdk import OrqestraClient client = OrqestraClient(base_url=..., token=...) request = await client.data_subject_requests.create( workspace_id, request_type="deletion", subject_identifiers={"email": "ada@example.com"}, subject_label="Ada L. (deletion request)", reason="Subject requested erasure", ) # request["state"] == "received"

A new request starts in received. A request id that belongs to another workspace is concealed as a 404 — you can only ever resolve a request inside its own tenant.

2. Collect the subject’s records

Run collection to resolve the candidate records that belong to the subject across the surfaces Orqestra can subject-scope. Collection advances the request through scoped → collecting → ready_for_review, and is safe to re-run.

collection = await client.data_subject_requests.collect(workspace_id, request_id) collection["manifest"] # { # "total_records": 12, # "counts_by_surface": {"memory": 7, "execution": 4, "governance_audit": 1}, # "counts_by_classification": {"deletable": 7, "exportable": 4, "retained_by_obligation": 1}, # "deferred_surfaces": [ # {"surface": "retrieval", "reason": "no subject-scoped query wired: ..."}, # ... # ] # }

What you get back is a bounded manifest — counts and classifications, never raw record content. Each query is tenant-scoped in SQL and filtered to the subject’s identifiers, so collection cannot reach another tenant’s or another subject’s records.

Read the deferred_surfaces list every time. Surfaces such as retrieval, evidence, provider_metadata, and support_account are reported as honest deferrals with a reason — Orqestra does not silently skip them, and it does not yet subject-scope them. A complete subject-record picture may require resolving those surfaces by other means.

3. Review and export

For an access_export request, run export once the request is ready_for_review. Export builds a minimized, redacted package and advances the request to exported.

export = await client.data_subject_requests.export(workspace_id, request_id) export["package"]["manifest"]["countsBySurface"]

The package is:

  • Minimized — only this subject’s collected records, each reduced to its surface, classification, record ref, and a bounded summary. No raw content.
  • Redacted — every value is run through the token-leak redactor and a secret-key guard, so no token, secret, password, or credential survives into the export.
  • Manifested — per-surface and per-classification counts, the explicit deferred-surface list, and a truncated flag with a truncatedSurfaces list, so the package is honest about what it does and does not contain.

Review the manifest counts and the deferred list before you hand the package to the subject or your privacy reviewer. Check manifest["truncated"]: when it is true, a surface held more of the subject’s rows than the per-surface cap returned, so the package contains a bounded subset of the subject’s records on the named truncatedSurfaces only — it is not a complete export. Resolve the remaining rows before treating the export as the subject’s full record set.

4. Action the request

For a correction, deletion, restriction, or objection request, run the action. The action verb must match the request’s type (a mismatch is rejected with a 422). Orqestra re-collects fresh before acting, so the disposition is decided on the current state, then applies it.

result = await client.data_subject_requests.action( workspace_id, request_id, action="deletion", ) result["result"] # { # "action_type": "deletion", # "erased": 7, # "restricted": 0, # "retained_by_exception": 1, # "skipped": 4, # "counts_by_surface": {"memory": 7}, # "retained_by_surface": {"governance_audit": 1}, # "retention_reasons": ["immutable_audit_record"], # "incomplete": False, # "incomplete_surfaces": [], # "drainable": False # }

What the action does, and does not do:

  • Erases only the subject’s in-tenant deletable records. Deletion is bounded to the exact collected memory entry ids, resolved through the governed, workspace-scoped purge path. It can never reach a cross-tenant or cross-subject row.
  • Never deletes the audit chain. Governance-audit / WORM rows and execution governance metadata are obligation-bound: they are recorded as retained_by_exception with a bounded retention reason (immutable_audit_record or legal_or_security_obligation), never destroyed. The DSAR action itself is appended to the same tamper-evident chain.
  • Restriction never deletes. A restriction action records a processing restriction over the subject’s records instead of erasing them.

If everything in scope was retained under an obligation — nothing erased, nothing restricted — the request lands in retained_by_exception rather than actioned, and an extra data_subject_request.retained_exception audit event is appended alongside the action event.

Capped (incomplete) deletions. If the subject owns more deletable rows on a surface than the per-surface cap, the action erases only a capped batch and reports incomplete: true with the capped surface in incomplete_surfaces. A deletion is drainable: true — the request is then held at ready_for_review instead of advancing to actioned, because re-running it erases the next batch. Re-run the action until incomplete is false (the state then advances to actioned); each run drains the next batch and the erasure completes across calls. A capped restriction is reported incomplete: true but drainable: false and still reaches actioned, since re-running removes no rows — resolve its remaining rows out of band. (A capped correction or objection records a single governance decision rather than processing memory rows individually, so it is not flagged incomplete and reaches actioned normally.) A capped action is never silently recorded as complete.

Every step writes a bounded data_subject_request.* governance-audit event whose recorded state carries counts, the lifecycle state, and bounded reasons only — never the subject’s personal data.

What this workflow is (and is not)

The DSAR workflow produces operational evidence of how you handled a request: what was searched, classified, exported, erased, restricted, and retained under an obligation, and why. It does not by itself constitute legal compliance or conformity. It does not decide a lawful basis, judge whether a request is valid, verify the requester’s identity, or cover personal data held outside the wired surfaces. Treat its output as input to your controller’s privacy process under appropriate legal review.