API reference

Validate a document

Authenticate with your API key, upload documents one-by-one or in batch, and receive complete, audit-ready ValidationReports. Every field, enum, error and warning is documented below.

Base URLhttps://api.sealium.eu
Prefer to start from working code?Clone the open-source Java / Spring Boot demo — single & batch validation and webhook verification, ready to run with Docker.

Authentication

Authenticate with your secret API key as a Bearer token. The key is created in your dashboard and shown once. The Free tier includes 100 validations a month — no credit card required.

Authorization: Bearer slm_live_...

The API key works on the developer API: /v1/validate, /v1/batch and /v1/reports. Account management (usage, keys, billing, webhook configuration) lives in the dashboard and authenticates with your account session, not the API key.

Create your first key
POST/v1/validate

Validates a single document and returns a ValidationReport. The document bytes are processed in memory and never stored — only the report is persisted.

Request

  • AuthAuthorization: Bearer slm_live_...
  • Content-Typemultipart/form-data

Body parameters

FieldTypeRequiredDescription
filebinaryrequiredThe document to validate. Max 50 MB. The format is detected automatically from the file's magic bytes — you never specify a type. Accepts PDF, ASiC-E, ASiC-S, KRX, XAdES, CAdES and JAdES.

There are no path or query parameters.

Example request

curl -X POST https://api.sealium.eu/v1/validate \  -H "Authorization: Bearer slm_live_..." \  -F "file=@contract.pdf"

Response

200 OK returns a ValidationReport. Fields that don't apply to a given document are omitted (the API uses JSON omit-null), so a typical PDF response is more compact than the full schema.

200 OK · application/json
{  "documentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",  "filename": "contract.pdf",  "format": "PDF",  "valid": true,  "documentIntact": true,  "validatedAt": "2026-06-01T20:00:00Z",  "signatures": [    {      "signatureId": "id-abc123",      "signerDn": "CN=Anna Schmidt, O=Example GmbH, C=DE",      "signerName": "Anna Schmidt",      "signingTime": "2026-06-01T10:00:00Z",      "claimedSigningTime": "2026-06-01T10:00:00Z",      "bestSignatureTime": "2026-06-01T10:00:01Z",      "signatureIntact": true,      "certValid": true,      "revocationOk": true,      "timestampValid": true,      "indication": "TOTAL_PASSED",      "subIndication": null,      "signatureLevel": "QES",      "signatureFormat": "PAdES_BASELINE_LT",      "certIssuerDn": "CN=EU Qualified CA G2, O=TrustProvider, C=EU",      "certNotBefore": "2024-01-01T00:00:00Z",      "certNotAfter": "2027-01-01T00:00:00Z",      "certExpiresInDays": 245,      "certExpiryWarning": false,      "timestamps": [        {          "type": "SIGNATURE_TIMESTAMP",          "productionTime": "2026-06-01T10:00:01Z",          "valid": true,          "issuerDn": "CN=Qualified TSA, O=TrustProvider, C=EU"        }      ],      "certChain": [        { "subjectDn": "CN=Anna Schmidt, ...", "trusted": false, "...": "..." },        { "subjectDn": "CN=EU Qualified CA G2, ...", "trusted": true, "...": "..." }      ]    }  ],  "signaturesCount": 1,  "validSignaturesCount": 1,  "validationSummary": {    "totalSignatures": 1,    "totalPassed": 1,    "totalIndeterminate": 0,    "totalFailed": 0,    "hasQualifiedSignature": true,    "allQualified": true  },  "pdfMetadata": {    "title": "Service agreement 2026",    "author": "Anna Schmidt",    "creator": "Microsoft Word",    "creationDate": "2026-05-15T08:30:00Z",    "modificationDate": "2026-06-01T09:55:00Z",    "encrypted": false,    "pageCount": 12  },  "lotlSummary": {    "loaded": true,    "lastRefresh": "2026-06-01T03:00:00Z",    "trustedListsCount": 31  },  "errorCode": null,  "errorMessage": null,  "warningCode": null,  "warningMessage": null,  "krxDocuments": null}

Batch validation

Validate many documents in one asynchronous job. Available on Business and above — lower tiers receive 403 FEATURE_NOT_AVAILABLE.

POST/v1/batch

Submits up to 50 documents (multipart field files, repeatable) and returns 202 Accepted with { jobId, status, totalItems } immediately. Validation runs in the background — poll the job until status leaves PROCESSING. As with single validation, document bytes are staged transiently and deleted when the job finishes; only the reports are persisted.

