Sending contracts for signature

Quotes and contracts are the same underlying record type in The Contractor Codex (a "Contract" with a kind field of quote, agreement, or change_order). Quotes are pricing offers; agreements are the long-form legal contracts.

This page covers sending an agreement-type contract.

Where contracts live

  • List: /admin/contracts — every contract you've sent, with filters by status, type, and signing provider.
  • Templates: /admin/contracts/templates — reusable contract bodies you can spin up per client.
  • Detail: /admin/contracts/<id> — the contract's full state: signers, audit log, attached PDF artifacts.

Creating a contract

Three paths:

From a template

If you've built a template (MSA, NDA, service agreement) for the contract bodies you send often, click New from template on /admin/contracts/templates. Pick the template, attach a client, fill in the merge fields (client name, signing date, etc.), and send.

From scratch

Click New Contract at the top of /admin/contracts. Pick the client, write the body inline (markdown supported), add signers, and send.

From an accepted quote

When a client accepts a quote and you want to follow up with a full agreement, open the contract page and click Convert to agreement — the line items + client + project are pre-filled into a new agreement-kind contract for you to add legal copy to.

Signers

Every contract has at least one signer (the client). You can add:

  • A co-signer, another person on the client side who also needs to sign.
  • A witness, typically a neutral third party.
  • A company signer (you), automatically populated at compose time using your saved signature.

For multi-signer flows, see Multi-signer workflows.

Pre-signing (your signature goes out with the contract)

Your signature is applied to every outgoing quote and agreement at the moment you click Send. The recipient opens a document that's already authorized by your side, and their signature becomes the only one needed to finalize it.

This means you don't have to do a separate "countersign" step after the client signs. As soon as they accept, the contract moves to signed and the final PDF is ready.

What you need to do once: save a signature at Settings → Signatures. After that, every outgoing quote and agreement uses it automatically. Both composers (quote and agreement) also have a signature pad in their UI so you can override the mode (typed vs drawn) per send if you want a different look on a specific document. The quote composer's pad is a sticky card on the right side under the Quote total; the agreement composer's pad is in the Review step before send.

The Send button is gated on a captured signature. You can't accidentally send an unsigned contract from the UI. If you switch to Typed mode with an empty name field, the button stays disabled until you fill it in.

Three exceptions where pre-sign doesn't fire:

  1. Change orders. They amend a parent contract that's already signed; the parent's signatures carry the legal weight. The Sign as company pad isn't shown when you select Change Order from the composer.
  2. MCP-sent contracts when the API key's owner has no saved signature. The send still goes through, but the response includes a warning string and the contract lands in awaiting_countersign after the customer signs. Save a signature once and future MCP sends ship pre-signed. See MCP server for the agent-side details.
  3. Pre-rollout contracts. Anything sent before the pre-sign rollout that's still sitting in awaiting_countersign can still be manually countersigned from the contract detail page.

Per-admin signatures. Each admin has their own saved signature (scoped to their Clerk user ID). Whichever admin clicks Send is the one whose signature gets stamped on that contract.

The signing flow

When you click Send:

  1. Your signature is stamped on the contract. A ContractSigner row with role="company" and status="completed" is created, the signature PNG uploads to storage, and ContractFieldValue rows are written for the company signature + date fields. All in one transaction; if it fails, the contract doesn't send.
  2. Each signer gets an email with a unique signing link (/contracts/sign/<token> for agreements, /quotes/<token> for quotes).
  3. The client clicks the link and lands on the signing page, branded and mobile-friendly. The PDF shows your signature already in place; the client column shows their printed name with a "Pending — accept via the link in this email" placeholder and an "Awaiting your acceptance" header at the top of the signature block.
  4. They review the contract body, type their name or paste a saved signature, and sign.
  5. Status moves to signed. The header on the PDF flips to "Signed and accepted" with both signatures filled in. Both parties get a copy emailed and the PDF is saved to the client's Documents tab.

What if I really do need a countersign step?

Some teams want the old "client signs, partner reviews, partner countersigns" workflow on purpose. Two ways to land there:

  • Don't save a signature on the admin account that's sending. Without a saved signature the UI Send button stays disabled, but contracts created and sent via MCP or the agent API will ship unsigned. They land in awaiting_countersign after the client signs and a different admin can countersign from the contract detail page.
  • Use the legacy countersign flow. Pre-rollout contracts that are sitting in awaiting_countersign still work the old way. The countersign UI on the contract detail page is unchanged for those.

See Multi-signer workflows for the use cases that warrant this and the per-template requiresCountersign flag's role (informational only — pre-sign at send time bypasses it).

Signing methods

On the signing page, the client picks one:

  • Type — type their name; the portal renders it in a cursive script for the signature.
  • Draw — sign with mouse or finger on a canvas. The drawn signature is saved as a PNG.
  • Use saved signature — if they've signed before and saved their signature, it's pre-loaded.

The signed PDF embeds the actual drawn or saved signature image, not just the typed name.

The audit trail

Every signature is captured with:

  • Timestamp (server-side, UTC)
  • IP address
  • User-agent string
  • A SHA-256 hash of the contract body at the moment of signing (signedBodyHash)
  • A SHA-256 hash of the signing token

When you mark a contract as signed, the portal generates two PDFs:

  • Signed PDF — the contract with all signatures embedded.
  • Audit PDF — a separate document listing every signer, timestamp, IP, UA, and hashes. Use this for legal disputes.

Both PDFs are downloadable from the contract detail page and are saved to the client's Documents tab.

Resending

If a signer hasn't acted in a few days, click Resend on the contract detail page. The signer gets a fresh email with the same signing link. The original link continues to work — no token rotation.

Voiding

If you need to pull back a contract, click Void on the detail page. Status moves to voided. The hosted signing page shows "This contract was voided." Voided contracts are kept in your list under the Closed filter.

Multi-org client switching

If a single client signs in to portals for more than one org, contracts follow them — they'll see all signed agreements across orgs in their dashboard, scoped per org.