Constaia
Use-case guides

Reuse settings with templates

Save in a template which documents you accept, what you check, what gets stored and when a person reviews, and use it with template in analyze, batches, links, sessions and dossiers. Examples in curl, JavaScript, PHP and Python.

If you validate the same kind of document from several places (the sign-up form, a batch process, the links your team sends), you'll end up repeating the same options on every call. A template stores them in Constaia:

  • your code only passes template: "tpl_…";
  • you change a rule (minimum age, certificate age, what goes to review) without deploying;
  • the dashboard, analytics and the review queue can filter by template.

In this guide you'll create a template for the ID of a registration form and use it in every flow. Full field reference: Templates.

Step 1: create the template

We want a valid Spanish ID, NIE or passport, from an adult; a person to confirm every rejection; to keep the original only while it waits for review (7 days at most); and never to store the full document number.

curl https://api.constaia.com/v1/templates \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Registration: identity document",
    "description": "Valid ID, NIE or passport of an adult.",
    "expect": ["es_dni", "es_nie", "passport"],
    "checks": { "not_expired": true, "min_age_years": 18 },
    "storage": "review",
    "review_max_days": 7,
    "review_retention_hours_after_decision": 0,
    "mask_fields": ["document_number", "mrz"],
    "retention_days": 365,
    "review": { "auto_approve_valid": true, "require_human_for": ["review", "invalid"] }
  }'

You can also create it in the dashboard, under Templates, and copy its id. The account already comes with five example templates (adult Spanish ID, sports medical certificate, sexual offences certificate, bank transfer receipt and invoice) you can use as a starting point.

OptionWhat it achieves
expect + checksAn invalid verdict if the document isn't one of those types, has expired or the holder is a minor.
review.require_human_for: ["review", "invalid"]Doubtful ones and rejections wait until someone decides (verdict.final_status).
storage: "review" + review_max_days: 7 + review_retention_hours_after_decision: 0The original is stored encrypted only while it waits for review, 7 days at most, and deleted on decision.
mask_fieldsThe document number is stored as 12****78Z (validation uses the full one).
retention_days: 365Results are deleted automatically after a year.

Step 2: analyse with the template

Pass template and, if needed, each request's own options. Here we add the expected holder, which depends on the user: checks is merged with the template's key by key.

curl https://api.constaia.com/v1/analyze \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -F "file=@dni_valid.jpg" \
  -F 'options={
    "template": "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2",
    "checks": { "holder": { "full_name": "María García López" } },
    "metadata": { "registration_id": "4821" }
  }'

The request's options win over the template. For example, "storage": "none" on a given request doesn't keep the original even if the template says review, and "checks": { "min_age_years": 16 } only changes the minimum age. The analysis returns template_id so you know which setup judged it.

Step 3: use it in the other flows

The same template works at every entry point:

Batch: common to every file
curl https://api.constaia.com/v1/batches \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -F "files[]=@dni_1.jpg" -F "files[]=@dni_2.jpg" \
  -F 'options={"template":"tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2"}'
Verification link: the person uploads from their phone
curl https://api.constaia.com/v1/verification-links \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template": "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2", "reference": "registration-4821", "notify_email": "maria@example.com" }'
Session: the browser uploads directly with a pk_ key
curl https://api.constaia.com/v1/sessions \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template": "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2", "reference": "user_42" }'
Dossier: the template applies to every document
curl https://api.constaia.com/v1/dossiers \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "template": "tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2", "reference": "registration-4821" }'

In links, sessions and dossiers, if you don't send documents (or requirements), a single document is requested (key: "document") with the template's expect. If you send several, each one can have its own expect and checks, applied on top of the template. More in Verification links, Sessions and Dossiers.

Step 4: tune it without deploying

Change the template from the dashboard or with PATCH. It only affects analyses created afterwards.

curl -X PATCH https://api.constaia.com/v1/templates/tpl_01J9Z8Q3K4M5N6P7Q8R9S0T1V2 \
  -H "Authorization: Bearer $CONSTAIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "checks": { "not_expired": true, "min_age_years": 16 } }'

PATCH replaces checks and review as a whole

checks and review are not merged with what was there: send the full object. A field set to null is removed from the template (then the request or the account decide).

To try a big change without touching the template in use, create a second template, send part of the traffic to each one and compare with GET /v1/analytics?group_by=template.

Verdict without expect

If the template doesn't set expect (for example, "any identity document the user uploads"), the verdict is computed against the detected type (verdict.basis: "detected"). If you'd rather have no verdict in that case, set verdict_without_expect: false on the template. See Verdicts.

Test it

With a ck_test_… key templates work the same and spend no credits. Analyse dni_valid.jpg (valid), dni_expired.jpg (invalid, left pending for review because of require_human_for) and blurry.jpg (for review) from the test files and look at review.status and storage.kept in each response.

Next steps

On this page