Skip to content

Extracting Parties and Signature Dates From an NDA

9 min read · updated August 11, 2026

A two-page NDA names its parties in at least three places, and those three places are typed by different people at different times. When they disagree, the disagreement is the finding — and picking the tidiest-looking version is the one response guaranteed to be wrong some of the time.

Three places, three answers

The preamble gives the parties with their legal form and often their jurisdiction of incorporation and address: “this Agreement is entered into by Northwind Traders, Inc., a Delaware corporation, and Contoso Analytics Ltd, a company registered in England and Wales”. The signature block gives the party name again, above a signatory’s printed name and title. The notices section gives the name a third time, with a postal address and often an attention line.

Each of the three is worth capturing separately, because each answers a different downstream question — who is bound, who signed, and where notice goes — and because their agreement or disagreement is itself a signal. Extracting a single parties array from whichever mention the model liked best discards the check.

The signatory is not the party. “By: /s/ J. Okonkwo, Title: VP Finance” identifies a human acting for an entity, and a record that lists the human as a party will produce nonsense the first time somebody searches for all agreements with a given counterparty. Keep party_name, signatory_name and signatory_title as three fields.

Reconciling entity names

Assume the three mentions differ, because they usually do in small ways. Normalise before comparing: case-fold, strip punctuation, collapse whitespace, and map the entity suffix to a canonical token so that “Inc.”, “Inc” and “Incorporated” compare equal, and likewise for Ltd, Limited, LLC, GmbH, B.V. and the rest. What remains after normalisation is the interesting part.

  • A residual character-level difference — “Northwind Traders” against “Northwind Trading” — is most likely a typo, and the correct output is both strings plus a mismatch flag. Do not pick one. Which one binds is a question for a person.
  • A different entity entirely — the preamble names a parent and the signature block names a named subsidiary — looks exactly like a typo to a string comparison and is materially different. Suffix and jurisdiction changes between mentions are the cheap tell: “Contoso Analytics Ltd” against “Contoso Analytics Pty Ltd” is not a spelling error.
  • A trading name. “Fabrikam Services LLC d/b/a Fabrikam Cloud” contains two names of which one is the legal entity. Store the legal name and the trading name in different fields; a downstream match against a customer master will otherwise fail on whichever one it did not expect.

The entity suffix and jurisdiction are worth their own columns for the same reason. “A Delaware corporation” in the preamble is the most reliable disambiguator in the document when two group companies share a trading name.

Why signature blocks decode wrongly

Signature blocks are set side by side, and that layout is where the text extraction fails before any model sees the content. A PDF text layer stores strings with coordinates in the order the generator wrote them, and a naive top-to-bottom read of a two-column block interleaves the columns line by line:

What the page looks like

  NORTHWIND TRADERS, INC.        CONTOSO ANALYTICS LTD
  By: ______________             By: ______________
  Name: J. Okonkwo               Name: R. Vasquez
  Title: VP Finance              Title: Director
  Date: 3 June 2024              Date: 28 May 2024

What a line-ordered text extraction can yield

  NORTHWIND TRADERS, INC. CONTOSO ANALYTICS LTD
  By: ______________ By: ______________
  Name: J. Okonkwo Name: R. Vasquez
  Title: VP Finance Title: Director
  Date: 3 June 2024 Date: 28 May 2024

Every field is now present twice on one line with no marker for which belongs to which party, and a model reading that will attach the fields to parties by guessing — correctly most of the time, which is worse than failing. The fix is not a better prompt. Cluster the text spans by x-coordinate into columns first, then read each column top-to-bottom, then extract. This is a general problem with a general answer; see two-column PDF reading order.

One diagnostic is nearly free: if the same label appears twice on one extracted line, the reading order is wrong for that region. Counting repeated Name: or Title: labels per line is a cheap detector for a column-merge failure and works without reference data.

Choosing the effective date

There are up to three candidate dates — a stated date in the preamble and one date per signature — and a precedence order that almost every agreement supports:

1. An express definition:
     "Effective Date means 1 May 2024"      -> use it
2. A preamble "as of" date:
     "made as of 1 May 2024"                -> use it
3. Otherwise, the latest signature date     -> use it
   (an agreement is generally not effective
    before the last party has signed)

effective_date_basis: stated | as_of | last_signature | ambiguous

A stated date earlier than both signatures is normal and is not an error to be corrected: parties agree to date an agreement as of the day their arrangement began. So a validation rule of “effective date must be on or after the signature dates” will fire constantly on perfectly ordinary documents. The rule worth having is the opposite shape: flag a large gap in either direction — more than a few months — because that is where backdating disputes and data-entry errors both live.

The ambiguous basis is for the common template that says “made as of ______, 2024” with the blank never filled in. There is no effective date. Falling back to the last signature date is usually the right operational choice, but the basis field must record that a fallback happened, because the two situations look identical in a date column and differ in whether anyone can rely on the number.

Handwritten and stamped dates

Scanned agreements put the dates in handwriting, and handwriting brings its own failures on top of the layout ones covered in handwriting recognition with an LLM. What to emit when the ink simply cannot be read is its own decision, worked through in handling an illegible field. Three cases are worth special handling:

  • Ambiguous numeric order. A handwritten 03/04/2024 is 3 April or 4 March depending on who wrote it, and the document rarely says. Where the day is 12 or lower and no other date in the document disambiguates, the honest output is a range or a flag, not a date. The counterparty’s address is a weak signal for the convention and should not be treated as proof.
  • Two-digit years and a scrawled century. A year that resolves before the incorporation date of either party, or after today, is a detectable error.
  • A date printed by an e-signature platform. Where an agreement was executed electronically, the certificate page appended by the platform typically carries the signer’s name, email and a timestamp with a timezone. That page is machine-set text, not handwriting, and it is usually the most reliable date in the file — but it records when the signature was applied, in whatever timezone the platform used, which is not necessarily the same calendar day as a handwritten date elsewhere on the document.
Executed agreements contain personal data: signatory names, sometimes personal addresses, sometimes an image of a signature. Where the pages are sent to a third-party model, that is a processing decision with contractual consequences, and the redaction question is best answered before the page leaves your infrastructure rather than after. See PII redaction.

What the extracted record looks like

Putting it together, a party record is not a string. It is an entity with provenance for each observation:

{
  "role": "receiving_party",
  "legal_name": "Northwind Traders, Inc.",
  "name_observations": [
    { "source": "preamble",        "value": "Northwind Traders, Inc." },
    { "source": "signature_block", "value": "NORTHWIND TRADERS, INC." },
    { "source": "notices",         "value": "Northwind Traders Inc" }
  ],
  "name_mismatch": false,
  "entity_type": "corporation",
  "jurisdiction": "Delaware",
  "signatory_name": "J. Okonkwo",
  "signatory_title": "VP Finance",
  "signature_date": "2024-06-03",
  "signature_date_source": "typed"
}

The observations array costs almost nothing and turns a silent disagreement into a queryable one. It also means a later change to the normalisation rules can be re-run over stored data instead of over the original PDFs.