> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# DSAR Self-Service Portal End-to-End

> Combine operator-filed and public-portal DSAR intake, publish the portal link with the sender prerequisites set, walk the email + SMS OTP verification a data subject completes, and pick up the verified request in your operator queue on its statutory clock.

# DSAR Self-Service Portal End-to-End

Devotel Orbit accepts data-subject requests through two intake paths:
your operators filing on a subject's behalf, and a public portal the
data subject files through themselves. One queue feeds both. This
guide walks the portal path from link publication to fulfilment, and
shows how it combines with operator filing. The [DSAR
reference](/compliance/dsar) documents the endpoint surface and the
public e-mail/phone-claim state machine; this page is the runbook you
operate from.

<Note>
  Every control here is tenant-owned: you publish the link, you run the
  queue, you decide and fulfil. Orbit hosts the portal, proves identity
  with a two-factor OTP, and tracks the statutory clocks — the legal
  duty to respond stays with you, the controller. Confirm your
  obligations with counsel.
</Note>

***

## 1. Two intake paths, one queue

**Operator-filed.** Your team files a request with
`POST /compliance/dsar` or the **Create DSAR** dialog in
**Settings → Compliance → DSAR**. A request filed this way starts as
`verification_status: pending` — no export or erasure worker touches it
until an operator approves or rejects the identity review. This path
currently fits: subjects you already know (a logged-in customer, a
contact already in your workspace), and the rights the public form
cannot carry (correct, limit-sensitive-PI, non-discrimination).

**Public self-service portal.** The data subject files their own
request through the hosted public page — no account, no API key, no
session. The page verifies their identity with a two-factor email +
SMS OTP before anything enters your queue, so a portal filing arrives
pre-verified and the export or erasure worker starts immediately.

Run both. The portal carries consumer volume to zero ops touches;
operator filing covers the edge cases the portal cannot. Every request
from either path lands in the same **Settings → Compliance → DSAR**
list and the same `GET /compliance/dsar` response — one queue, one SLA
banner, one audit chain.

***

## 2. Portal walkthrough

### Publish the link

Host the portal as the "Submit a privacy request" link in your privacy
policy, website footer, or in-product privacy center:

```
https://orbit.devotel.io/<locale>/dsar
```

`<locale>` is the same locale prefix every Orbit web page carries
(`en`, `fr`, `de`, …). The page renders a two-step identifier form
behind a Cloudflare Turnstile bot check: the subject enters their
email and phone (E.164), picks a request type, and the identity proof
begins.

### The sender-email prerequisite

Decide which addresses the portal's verification codes send from
**before** the link goes live — an unset sender leaves the portal
failing closed in public. Two platform-level senders are configured
once in your API environment:

| Variable                        | Used for                       | Fallback                                            |
| ------------------------------- | ------------------------------ | --------------------------------------------------- |
| `DEVOTEL_DSAR_PROOF_FROM_EMAIL` | From-address on the email OTP. | none — delivery also needs `DEVOTEL_RESEND_API_KEY` |
| `DEVOTEL_DSAR_PROOF_SMS_FROM`   | E.164 sender on the SMS OTP.   | `DEVOTEL_PLATFORM_DEFAULT_FROM`                     |

With no SMS sender and no platform fallback, the phone step returns
`503` and the portal shows a "temporarily unavailable" message; with no
email delivery key, the email step fails the same way. In production
the first step also needs a Turnstile token — set
`DEVOTEL_TURNSTILE_SECRET_KEY` on the API and
`NEXT_PUBLIC_DEVOTEL_TURNSTILE_SITE_KEY` on the web deployment, from
the Cloudflare dashboard (Turnstile → Add site).

SMS verification codes ride the Devotel softswitch as platform OTPs —
not tenant-billable traffic.

### What the data subject sees

The subject completes a five-step claim; nothing is queued until both
proofs are on file:

1. **Begin** — email, phone (E.164), request type. An email OTP sends
   immediately.
2. **Verify email** — a 6-digit email code (10-minute TTL, 3 attempts,
   60-second resend cooldown).
3. **Send phone code** — an SMS OTP to the same phone (60-second
   cooldown between sends).
4. **Verify phone** — a 6-digit SMS code.
5. **Submit** — the request enters your queue only with both proofs.
   The whole claim has a 30-minute end-to-end TTL.

The friendly request types the subject picks map onto the operator
enum:

| Subject picks | Operator `request_type` |
| ------------- | ----------------------- |
| `access`      | `know`                  |
| `delete`      | `delete`                |
| `portability` | `portability`           |
| `opt_out`     | `opt_out_sale`          |

If the identifiers match no contact in your workspace, the submit step
still answers the same way — the portal never reveals whether a
contact exists — and the audit row is written at platform scope so the
forensic trail survives the no-match case.

### Jurisdiction maps to the SLA clock

The subject picks the jurisdiction their request falls under, and that
choice decides both the statutory clock the row carries and which
`request_type` values the queue may hold:

