Skip to main content

Compliance Checks

Loyva evaluates every envelope against the UCC §9-105 requirements below. All 8 checks must pass for full compliance — only a score of 100 means the envelope is compliant.

Each check returns a structured result:

interface UCC9105Check {
requirement: string; // Human-readable requirement
ucc_reference: string; // UCC citation
satisfied: boolean; // Pass/fail
detail: string; // Explanation with envelope-specific data
}

Check 1: Single authoritative copy

UCC §9-105(b)(2) — A single authoritative copy of the record exists that is unique, identifiable, and unalterable.

How Loyva evaluates:

  • Verifies envelopes.vault_file_path is set
  • The authoritative PDF is uploaded to the ucc-vault bucket with upsert: false, enforcing a single copy
  • The stored bytes include a UCC watermark so the file itself announces its authoritative status

Fails when: The signed document hasn't been stored in the vault yet.


Check 2: Tamper-evident record

UCC §9-105(b)(4) — The authoritative copy is stored with tamper-evident technology so any change is detectable.

How Loyva evaluates:

  • Verifies envelopes.document_hash contains a SHA-256 digest of the stored authoritative bytes
  • Hash is computed once at vault time and written atomically with the path
  • Hash is re-verified on every vault download and by the weekly cron job — results are appended to integrity_check_history

Fails when: No document_hash is stored.


Check 3: Controlling party identified

UCC §9-105(b)(1) — The authoritative copy identifies the person asserting control.

How Loyva evaluates:

  • Looks up custodian_permissions for the envelope with status = 'accepted'
  • The first such row is the active custodian (controlling party)
  • The queue worker auto-assigns the envelope creator as the initial custodian once the vault pipeline completes, so this check passes without manual action

Fails when: No custodian permission exists in accepted state (rare; only happens if auto-assignment was skipped).


Check 4: All required signatories executed

UCC §9-105(b)(3) — Every party required to sign the record has signed.

How Loyva evaluates:

  • Compares envelopes.submitters[].email (expected signers) with envelopes.signed_documents[].signer_email (actual signatures)
  • The check passes if every submitter has a matching signed document, or if there are no submitters recorded (paper uploads)

Fails when: One or more required signers haven't completed signing.

note

Per-signature hashes are captured on the signature image artifacts, but this check only verifies that each required signer is represented — not a separate per-signature hash value.


Check 5: Non-authoritative copies identifiable

UCC §9-105(b)(5) — Copies of the authoritative copy must be readily identifiable as copies.

How Loyva evaluates:

  • Verifies envelopes.copy_file_path is set and points into the ucc-copies bucket
  • Copies are uploaded separately from the authoritative file with a non_authoritative metadata flag

Fails when: No copy has been stored in ucc-copies.


Check 6: Electronic record fully executed

UCC §9-105 (general) — The record must actually be a complete, executed electronic record.

How Loyva evaluates:

  • Verifies envelopes.status is completed or vaulted
  • vaulted is a superset — it implies completed plus the authoritative copy has been stored

Fails when: The envelope is still pending, sent, or viewed.


Check 7: Audit certificate generated

UCC §9-105 best practice — An audit certificate accompanies the record for inspection.

How Loyva evaluates:

  • Verifies envelopes.vault_out_certificate_path is set
  • The certificate is a JSON document stored alongside the authoritative PDF in ucc-vault
  • It contains the full check results, signer timeline, document hash, issuer, secured party, and legal notices

Fails when: The certificate hasn't been generated yet (pipeline still running or failed).


Check 8: Secured party identified

UCC §9-105(b)(1) — The authoritative copy identifies the secured party / assignee.

How Loyva evaluates:

  • Verifies envelopes.secured_party is populated with a non-empty name
  • Structured object: { name, role?, address?, email?, identifier? }
  • Surfaced at the top level of the compliance certificate as secured_party

Fails when: secured_party is null or name is missing/empty.

Resolution: Populate secured_party when you create the envelope via POST /api/v2/partner/envelopes:

{ "secured_party": { "name": "First National Bank", "role": "secured_party", "address": "..." } }

API response example

The compliance evaluator is exposed via GET /api/v2/partner/envelopes/:id/compliance. The response wraps the result under data:

{
"data": {
"envelope_id": "env_x7k9m2p4q1w3",
"external_id": null,
"envelope_status": "vaulted",
"compliance": {
"compliant": true,
"score": 100,
"evaluated_at": "2026-04-11T10:17:00.000Z",
"missing_requirements": [],
"checks": [
{
"requirement": "Single authoritative copy",
"ucc_reference": "UCC §9-105(b)(2)",
"satisfied": true,
"detail": "Authoritative copy stored at: ucc-vault/org_abc/env_x7.../signed.pdf"
},
{
"requirement": "Tamper-evident record",
"ucc_reference": "UCC §9-105(b)(4)",
"satisfied": true,
"detail": "SHA-256 hash: a1b2c3d4..."
},
{
"requirement": "Controlling party identified",
"ucc_reference": "UCC §9-105(b)(1)",
"satisfied": true,
"detail": "Custodian: usr_abc (accepted 2026-04-11T10:16:30.000Z)"
},
{
"requirement": "All required signatories executed record",
"ucc_reference": "UCC §9-105(b)(3)",
"satisfied": true,
"detail": "All 2 required signature(s) present"
},
{
"requirement": "Non-authoritative copies identifiable",
"ucc_reference": "UCC §9-105(b)(5)",
"satisfied": true,
"detail": "Copy path: ucc-copies/org_abc/env_x7.../signed.pdf"
},
{
"requirement": "Electronic record fully executed",
"ucc_reference": "UCC §9-105 general",
"satisfied": true,
"detail": "Envelope status is vaulted"
},
{
"requirement": "Audit certificate generated",
"ucc_reference": "UCC §9-105 best practice",
"satisfied": true,
"detail": "Certificate: ucc-vault/org_abc/env_x7.../certificate.json"
},
{
"requirement": "Secured party identified",
"ucc_reference": "UCC §9-105(b)(1)",
"satisfied": true,
"detail": "Secured party: First National Bank"
}
]
}
}
}

Common failure scenarios

ScenarioFailing checksResolution
Signing just completed1, 2, 5, 7Wait for vault pipeline (usually < 30 seconds)
No custodian assigned3Normally auto-assigned on vault; use the custodian API if manual action is needed
Signer didn't complete4, 6Send a reminder or check signer status
Pipeline error1, 2, 5, 7Re-fetch the live score via GET /api/v2/partner/envelopes/:id/compliance once the pipeline has caught up
Secured party not set8Pass secured_party on POST /partner/envelopes when creating the envelope