curl -X POST https://api.sealium.eu/v1/batch \  -H "Authorization: Bearer slm_live_..." \  -F "files=@contract.pdf" \  -F "files=@annex-a.asice" \  -F "files=@invoice.xml"
GET/v1/batch/{jobId}

Job status with per-item results. Each completed item carries a reportId — fetch the full report via GET /v1/reports/{id}.

200 OK · application/json
{  "jobId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",  "status": "PARTIAL",  "totalItems": 3,  "completedItems": 2,  "failedItems": 1,  "createdAt": "2026-06-10T09:00:00Z",  "finishedAt": "2026-06-10T09:00:41Z",  "items": [    {      "itemId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",      "filename": "contract.pdf",      "status": "COMPLETED",      "reportId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"    },    {      "itemId": "9b2f3c1d-2c5a-4b8e-9f0d-1a2b3c4d5e6f",      "filename": "annex-a.asice",      "status": "COMPLETED",      "reportId": "1c0d7e2a-4b6f-4f3a-8d9e-2f1a0b3c4d5e"    },    {      "itemId": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",      "filename": "invoice.xml",      "status": "FAILED",      "reportId": null,      "errorCode": "PARSE_ERROR"    }  ]}
FieldTypeDescription
jobIdstring · uuidUnique id of the batch job.
statusenum JobStatusPENDING → PROCESSING → COMPLETED, PARTIAL or FAILED. See below.
totalItemsintegerNumber of documents submitted in this job.
completedItemsintegerDocuments validated successfully so far.
failedItemsintegerDocuments that could not be processed.
createdAtstring · date-timeWhen the job was submitted.
finishedAtstring · date-time | nullWhen the job finished. null while still running.
itemsBatchJobItem[]One entry per submitted document. Omitted in the GET /v1/batch list view.

BatchJobItem

FieldTypeDescription
itemIdstring · uuidId of this document within the job.
filenamestringOriginal filename of the submitted document.
statusenumPENDING, PROCESSING, COMPLETED or FAILED.
reportIdstring · uuid | nullId of the resulting ValidationReport — fetch it via GET /v1/reports/{id}. null until completed or on failure.
errorCodestring | nullWhy this item failed (e.g. PARSE_ERROR). null unless status is FAILED.

status — JobStatus

ValueDescription
PENDINGJob accepted, waiting for a worker.
PROCESSINGDocuments are being validated.
COMPLETEDEvery document validated successfully.
PARTIALFinished, but some documents failed — check items[].errorCode.
FAILEDNo document could be processed.
GET/v1/batch

The 20 most recent jobs for your account — the same fields as the detail view, without items.

Reports

Every validation — single or batch — persists a ValidationReport you can retrieve later. Documents themselves are never stored.

GET/v1/reports

Paginated report list, newest first — metadata only.

Query parameters

FieldTypeDescription
pageintegerZero-based page index. Default 0.
sizeintegerPage size. Default 20, max 100.
qstringSigner-name search (Pro and above).
from / tostring · date-time | dateValidation time range, ISO-8601 — full datetime or plain date (2026-06-12 expands to start/end of day UTC, inclusive). Business and above.
validbooleanFilter by verdict (Business and above).
formatstringFilter by detected format (Business and above).

Response item

Returned as a standard Spring page: { content: [...], totalElements, totalPages, number, size }.

FieldTypeDescription
idstring · uuidReport id — use with GET /v1/reports/{id} for the full ValidationReport.
filenamestringOriginal filename of the validated document.
formatstringDetected document format (see FormatType enum).
validbooleanOverall validation verdict.
warningCodestring | nullNon-blocking finding, when present.
signaturesCountintegerNumber of signatures found.
hasQualifiedSignaturebooleantrue if at least one signature is QES.
createdAtstring · date-timeWhen the validation ran.
GET/v1/reports/{id}

The full ValidationReport — byte-for-byte the same object POST /v1/validate returns, documented in the schema section below. Unknown or foreign ids return 404 NOT_FOUND.

GET/v1/reports/export

CSV export (text/csv attachment, max 10,000 rows) of the filtered report list — same query parameters as the list endpoint. Available on Business and above.

curl
# Paginated list (metadata only)curl "https://api.sealium.eu/v1/reports?page=0&size=20" \  -H "Authorization: Bearer slm_live_..." # Full ValidationReport by idcurl https://api.sealium.eu/v1/reports/3fa85f64-5717-4562-b3fc-2c963f66afa6 \  -H "Authorization: Bearer slm_live_..." # CSV export (Business+)curl -OJ "https://api.sealium.eu/v1/reports/export?valid=false" \  -H "Authorization: Bearer slm_live_..."

The ValidationReport object

The full object graph returned by /v1/validate. Nested arrays — signatures, certChain, timestamps and krxDocuments — reference the object definitions below.

ValidationReportTop-level response.

FieldTypeDescription
documentIdstring · uuidUnique id assigned to this validation run.
filenamestringOriginal filename of the uploaded document.
formatenum FormatTypeDetected document format. See Enums.
validbooleantrue when every signature is TOTAL_PASSED and at least one exists. For KRX, true only if every sub-document is valid.
documentIntactbooleantrue when every signature's cryptographic hash still matches the document.
validatedAtstring · date-timeWhen validation ran (ISO-8601, UTC).
signaturesSignatureInfo[]One entry per electronic signature found in the document.
signaturesCountintegerTotal number of signatures found.
validSignaturesCountintegerNumber of signatures that passed (TOTAL_PASSED).
validationSummaryValidationSummaryAggregated totals across all signatures.
pdfMetadataPdfMetadata | nullPDF document metadata. null for non-PDF formats.
lotlSummaryLotlSummaryState of the EU List of Trusted Lists at validation time.
errorCodeenum | nullBlocking error code. Always accompanied by valid=false. See Enums.
errorMessagestring | nullHuman-readable description of the blocking error.
warningCodeenum | nullNon-blocking finding. valid may still be true. See Enums.
warningMessagestring | nullHuman-readable description of the warning, including the relevant dates.
krxDocumentsKrxDocumentReport[] | nullPer-sub-document reports. Non-null only for KRX containers.

SignatureInfo

FieldTypeDescription
signatureIdstringIdentifier of the signature within the document.
signerDnstringFull distinguished name of the signer's certificate.
signerNamestringCommon name (CN) extracted from the signer's certificate.
signingTimestring · date-timeBackward-compatible alias of claimedSigningTime.
claimedSigningTimestring · date-timeSigning time as claimed in the signature.
bestSignatureTimestring · date-timeProven signing time from a trusted timestamp. Falls back to the current time when no trusted timestamp exists — gate display on timestampValid.
signatureIntactbooleanCryptographic integrity of this signature.
certValidbooleanWhether the signing certificate was valid.
revocationOkbooleanWhether revocation checking (OCSP/CRL) passed.
timestampValidbooleanWhether a trusted timestamp was found and is valid.
indicationenumDSS result: TOTAL_PASSED, INDETERMINATE or TOTAL_FAILED. See Enums.
subIndicationstring | nullDSS sub-indication when not TOTAL_PASSED (e.g. NO_CERTIFICATE_CHAIN_FOUND).
signatureLevelenumeIDAS level: QES, AdESqc, AdES or unknown. See Enums.
signatureFormatstringETSI baseline format, e.g. PAdES_BASELINE_LT.
signaturePolicyIdstring | nullSignature policy identifier, when present.
commitmentTypeIndicationstring | nullCommitment type, when present.
signerLocationstring | nullDeclared signer location, when present.
certIssuerDnstringDistinguished name of the certificate issuer.
certNotBeforestring · date-timeCertificate validity start.
certNotAfterstring · date-timeCertificate validity end.
certExpiresInDaysinteger · int64Days until the signing certificate expires.
certExpiryWarningbooleantrue when the certificate is close to expiry.
timestampsTimestampInfo[]Timestamp tokens embedded in the signature.
certChainCertInfo[]Certificate chain from the signer up to a trust anchor.

TimestampInfo

FieldTypeDescription
typestringTimestamp type, e.g. SIGNATURE_TIMESTAMP or ARCHIVE_TIMESTAMP.
productionTimestring · date-timeWhen the timestamp token was produced.
validbooleanWhether the timestamp token is valid.
issuerDnstringDistinguished name of the timestamp authority.

CertInfo

FieldTypeDescription
subjectDnstringSubject distinguished name of this certificate.
issuerDnstringIssuer distinguished name.
notBeforestring · date-timeCertificate validity start.
notAfterstring · date-timeCertificate validity end.
trustedbooleantrue when this certificate is a trust anchor on a recognised trusted list.

ValidationSummary

FieldTypeDescription
totalSignaturesintegerTotal signatures examined.
totalPassedintegerSignatures with indication TOTAL_PASSED.
totalIndeterminateintegerSignatures with indication INDETERMINATE.
totalFailedintegerSignatures with indication TOTAL_FAILED.
hasQualifiedSignaturebooleantrue if at least one signature is QES.
allQualifiedbooleantrue if every signature is QES.

PdfMetadataPresent only when format is PDF.

FieldTypeDescription
titlestringDocument title from the PDF info dictionary.
authorstringDocument author.
creatorstringCreating application.
creationDatestring · date-timePDF creation date.
modificationDatestring · date-timePDF last-modification date.
encryptedbooleantrue if the PDF is encrypted. pageCount is then 0.
pageCountintegerNumber of pages (0 when encrypted).

LotlSummary

FieldTypeDescription
loadedbooleanWhether the EU LOTL was loaded for this validation.
lastRefreshstring · date-time | nullLast successful LOTL refresh. null if never loaded.
trustedListsCountintegerNumber of national trusted lists processed (~31). 0 only when loading failed.

KrxDocumentReportOne per sub-document for KRX containers.

FieldTypeDescription
documentIndexinteger1-based index of the sub-document inside the KRX container.
filenamestringFilename of the enclosed document.
formatstringDetected format of the sub-document.
validbooleanValidity of this sub-document.
documentIntactbooleanCryptographic integrity of this sub-document.
signaturesSignatureInfo[]Signatures found in this sub-document.
warningCodestring | nullPer-document warning, e.g. NO_SIGNATURES or CERTIFICATE_CHAIN_INVALID.
warningMessagestring | nullHuman-readable per-document warning.

Enums & codes

format — FormatType

ValueDescription
PDFPDF / PAdES signature.
ASIC_EASiC-E container (CAdES or XAdES inside).
ASIC_SASiC-S container.
KRXHungarian KRX multi-document container.
XADESXAdES (XML) signature.
CADESCAdES (CMS/PKCS#7) signature.
JADESJAdES (JSON) signature.
UNKNOWNFormat could not be detected.

signatureLevel

ValueDescription
QESQualified Electronic Signature — legal equivalent of a handwritten signature across the EU.
AdESqcAdvanced signature backed by a qualified certificate.
AdESAdvanced Electronic Signature.
unknownCannot be determined (e.g. LOTL not loaded, or INDETERMINATE result).

indication

ValueDescription
TOTAL_PASSEDThe signature is cryptographically valid and trusted.
INDETERMINATEValidity could not be fully established (e.g. missing revocation data or trust anchor).
TOTAL_FAILEDThe signature is invalid (e.g. hash mismatch).

errorCode blocking

Parsing or integrity failures that stop validation. Always accompanied by valid: false.

ValueDescription
NO_SIGNATURESThe document contains no electronic signature.
PARSE_ERRORThe document could not be parsed by the engine.
PREPROCESS_ERRORA KRX container could not be unpacked.
FORMAT_NOT_SUPPORTEDUnknown or unsupported format.
HASH_FAILURECryptographic integrity check failed.

warningCode non-blocking

Certificate-quality findings. valid may still be true — for example, an LTA-timestamped signature with an expired certificate stays TOTAL_PASSED.

ValueDescription
SIGNATURE_EXPIREDThe certificate expired. With a trusted timestamp the signature may still be valid at signing time.
SIGNATURE_NOT_YET_VALIDThe certificate was not yet valid at the claimed signing time.
REVOKEDThe certificate was revoked. If revocation came after signing, valid may still be true (INDETERMINATE).
CERTIFICATE_CHAIN_INVALIDThe certificate chain could not be built to a trusted root.
PARTIAL_VALIDATIONKRX only: some sub-documents are valid and some are not.
MULTIPLE_WARNINGSKRX only: more than one sub-document carries a warning.

warningMessage carries the human-readable detail with dates, e.g. “Certificate expired on 2021-07-12, but signature was valid at signing time (2019-09-22)”. When no trusted timestamp exists it instead notes that validity at signing time cannot be guaranteed.

Errors

Error responses use an ApiError body: { code, message, timestamp }.

StatusCodeWhen
400BAD_REQUESTMissing or empty file field.
401MISSING_API_KEYNo Authorization: Bearer slm_live_... header on /v1/validate.
401INVALID_API_KEYThe API key does not exist or has been revoked.
403FEATURE_NOT_AVAILABLEYour tier does not include this feature (e.g. batch or CSV export below Business).
404NOT_FOUNDReport or batch job not found, or it belongs to another account.
413FILE_TOO_LARGEFile exceeds the 50 MB limit.
429QUOTA_EXCEEDEDMonthly quota reached. Returns X-RateLimit-Remaining and X-RateLimit-Reset headers.
502ENGINE_UNAVAILABLEThe validation engine could not be reached.
503SERVICE_BUSYYour tier's concurrency limit is in use — retry shortly.

Ready to validate your first document?

100 free validations a month, every eIDAS format, no credit card.