Rights API
Public OTP intake and operator cases, systems, maps, evidence.
Rights API
Source: app_docs/api.md, app_docs/guide/rights.md, app_docs/guide/api.md.
Terminology: engineering Case = product Rights request. HTTP connectors = product Systems.
Public intake (OTP)
Auth: none (public). Abuse controls: IP + email rate limits, OTP attempt caps, hashed OTP at rest.
Base: /api/rights/v1/orgs/:orgSlug
Flow: initiate OTP → verify OTP → then create VERIFIED DELETE Case. No case before verify.
Does not use legacy /api/portal/*.
| Method | Path | Purpose |
|---|---|---|
GET | /api/rights/v1/orgs/:orgSlug | Public org card { organization: { name, slug } } |
POST | /api/rights/v1/orgs/:orgSlug/intake | Body { email, label? }. Issues OTP. 200 { success, expiresInMinutes, demoOtp? } |
POST | /api/rights/v1/orgs/:orgSlug/verify | Body { email, otp }. 201 { success, case: { id, type, status, verificationStatus, openedAt } } |
demoOtp: returned only when NODE_ENV !== 'production' or RIGHTS_INTAKE_DEMO_OTP=true. Production must send email (Resend / RESEND_API_KEY in product security model). Never return OTP in production JSON as a normal path.
| Code | When |
|---|---|
| 200 / 201 | Success |
| 400 | Validation / invalid OTP |
| 404 | Unknown org slug |
| 429 | Rate limited / too many OTP attempts |
After verify, operators see the case on platform Rights APIs (status OPEN, verification VERIFIED).
Operator cases
Auth: session Bearer + org membership.
Base: /api/platform/orgs/:orgId/rights/cases
Type: DELETE only. Start enqueues Job rights.delete (worker + connectors).
Non-members receive 404 for the org (no enumeration). Cases in another org return 404.
Case JSON shape (public)
{
"case": {
"id": "…",
"organizationId": "…",
"projectId": null,
"type": "DELETE",
"status": "OPEN",
"verificationStatus": "UNVERIFIED",
"subject": { "email": "a@b.co", "externalId": null, "label": null },
"openedAt": "…",
"completedAt": null,
"cancelledAt": null,
"failedAt": null,
"createdAt": "…",
"updatedAt": "…",
"events": [
{
"id": "…",
"type": "case.created",
"payload": {},
"actorType": "operator",
"actorId": "…",
"createdAt": "…"
}
]
}
}List responses omit events. Detail + mutation responses include events.
Case routes
| Method | Path | Notes |
|---|---|---|
POST | …/cases | Create. Body: { subject: { email?, externalId?, label? }, projectId?, type?: "DELETE" }. Email and/or externalId required. 201 { case } |
GET | …/cases | List. Query: status, take (1–100, default 50). 200 { cases } |
Lifecycle actions documented for the operator API group: start, cancel, complete, fail, verify (see platform Rights routes under /api/platform/orgs/:orgId/rights/…).
Start requires:
- Verification VERIFIED
- Start readiness — enabled Systems; each SQL system has ≥1 DELETE entity with identifiers
Operator UI (same session)
| Route | Surface |
|---|---|
#/rights | Operations board |
#/rights/connector | Systems + Data Maps |
#/rights/:caseId | Case detail |
#/rights/:caseId/evidence | Deletion evidence |
Systems (connectors) + Data Maps
Base: /api/platform/orgs/:orgId/rights/connectors
| Method | Path | Notes |
|---|---|---|
GET | /connectors | { connectors, availableTypes } + health + dataMap summary |
POST | /connectors | Upsert by type + connection config + optional secrets |
GET / PATCH / DELETE | /connectors/:id | Detail · enable · delete |
POST | /connectors/:id/test | Health check |
POST | /connectors/:id/rotate | New secrets; webhook may return revealedSecrets once |
GET | /connectors/:id/data-map | Data map + subject field catalog |
POST | /connectors/:id/data-map/entities | Add entity (table + identifiers + deletion action) |
PATCH / DELETE | /connectors/:id/data-map/entities/:entityId | Update / remove entity |
POST | /connectors/:id/preview | SQL dry-run match counts (no delete) |
* | /connectors/postgres | Legacy alias for POSTGRES |
Secrets never return on GET lists (only hasSecrets / display hints). Rotate requires Owner capability.
Evidence (Rights)
| Method | Path | Notes |
|---|---|---|
GET | /api/platform/orgs/:orgId/rights/cases/:caseId/evidence | Deletion evidence package JSON |
GET | same ?format=json|csv|report&download=1 | Export download |
Readiness / graph / preview
Operator Rights routes also expose readiness, graph, and execution-preview under the org Rights base (see guide/api Rights operator group).