Evidence and certificates
Somebody disputing a signature three years from now does not get a database. They get a PDF and a claim.
When a document completes, a certificate is issued: the document and its hash, every signer with the method and value of their signature, and the whole event chain with the address, the browser, the language and the device at each step. It is frozen at issue and hashed.
Frozen, and checked against the live record
Freezing sounds like the wrong instinct — a derived value that has drifted is the one somebody quotes. But a certificate is evidence, and evidence says what was true at a moment. Deriving it later means the document somebody holds and the document we render can differ with nothing to compare.
So both properties are kept. The payload is frozen and hashed at issue, and verification re-derives it from the live record and reports any divergence:
{
"certificate_found": true,
"document_matches": true,
"still_matches_record": false,
"divergence": "The document text has changed since this certificate was issued."
}
A divergence is a finding, not a correction. We report it and change nothing. A verification service that quietly re-derived would be unable to answer the one question it exists for.
What the signer was told, and how the link reached them
A certificate does not only say that consent was given. For each
signer it carries the consent disclosure in the words that were on the page,
with its SHA-256 and a version reference (consent/1, plus the
template's own consent wording when the business wrote one), the address and
browser the agreement came from, and the statement that stood above the
signature, hashed and versioned the same way. What the person agreed to is on
the record, not reconstructed from a later copy of the page.
Each signer also carries an assurance level: what the signature proves about who was at the keyboard. None of these is an identity check, and the printed certificate says so in each case.
| Level | What it proves |
|---|---|
email_link | A link we emailed to this address was used: control of the inbox. |
sms_link | A link we texted to this number was used: control of the phone. |
email_otp / sms_otp | As above, and a one-time code sent to the same address or number was entered before consent: control of that inbox or phone at the moment of signing, not only when the link arrived. |
in_person | The signing was started by a tablet you paired, using that tablet's own credential: our record of which device opened it, not anything the signer's browser said. |
link | A link handed over some other way — a public form, a QR code, your own application — was used: possession of the link. |
The one-time code is a choice each business makes under Settings ("Ask
signers for a code"). It applies to signers a link was delivered to; somebody
signing at the counter is not asked. Over the API the step is
POST /v1/sign/{token}/code and /verify. Certificates
issued before these fields existed carry the times and addresses they always
did, and nothing invented.
ID Evidence
A business may ask the people it sends a link to for a photograph of a
government-issued ID, and optionally of themselves, after consent and
before the signature (Settings → "Ask signers for ID evidence"). The
image is resized on the way in, kept encrypted under a key derived for
that business, shown only to its team from the document's page (each
look is audited), and dropped after thirty days or with a redaction. The
certificate carries each capture by kind, SHA-256, type, size, time and
the words the person was told, with "verified": false beside
it and "not verified against anything" in print: it is evidence that
somebody held that ID up when they signed, not a verification of who they
are, and a certificate issued before the image is dropped still matches
its record after.
The sealed PDF
GET /v1/documents/{id}/pdf returns the certificate as a PDF
sealed with a detached digital signature (PAdES) and an RFC 3161 timestamp — over
the signature, not over the document, which is what lets a reader tell when
the seal was applied rather than when the file was made.
The seal is self-issued, and the PDF's last page says so. It proves the file has not changed since it was sealed: alter a byte and a reader reports the signature as broken. It does not prove who produced the file — no certificate authority stands behind it, and a reader will show the sealer's identity as unverified. Identity is established by the verification code and the record it points to, not by the seal. If a counterparty requires a seal that validates as trusted in Adobe Reader (an AATL certificate), ask; it is not something SignSealer sells today.
The evidence bundle
GET /v1/documents/{id}/bundle returns the same sealed PDF with
the evidence package printed after the audit trail: every message sent about
the document and whether it arrived, every webhook delivered to your systems,
what an AI review flagged before it was sent (when the business ran one, and
that it was sent anyway), and the record's state when the file was made —
voided, redacted, still matching. The package's SHA-256 is on the last page, so the JSON and the PDF
can be tied together if both are produced. One file, sealed as one, for an
insurer, an adjuster or a court; the JSON stays the machine-readable form and
is available before the document completes, when the bundle is not.
Public verification
Every certificate carries a sixteen-character code, printable and typable: no I, L, O or U, because those are the four that get mistyped as 1, 1, 0 and V. Anybody holding the document can check the certificate without an account: the code alone confirms it exists, who issued it, when it completed, how many signed and that the record still matches. Add the document's SHA-256 and, when it matches, the page names the signers and shows the trail. Email addresses are never on the public page; they are in the sealed PDF and your evidence package.
Ready to build? An API key takes a minute in the portal, and the free plan covers the first 25 agreements a month.
Get an API key