Intempt Docs
GuidesPrivacy

Manage personal data

Submit, track, download, and cancel data subject requests through the Intempt API: endpoints, request types, identity formats, and error responses.

Overview

Everything the Privacy Center does for data subject requests is also available over the API. Use it when requests arrive at volume, or when you want your own support tooling to file them rather than a person filling in a form.

Intempt implements OpenDSR, so the request shape is portable across processors that support the same framework.

📘 Good to know

The API and the Privacy Center act on the same requests. A request filed over the API appears on the Data subject requests tab, and one filed in the UI is visible to the API. See Managing DSR for the UI walkthrough.

Authentication

Every DSR endpoint takes the same Bearer token as the rest of the Intempt API. There's no separate privacy credential to generate or rotate.

Authorization: Bearer <JWT>

All endpoints are nested under /v1/{orgName}/projects/{projectName}, so a request is always scoped to one project. See API Keys.


Create a request

POST /v1/{orgName}/projects/{projectName}/requests

Request Body

FieldTypeRequiredDescription
regulationstringYesgdpr or ccpa
subject_request_typestringYesaccess, erasure, or portability
subject_identitiesarrayYesAt least one identity for the data subject
subject_identities[].identity_typestringYesemail, mobile_number, or master_id
subject_identities[].identity_valuestringYesMust match the format implied by the type
subject_identities[].identity_formatstringYesAlways raw
api_versionstringYes2.0

Examples

Erasure request by email

{
  "regulation": "gdpr",
  "subject_request_type": "erasure",
  "subject_identities": [
    {
      "identity_type": "email",
      "identity_value": "dana.whitfield@northbay.io",
      "identity_format": "raw"
    }
  ],
  "api_version": "2.0"
}

Access request by Master ID

{
  "regulation": "ccpa",
  "subject_request_type": "access",
  "subject_identities": [
    {
      "identity_type": "master_id",
      "identity_value": "614829301174820993",
      "identity_format": "raw"
    }
  ],
  "api_version": "2.0"
}

Responses

200 OK

Responses are HAL+JSON, so they also carry a _links object alongside the fields below.

{
  "subject_request_id": "792318291839823872",
  "subject_request_type": "erasure",
  "regulation": "gdpr",
  "submitted_time": "2026-08-27T10:30:00Z",
  "subject_identities": [
    {
      "identity_type": "email",
      "identity_value": "dana.whitfield@northbay.io",
      "identity_format": "raw"
    }
  ],
  "api_version": "2.0",
  "status": "pending",
  "results_url": null
}

📘 Good to know

subject_request_id is a 64-bit Snowflake ID and is serialized as a string, because it exceeds what a JavaScript number can hold precisely. Don't parse it as a number.

Filing for many users at once

Send up to 2,000 identities in a single request. Every identity in the batch gets the same regulation and request type.

{
  "regulation": "gdpr",
  "subject_request_type": "erasure",
  "subject_identities": [
    { "identity_type": "email", "identity_value": "dana.whitfield@northbay.io", "identity_format": "raw" },
    { "identity_type": "email", "identity_value": "marcus.oduya@northbay.io", "identity_format": "raw" },
    { "identity_type": "master_id", "identity_value": "614829301174820993", "identity_format": "raw" }
  ],
  "api_version": "2.0"
}

The Privacy Center accepts the same volume as a CSV upload, one identity per row, for teams who'd rather not script it.

CCPA disclosure types

CCPA distinguishes three kinds of disclosure. Set disclosure_type on a CCPA request to answer one of them specifically:

ValueReturns
dataEverything held about the person. The default
categoriesThe categories of data held, without the values
sourcesWhere the data was collected from
{
  "regulation": "ccpa",
  "subject_request_type": "access",
  "disclosure_type": "categories",
  "subject_identities": [
    { "identity_type": "email", "identity_value": "dana.whitfield@northbay.io", "identity_format": "raw" }
  ],
  "api_version": "2.0"
}

GDPR requests ignore this field, because GDPR doesn't make the distinction.

📘 Good to know

