Jatobá
API Reference

Documents

Upload, import, list, download, verify, certificates, and timestamps

All routes require a Clerk Bearer token and are scoped to the active tenant.

The document object

{
  "id": "abc123xyz",
  "serialNumber": "JAT-7K2M9",
  "fileName": "contrato.pdf",
  "fileSize": 45023,
  "mimeType": "application/pdf",
  "sha256Hash": "a1b2c3...",
  "sourceType": "upload",
  "sourceUri": null,
  "screenshot": null,
  "onchainStatus": "registered",
  "onchainTxHash": "0x...",
  "onchainAttestationUid": "0x...",
  "onchainAt": "2026-05-01T12:01:00.000Z",
  "stacksStatus": "registered",
  "stacksTxId": "...",
  "stacksAnchoredAt": "2026-05-01T12:30:00.000Z",
  "consentGiven": true,
  "consentTimestamp": "2026-05-01T12:00:00.000Z",
  "createdAt": "2026-05-01T12:00:00.000Z",
  "published": false,
  "publishedAt": null,
  "acervoTitle": null,
  "acervoAuthor": null,
  "metadata": null
}

sourceType is one of upload, ipfs, fileverse, web-capture. screenshot is a presigned preview URL, only for web captures.

POST /api/documents/upload

Upload via multipart/form-data. Consent is mandatory (LGPD Art. 7º I) — send consent=true as a form field alongside the file. Max 250 MB, 10 req/min. In an organization, requires editor or higher.

curl -X POST https://jatoba-web3-production.up.railway.app/api/documents/upload \
  -H "Authorization: Bearer $CLERK_TOKEN" \
  -F "file=@contrato.pdf" \
  -F "consent=true"

201 — the document object. Anchoring on both chains starts in the background (onchainStatus/stacksStatus begin as pending). 400 missing file or consent, 403 insufficient org role.

POST /api/documents/import/ipfs

Fetches a file from the configured IPFS gateway, hashes it, and registers a reference-only record (sourceType: "ipfs") — the bytes are not copied to R2.

Body fieldTypeDescription
cidstring (required)Bare IPFS CID (v0 Qm... or v1 base32)
fileNamestringDisplay name, defaults to the CID
consentboolean (required)Must be true

201 document object · 400 invalid CID / missing consent · 413 over 250 MB · 502 gateway failure.

GET /api/documents

Lists the active tenant's non-deleted documents, newest first.

200{ "documents": [Document] }

GET /api/documents/:id

Single document. 403 when outside your tenant, 404 when missing.

200{ "document": Document }

PATCH /api/documents/:id/publish

Publishes/unpublishes a document on the tenant's public acervo feed. While publishing you may set curator copy — only fields actually sent are rewritten:

Body fieldTypeDescription
publishedboolean (required)Target state
titlestringAcervo display title (falls back to file name)
authorstringAcervo display author
metadatastringFree-form metadata string

200 { "document": Document } · 410 when LGPD-deleted. Requires editor+ in an org.

GET /api/documents/:id/download

Presigned download URL (5 min). R2 downloads force attachment disposition and a neutral MIME so stored XSS can't execute; IPFS imports resolve to a gateway URL.

200

{ "downloadUrl": "https://...", "sha256": "a1b2c3...", "expiresInSeconds": 300 }

410 when the document was deleted via LGPD (the hash stays on record).

GET /api/documents/:id/view

Presigned inline view URL for browser tabs. Safe types (PDF, PNG/JPEG/GIF/WebP, plain text) render inline with their real Content-Type; anything else falls back to forced attachment.

200{ "viewUrl": "https://...", "inline": true, "expiresInSeconds": 300 }

GET /api/documents/:id/verify

Compares a provided hash against the stored one.

Query paramTypeDescription
hashstring (required)SHA-256 to check

200

{
  "documentId": "abc123xyz",
  "serialNumber": "JAT-7K2M9",
  "hashMatches": true,
  "storedHash": "a1b2c3...",
  "providedHash": "a1b2c3..."
}

GET /api/documents/:id/certificate

Generates the notarization certificate (comprovante) PDF: QR code to the permanent EAS attestation, the SHA-256, the full web3 proof, and a compliance section. When the source is a PDF, every page is stamped "Notarized with Jatobá" and the certificate page is appended — the original file in R2 is never modified.

Query paramDescription
signed=1PAdES-sign the certificate (ICP-Brasil compatible) when a signing certificate is configured; falls back to unsigned otherwise

Returns application/pdf as an attachment. The X-Jatoba-Signed header is pades or none.

POST /api/documents/:id/timestamp

Requests an RFC 3161 trusted timestamp over the document's SHA-256 from the configured Time-Stamping Authority. Returns the DER token (application/timestamp-reply, .tsr attachment), verifiable with openssl ts -verify — independent proof of anteriority alongside the on-chain anchors.

503 when no TSA is configured · 502 when the TSA request fails. 10 req/min.

On this page