How verification works
Every proposal signed on YesPage produces two files: the signed proposal and a certificate of completion. Each is hashed with SHA-256 the moment it is created, and neither is ever regenerated. The certificate prints the signed PDF's hash, the hash of the proposal content that every signer saw, and the full audit trail with a hash per event. This page describes the rules, so anyone can check a document without trusting us or our servers.
1. The signed PDF
Compute the SHA-256 of the file exactly as delivered. On a Mac or Linux: shasum -a 256 "Signed proposal.pdf". On Windows: certutil -hashfile "Signed proposal.pdf" SHA256. It must equal the value on the certificate under "Signed PDF SHA-256". Any change to the file, even re-saving it in a PDF tool, changes the hash.
2. The audit trail
Events are numbered from 1. For each event:
canonical = canonical_json({
proposal_id, sequence, event_type, actor_type, actor_id,
ip, user_agent, data, created_at
})
hash = SHA-256( prev_hash_bytes || utf8(canonical) )
prev_hash = hash of the event with sequence - 1; empty for sequence 1The certificate prints the first 16 hex characters of each hash and the full hash of the last event (the chain head). Change, remove, or reorder any event and every hash after it changes.
3. Canonical JSON
- Object keys sorted by UTF-16 code unit, recursively.
- No whitespace between tokens.
- Strings escaped as in RFC 8259 with lowercase hexadecimal escapes, as RFC 8785 specifies.
- Numbers are integers only. Money is in cents, rates in basis points. A non-integer is an error, never a hash input.
- Byte values (hashes) are lowercase hexadecimal strings.
- Timestamps are ISO 8601 in UTC with millisecond precision, for example 2026-09-10T14:03:22.418Z.
- null values are included. A missing field is an error, not an omission.
4. The content hash
When a proposal is sent it is frozen, and its canonical content is hashed: title, sender name, every block in order, every line item with quantity, price, tax and optional flags, the pricing settings, the expiry date, and the ordered list of signers. Image blocks contribute the SHA-256 of the image bytes. Each signature records this hash as the document the signer saw, and the certificate prints it.
5. What we do not claim
Hashes prove a file is unchanged since we produced it and that the audit trail is intact. They do not by themselves prove who a person is; that rests on the signer link sent to their email address, the consent they gave, and the IP and browser details recorded at signing, all of which the certificate lists.