| Jurisdiction              | Code     | Response SLA |
| ------------------------- | -------- | ------------ |
| EU / EEA GDPR             | `gdpr`   | 30 days      |
| California CCPA           | `ccpa`   | 45 days      |
| California CPRA           | `cpra`   | 45 days      |
| Brazil LGPD               | `lgpd`   | 15 days      |
| Singapore / Thailand PDPA | `pdpa`   | 30 days      |
| Canada PIPEDA             | `pipeda` | 30 days      |
| India DPDP                | `dpdp`   | 30 days      |

Getting the pairing right matters: `opt_out_sale` and
`limit_sensitive_pi` have no GDPR equivalent, and the operator default
jurisdiction is `gdpr` — set it expressly on California consumers. A
portal filing of `opt_out` defaults jurisdiction to CCPA/CPRA precisely
because the GDPR default would otherwise be invalid. A subject's
mis-selection is fixable: reclassify the jurisdiction from the queue
and the SLA badge re-anchors.

***

## 3. What operators see after a filing

A portal filing that matches a contact lands in **Settings →
Compliance → DSAR** alongside operator-filed requests. Because the OTP
already proved identity, it arrives `verification_status: verified` —
no approve/reject gate blocks it.

* **Status and deadline.** The row carries the usual lifecycle status
  and a **Day X of N** SLA badge anchored to the jurisdiction's window;
  any breach raises the workspace-level SLA banner. `GET
  /compliance/dsar/sla` gives the same picture over the API.
* **Erasure-class filings.** A subject who picked "delete" appears in
  the **Erasure requests (Art. 17)** tab's portal section, SLA badge
  beside it, ahead of the 7-day cooling-off default.
* **Fulfilment.** An access or portability filing runs to **Completed**
  with a signed `export_url`; the **Download decrypted** action builds
  the plaintext export for an operator. An erasure, once executed,
  offers the **Proof of deletion** certificate and **Propagate** to your
  connected destinations.
* **Audit chain.** Begin, both verifications, and submit write rows
  with hashed (never raw) identifiers, source IP, and user agent — the
  record your [evidence binder](/guides/compliance-evidence-binder)
  pulls from when a regulator asks how identity was established.

***

## 4. What Orbit does not do

The portal is machinery for intake and identity proof; the legal
decisions stay with you:

* **Orbit never decides validity.** It never accepts or rejects a
  request on legal grounds. Verification pending rows wait on your
  approve/reject call; verified rows fulfil because you let them, not
  because the platform judged the claim.
* **Orbit never auto-fulfil an operator verdict.** For an
  operator-filed request, no export is produced and nothing is erased
  while `verification_status: pending`. A portal filing skips the gate
  only because its OTP already proved identity.
* **Erasure honours your cooling-off posture.** The 7-day default
  (overridable per tenant) gives you the window to reject, hold, or
  exempt before destruction.
* **Telling you which law applies is still your counsel's job.** Orbit
  anchors the SLA clock to whatever jurisdiction the subject picked
  and you confirmed.
* The portal surfaces the consumer-friendly rights subset — a subject
  who needs an operator-only right (correct, limit-sensitive-PI,
  non-discrimination) files through your team.

***

## 5. Worked example — a GDPR access request end to end

A customer in Berlin opens your privacy policy, taps the portal link,
and asks for everything you hold. The sequence:

1. **Begin.** She enters her email, her phone in E.164
   (`+4915…`), picks **access**, and clears the Turnstile check. The
   portal returns a claim id; the email OTP is already on its way.
2. **Verify email.** She reads the 6-digit code (10-minute TTL, up to
   3 attempts) and passes the first factor.
3. **Send phone code, verify phone.** The second factor repeats over
   SMS — a 60-second cooldown apart between sends — and both proofs are
   now on file.
4. **Submit.** The portal files the request. Because her email and
   phone match a contact in your workspace, the row queues as `know`
   under `gdpr` and returns a `dsar_pub_…` reference.
5. **In your queue.** The row shows **Day 1 of 30** —
   `verification_status: verified` — and the export worker already has
   it. Nobody on your team touches triage.
6. **Fulfil.** The worker compiles the export and marks the row
   **Completed** with `export_url` and `tables_exported`. An operator
   delivers the download link (an operator-only plaintext copy is one
   **Download decrypted** click away).
7. **Over the SLA line.** If the row is still open when the 30-day GDPR
   window elapses, the workspace SLA banner flags it — and had she
   mis-picked a jurisdiction at intake, your queue reclassification
   fixes the clock retroactively.

Time from subject's first form submission to queued request: the two
OTP prompt round-trips. Operator touches: zero.

***

## Related references

* [DSAR reference](/compliance/dsar) — the full operator and public
  endpoint surfaces, abuse-defence limits, and SLA severity tiers.
* [DPO & EU/UK representative designation](/compliance/dpo-representative) —
  the Art.37/Art.27 designations a privacy notice must name.
* [GDPR processing register (ROPA + DPIA)](/compliance/privacy-register) —
  the Art.30 inventory kept before any request arrives.
* [Compliance evidence binder](/guides/compliance-evidence-binder) —
  assemble the audit rows a portal filing leaves behind.
* [Fulfill a DSAR and operate the breach-incident register](/guides/compliance-dsar-breach-register) —
  the operator walkthrough of the queue your portal feeds.
* [Assembling a GDPR Posture End to End](/compliance/gdpr-posture-guide) —
  where portal intake sits in the full sequence.