A CCPA export returns everything Intempt holds, not just the previous twelve months. The twelve-month lookback in the statute is a minimum, and returning more of the person's own data to them is always compliant.


List requests

GET /v1/{orgName}/projects/{projectName}/requests

With no query parameters, returns every non-deleted request for the project.

Query Parameters

ParameterTypeRequiredDescription
requestIdlongNoReturn a single request by ID
regulationstringNoFilter by gdpr or ccpa
typestringNoFilter by access, erasure, or portability
startTimedateNoSubmitted on or after this date, yyyy-MM-dd
endTimedateNoSubmitted on or before the end of this date, yyyy-MM-dd

Examples

Every erasure request filed in August

GET /v1/acme/projects/production/requests?type=erasure&startTime=2026-08-01&endTime=2026-08-31

Check status

GET /v1/{orgName}/projects/{projectName}/requests/{requestId}

Responses

200 OK

{
  "subject_request_id": "792318291839823872",
  "controller_id": "1",
  "expected_completion_time": "2026-08-27T10:30:00Z",
  "request_status": "completed",
  "results_url": "https://api.intempt.com/v1/acme/projects/production/requests/792318291839823872/results",
  "api_version": "2.0"
}

Response Fields

FieldTypeDescription
subject_request_idstringThe request's ID
controller_idstringIdentifier of the data controller that filed it
expected_completion_timestringThe submission time. Processing begins immediately, so this is not a future deadline; it holds the moment the request was received
request_statusstringCurrent status, for example pending or completed
results_urlstringDownload URL for access and portability results. null until results exist
api_versionstring2.0

Download results

GET /v1/{orgName}/projects/{projectName}/requests/{requestId}/results

Streams the results file through the service, with a Content-Disposition: attachment header. The download takes the same Bearer token as every other endpoint, and the URL doesn't expire. Object storage itself is internal and is never exposed to callers.

Returns 404 when the request doesn't exist for your org and project, when results aren't ready yet, or when the stored file is missing.


Cancel a request

DELETE /v1/{orgName}/projects/{projectName}/requests/{requestId}

Marks the request record deleted in the console. It does not stop an erasure. Erasure begins on receipt and the deletion work runs downstream independently, so this removes the request from your list without recalling anything — the service's own documentation states that once a deletion request is created it cannot be undone. Use it to tidy a record, never as a way out.

Responses

200 OK

{
  "subject_request_id": "792318291839823872",
  "controller_id": "1",
  "expected_completion_time": null,
  "received_time": "2026-08-27T11:00:00Z"
}

Discovery

GET /v1/discovery

Returns what this OpenDSR implementation supports. This is the only DSR endpoint that takes no authentication, so a partner can read your processor's capabilities without credentials.

Responses

200 OK

{
  "api_version": "2.0",
  "supported_identities": {
    "identity_type": "email, mobile_number",
    "identity_format": "raw"
  },
  "supported_subject_request_types": ["ACCESS", "ERASURE", "PORTABILITY"],
  "processor_certificate": "https://static.intempt.com/dsr/opendsr_cert.pem"
}

Errors

StatusCause
400Validation failure. The body carries a structured errors array
401Missing or invalid JWT
403The request belongs to a different organization
404Request not found for this org and project
500Unexpected error. No detail is returned

400 example

{
  "errors": [
    { "message": "The regulation and the type of the request must be declared." }
  ]
}

Use cases

  1. Your support desk files erasure requests automatically when a ticket is tagged, instead of a person opening the Privacy Center.
  2. A monthly compliance report counts requests by type and regulation using startTime and endTime.
  3. Your own admin tool polls status and emails the requester when request_status reaches completed.
  4. A request was filed against the wrong identity, and support clears the record from your tooling — the erasure itself has already run and cannot be recalled.
  5. A partner verifies Intempt's OpenDSR capabilities and processor certificate before signing off on a data flow.
  6. An access request completes and your tool fetches the results file to hand to the requester directly.
  7. You reconcile requests filed in the UI against your own ticket system by listing everything for a date range.

Where to go next

On this page