Constaia
Use-case guides

Analyze without storing

Data minimisation (GDPR) with Constaia. Analyze documents without keeping the file or the extracted data using storage none and keep_results false.

Often you only need an answer ("is this a valid ID of this person?") and you don't want the document or its data kept anywhere else. Constaia lets you analyze without keeping the file and, if you want, without keeping the results either. It's the simplest way to apply the GDPR data minimisation principle.

Three levels

What you wantOptionsWhat stays at Constaia
Don't store the filestorage: "none" (default)The analysis results (type, verdict, fields), until you delete it.
Store nothingstorage: "none" + keep_results: falseOnly usage and billing metadata.
Keep for a while, delete laterstorage: "temporary" or "persistent" + DELETE /v1/analyses/{id}Nothing after deletion.

storage: "none": the file is not stored

This is the default, unless you changed your account default in the dashboard (account settings).

  • Synchronous analysis (the usual case): the file is processed in memory and never written to storage.
  • Asynchronous analysis (async: true) and batches: the file is stored encrypted only while it's processed and deleted when it finishes.

The response records it in storage.file_deleted_at, which you can keep as evidence:

"storage": { "mode": "none", "file_deleted_at": "2026-09-29T10:00:02Z", "expires_at": null }

With storage: "none" the document's OCR text isn't kept either.

keep_results: false: the data isn't stored either

With keep_results: false you get the full result once, in the response, and Constaia doesn't store the extracted data (type, fields, checks, reasons). Afterwards:

  • GET /v1/analyses/{id} returns 404 resource_missing.
  • GET /v1/analyses/{id}/export also returns 404.
  • The analysis doesn't appear in API listings.
  • Only what's needed for usage and billing remains: pages, credits, document type and the verdict status.

Watch out for export and metadata

If you ask for export together with keep_results: false, the export files are still generated and stored encrypted until they expire after 24 hours. If you want nothing left, don't request exports: take the data from the response. And the metadata you send is stored with the analysis: use internal ids, not names or document numbers.

analyze-no-store.js
import { Constaia, ConstaiaError, NotFoundError } from "@constaia/sdk";
import { fromPath } from "@constaia/sdk/node";

const constaia = new Constaia(); // reads CONSTAIA_API_KEY

try {
  const analysis = await constaia.analyze(await fromPath("./dni_valid.jpg"), {
    expect: "es_dni",
    checks: { holder: { fullName: "María García López" } },
    storage: "none",
    keepResults: false,
    language: "en",
    metadata: { user_id: "u_8812" },
  });

  // Take what you need now: it won't be there later.
  const record = {
    analysisId: analysis.id,
    status: analysis.verdict?.status,
    checkedAt: analysis.completed_at,
    fileDeletedAt: analysis.storage.file_deleted_at,
  };
  console.log(record);

  await constaia.analyses.get(analysis.id); // throws NotFoundError
} catch (err) {
  if (err instanceof NotFoundError) console.log("Nothing is kept:", err.code); // resource_missing
  else if (err instanceof ConstaiaError) console.error(err.code, err.message, err.requestId);
  else throw err;
}

Use synchronous analysis with keep_results: false. If the analysis exceeds the 30-second wait and the API responds 202, the result can't be fetched later: it only reaches you through the analysis.completed webhook, so have it set up if you process long PDFs. See Webhooks.

Delete what you did keep

If you keep files or results for a while (for example with storage: "temporary" and ttl_hours for a human review, or persistent), delete them when you no longer need them. Deletion removes the file, the results and the exports:

delete.js
const deleted = await constaia.analyses.delete("an_01J...");
console.log(deleted); // { id: "an_01J...", object: "analysis", deleted: true }

With temporary, the file is deleted automatically once ttl_hours have passed (1 to 720; 24 by default). The response tells you when in storage.expires_at.

Account defaults

In the dashboard (app.constaia.com, account settings) you can set the default storage mode and TTL. They apply when a request doesn't send storage or ttl_hours. Even so, send storage: "none" explicitly in the code of sensitive flows: that way a change in the dashboard doesn't alter them. keep_results has no account default: it's true unless you send false.

What to store on your side

If Constaia keeps nothing, your record is the only trace of the check. Usually this is enough:

  • analysis.id as a reference (for support; it can't be used to retrieve data with keep_results: false).
  • verdict.status and the date (completed_at).
  • storage.file_deleted_at, as evidence that the file wasn't kept.
  • Only the fields your process really needs (for example the validated document number).

Where it's processed

Processing happens in the EU and the files that are stored are encrypted in the application before they reach storage. Details in Storage and privacy and Data residency.

If you also want the document to be processed only by providers headquartered and operated in the EU, add processing: "sovereign" to the options. The response carries the processing object with the profile, region and providers that handled it: store it next to your decision as evidence. See Data residency.

Test it

With a ck_test_… key, analyze dni_valid.jpg with storage: "none" and keep_results: false as in the example: the response contains the full result and storage.file_deleted_at, and the subsequent GET returns 404. More in Test mode.

Next steps

On this page