Developer guide · Professional Team and Corporate Studio
Machine-to-machine access without a single document leaving your machines
DOCSUPRA processes every document inside the browser of the workstation that holds it. There is no upload endpoint and there never will be. What your systems can integrate with is everything the organisation already records about its work: the audit log (identifiers or file names as your compliance mode dictates, SHA-256 hashes, verdicts, department, person, time), the hash-chain verification, the usage report, the compliance policy, and capture links your clients use to send photos straight to your desk. Three mechanisms: API keys, signed webhooks and the Integrity SDK.
1. Authentication
Send the key as a bearer token. Keys look like dvk_ followed by 40 hexadecimal characters; they are shown once at creation and stored hashed. Up to 10 keys per organisation; revoke any of them at any time.
curl https://api.docsupra.com/api/bitacora?mes=2026-09 \
-H "Authorization: Bearer dvk_0123abcd..." \
-H "Origin: https://docsupra.com"
2. Read endpoints
| Endpoint | What it returns |
|---|---|
GET /api/bitacora?mes=YYYY-MM | The month’s batches: id, date, type (auditoria, entrega, admin), department, destination, who, counts, sequence number and seal. |
GET /api/bitacora?mes=YYYY-MM&id=<id> | One batch with its rows: identifier or file name, source SHA-256, delivered SHA-256 (se) on delivery batches, verdict, reasons, integrity risk. |
GET /api/bitacora?mes=YYYY-MM&verifica=1 | Recomputes every seal of the month: verificados, roto (first altered batch, or null), huecos. |
GET /api/informe?mes=YYYY-MM | Downloads per person and per department, capture deliveries, members. |
GET /api/politica | The compliance mode in force (framework, mandatory log, pseudonyms, retention, idle clearing). |
POST /api/captura | Creates capture links for clients: body {"destino":"uscis","dep":"legal","org":"Firm","refs":["Case 1"]}. Your CRM can hand each client a link; the photos land on your desk, audited. |
Rate limits apply per organisation and per day. A revoked key answers 401; a key on a lapsed plan answers 403.
3. Signed webhooks
Set one HTTPS URL per organisation and choose the events: batch.recorded (a desk recorded an audit batch), batch.delivered (a ZIP was delivered, with the SHA-256 of every delivered file), admin.action (policy changed, keys created or revoked, log purged, webhook changed). Every delivery is a JSON POST:
POST https://your-system.example/docsupra
Content-Type: application/json
X-DOCSUPRA-Event: batch.delivered
X-DOCSUPRA-Signature: t=1758500000,v1=<hex HMAC-SHA256>
{"event":"batch.delivered","sent":"2026-09-21T22:40:00.000Z","organisation":"...",
"data":{"id":"mubtv1cu-hyi08a","fecha":"...","tipo":"entrega","de":"mubtu5nt-52p77u",
"depto":"legal","destino":"generic_pdf","quien":"owner","seq":3,"prev":"...","sello":"...",
"filas":[{"n":"doc-17619936d72d","sha":"...","se":"...","v":"delivered","m":"lease-agreement-generic_pdf.pdf","ir":""}]}}
Verify the signature
Compute HMAC-SHA256 with your webhook secret (whsec_dvp_…, shown once) over the string <t>.<raw body> and compare it in constant time with v1. Reject timestamps older than five minutes to defeat replays.
// Node.js
const crypto = require("crypto");
function verify(secret, header, rawBody) {
const t = header.match(/t=(\d+)/)[1], v1 = header.match(/v1=([a-f0-9]+)/)[1];
const expected = crypto.createHmac("sha256", secret).update(t + "." + rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1)) && Math.abs(Date.now()/1000 - t) < 300;
}
Delivery is best effort with a four-second timeout and no retries: your system can always reconcile by reading the log. The last delivery status is shown in the console.
4. Integrity SDK
The technical integrity analyser that runs on this site (EXIF, XMP, PNG chunks, PDF structure; risk level Low, Medium or High with the technical reasons) is served to your organisation as a JavaScript module so that it runs inside your browsers, for example in a client onboarding page. The file is never a document upload: it is code that runs on the file where the file already is.
const js = await fetch("https://api.docsupra.com/api/sdk/integrity.js", {
headers: { Authorization: "Bearer dvk_0123abcd..." } }).then(r => r.text());
new Function(js)(); // defines window.DVP_INTEGRIDAD
const result = await window.DVP_INTEGRIDAD.analizar(fileFromInput);
// { status:"success", analysis:{ riskLevel:"LOW"|"MEDIUM"|"HIGH", technicalReason, metadataFound }, detalle, legalDisclaimer }
The result wording never says fraud, fake or illegal: it states a risk level and technical facts, with the disclaimer that it is not a legal or expert opinion.
5. What this is not
- Not an upload API. DOCSUPRA has no endpoint that accepts a document, and adding one would break the promise the product is built on.
- Not a licence. A key cannot trigger
/api/export; downloads happen only on a person’s seat inside the studio. - Not an administrator. Keys, webhooks, compliance mode, members and purges are changed only by a signed-in administrator, and every such change leaves an
admin.actionentry in the same hash chain.