Zapier
Validate documents in Zapier with Webhooks by Zapier (JSON with file_url) or Code by Zapier (base64), filter by verdict and receive events with Catch Hook.
Zapier needs no dedicated connector to use Constaia: the Webhooks by Zapier action sends the request to the API and the Catch Hook trigger receives events. If the file isn't at a downloadable URL, Code by Zapier can convert it to base64.
Prerequisites
- A Zapier account with access to Webhooks by Zapier (and Code by Zapier if you use the code option). Check what your plan includes.
- A test key
ck_test_…from the dashboard. See Authentication. - A previous step that provides the document: a Gmail attachment, a Google Drive file, a form (Typeform,
Jotform…). Zapier usually exposes files as a downloadable
https://URL.
Option 1: Webhooks by Zapier with file_url
Add the Custom Request action
Add Webhooks by Zapier with the Custom Request event (it lets you write the full JSON, with nested objects):
| Field | Value |
|---|---|
| Method | POST |
| URL | https://api.constaia.com/v1/analyze |
| Data Pass-Through? | False |
| Headers | Authorization → Bearer ck_test_… · Content-Type → application/json |
Write the body
In Data write the JSON and insert values from previous steps where needed (the file URL, its name, the holder's name…):
{
"file_url": "https://files.example.com/uploads/dni.jpg",
"filename": "dni.jpg",
"options": {
"expect": ["es_dni", "es_nie", "passport"],
"checks": { "min_age_years": 18, "holder": { "full_name": "María García López" } },
"language": "en",
"metadata": { "source": "zapier" }
}
}file_url must be https, with no private IPs, up to 20 MB and downloadable within 15 s. filename replaces the
name Constaia derives from the URL (handy in test mode). All options are in POST /v1/analyze.
If you don't need nested objects, the POST event with Payload Type json also works: the API accepts options
at the root of the body (file_url, filename, expect, language…).
Filter or branch by verdict
Zapier flattens the response into fields such as Verdict Status, Verdict Reasons Message or
Fields Document Number Value. Use Filter by Zapier to continue only on valid, or Paths by Zapier for
three branches:
| Branch | Condition | What to do |
|---|---|---|
| Válido | Verdict Status (Text) Exactly matches valid | Store data, approve |
| No válido | … Exactly matches invalid | Reply to the user with the verdict.reasons messages |
| Revisar | … Exactly matches review | Create a human review task |
If the analysis takes longer than 30 s (long PDFs), the API responds 202 with status: "queued" or
"processing" and no verdict: filter on Status = completed or use "async": true and the webhook (below). What
each status means is in Verdicts.
Option 2: Code by Zapier (base64)
If the previous step doesn't give you a URL Constaia can download (for example, it requires your session), download
the file in a Code by Zapier → Run JavaScript step and send it as file_base64.
In Input Data define file_url (the file from the previous step), file_name and api_key, and use:
const file = await fetch(inputData.file_url);
if (!file.ok) throw new Error(`Could not download the file: ${file.status}`);
const base64 = Buffer.from(await file.arrayBuffer()).toString("base64");
const res = await fetch("https://api.constaia.com/v1/analyze", {
method: "POST",
headers: {
Authorization: `Bearer ${inputData.api_key}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
file_base64: base64,
filename: inputData.file_name,
options: { expect: "payment_receipt", checks: { expected_amount: 45 } },
}),
});
const analysis = await res.json();
if (!res.ok) {
throw new Error(`${analysis.error.code}: ${analysis.error.message} (${analysis.error.request_id})`);
}
return {
id: analysis.id,
status: analysis.status,
verdict: analysis.verdict?.status ?? null,
reasons: (analysis.verdict?.reasons ?? []).map((r) => r.message).join(" | "),
amount: analysis.fields.amount?.value ?? null,
};Return only what later steps use. Code steps have a maximum run time that depends on your Zapier plan; if your
documents are long PDFs or the analysis gets close to that limit, use async: true and receive the result by
webhook.
The api_key value in Input Data is stored in the Zap and visible to anyone who can edit it. Don't use a
ck_live_… key in shared Zaps; restrict who can edit the Zap.
Test in test mode
With a ck_test_… key no credits are used and the response depends on the file name (the file must be a real
JPEG, PNG, WEBP, HEIC or PDF). In the JSON body set "filename" to one of these names:
filename | With expect: "es_dni" |
|---|---|
dni_valid.jpg | Válido |
dni_expired.jpg | No válido (not_expired, severity error) |
blurry.jpg | Revisar (low_quality, severity warning) |
For option 2 test with payment_receipt.pdf and expected_amount: 45. All scenarios in Test mode.
Receive events with Catch Hook
Create the trigger
Create a new Zap with Webhooks by Zapier → Catch Hook and copy the URL. Register it in the dashboard or through the API:
curl https://api.constaia.com/v1/webhook-endpoints \
-H "Authorization: Bearer $CONSTAIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://hooks.zapier.com/hooks/catch/…","events":["analysis.completed","analysis.failed"]}'Run an analysis with "async": true so Zapier receives a sample event (type, created_at, data).
Read the analysis again
Catch Hook doesn't let you verify the HMAC signature of webhooks, so don't trust the event
content. Add a Filter checking that Data Id starts with an_, then a Webhooks by Zapier → GET action (or
Custom Request with GET):
| Field | Value |
|---|---|
| URL | https://api.constaia.com/v1/analyses/ + Data Id |
| Headers | Authorization → Bearer ck_test_… |
Decide based on that response, which comes from the API with your key. The API only returns analyses of your account, so a forged event can at most make you re-read one of your own analyses.
Be idempotent
Constaia retries deliveries that don't get a 2xx for about 3 days, and Catch Hook may receive the same event more
than once. Before creating records, check in your destination (sheet, CRM, database) whether that Data Id was
already processed.
The re-read needs the analysis to still be stored: don't use keep_results: false on analyses you want to receive by
webhook.
Security
- Never paste a
ck_live_…key into shared Zaps or templates. Anyone who can edit the Zap can see headers and Input Data. - Build and test the Zap with a test key; switch to the live key when you turn it on.
- Zapier keeps each run's data in the Zap history. Keep that in mind with identity documents. More in Storage and privacy.
Limits
- 20 MB per file; PDFs up to 30 pages synchronously and up to 200 with
async: true. - 2 requests per second per key on the free plan (10 on paid); on a 429 honour
Retry-After. For many files at once use batches. See Rate limits.
Next steps
Make
Validate documents in Make with the HTTP module using multipart/form-data, route by verdict with a Router and receive Constaia events by webhook.
Power Automate
Validate SharePoint or OneDrive documents with the Power Automate HTTP action, read the response with Parse JSON and receive Constaia events.