E Signature logo

E Signature

Community
ericrisco
e-signature

Use when wiring an e-signature flow with DocuSign or Dropbox Sign — picking the SES/AES/QES legal tier, sending a PDF or template for signature, embedded signing, verifying signing webhooks, retrieving the signed PDF plus audit trail. NOT drafting contract text (that is `contracts`), NOT extracting fields from PDFs (that is `document-processing`).

Overview

Publisherericrisco
Repositoryrsc-harness
Skill namee-signature
Stars
239
Forks
24
Bundled files
5
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 5 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by ericrisco on GitHub. Read the source before you install it.

Installation

Install the E Signature AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/ericrisco/rsc-harness/tree/main/skills/e-signature
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/ericrisco/rsc-harness.git /tmp/rsc-harness
mkdir -p .claude/skills
cp -r /tmp/rsc-harness/skills/e-signature .claude/skills/e-signature
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable E Signature in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads E Signature on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so E Signature is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

e-signature

You are wiring a third-party signing API (DocuSign eSignature or Dropbox Sign, ex-HelloSign) into someone's app or backend. You take a PDF or template, define signers and fields, send it for signature, track status, react to completion via a verified webhook, and retrieve the signed PDF plus its audit trail.

Contract language — clauses, indemnity, liability — goes to ../contracts/SKILL.md; OCR, field extraction, or PDF splitting with no signing involved is ../document-processing/SKILL.md.

Decision: which legal tier do you need?

Pick the tier deliberately, before you write code: it decides which provider features you enable (ID Verification, SMS/access code, qualified signature), and getting it wrong leaves a signature that is hard to defend in court.

US law (ESIGN Act + UETA) has no tiers — e-signatures equal wet ink. The EU (eIDAS, and eIDAS 2.0 / Reg (EU) 2024/1183 in force since May 2024) defines three. A typed name (SES) is binding for most B2B in the US and EU, but a high-stakes EU document may need AES or QES. Map the document's stakes to a tier, then to a provider feature.

TierWhat it isWhen you need itProvider feature to enable
SES (Simple)Typed or drawn signature, basic intent + audit trailMost B2B: offers, NDAs, quotes, US contracts generallyDefault flow — just capture the signature + keep the audit trail
AES (Advanced)Uniquely linked to signer, identity-verified, tamper-evidentHigher-value EU contracts, regulated sectorsID Verification, SMS/access-code auth, signer authentication step
QES (Qualified)EU handwritten-equivalent EU-wide; qualified cert via a QTSPWhere law mandates it (some real-estate, gov, regulated finance)Qualified signature add-on through a Qualified Trust Service Provider

If the document is genuinely high-stakes or you are unsure whether a tier is legally mandated, escalate to a lawyer and to ../contracts/SKILL.md — you do not give legal advice. Detail and the court-admissibility checklist live in references/legal-tiers.md.

Decision: which provider?

Either is fine. Pick one and stay on it so you keep one consistent audit trail.

DocuSign eSignatureDropbox Sign (ex-HelloSign)
AuthOAuth 2.0 JWT Grant (RSA keypair, impersonation, one-time consent)API key (header bearer)
Core callcreate Envelopesignature_request/send
Node SDKdocusign-esign (9.0.0)@dropbox/sign (1.11.0) — replaces deprecated hellosign-sdk
EmbeddedclientUserId on recipient + recipient view URLsignature_request/create_embedded
Pricing postureseat/envelope, enterprise-leaningAPI: Essentials ~$75/mo (50+ requests, embedded signing included), Standard ~$250/mo annual (adds bulk send + higher volume), free test_mode
EU / QESmature QES + ID VerificationSES/AES focus; check current QES support

Auth & setup

Never commit keys. Read everything from env; the RSA private key lives in a secret store or a file path, never inline in source.

Point at the sandbox before prod, always — a live send is billable and emails a real human. DocuSign demo env is https://demo.docusign.net; Dropbox Sign uses test_mode: 1. Only non-test sends count against quota and reach signers.

Env varProviderHolds
DOCUSIGN_INTEGRATION_KEYDocuSignclient/integration key (GUID)
DOCUSIGN_USER_IDDocuSignGUID of the user being impersonated
DOCUSIGN_ACCOUNT_IDDocuSignAPI account ID
DOCUSIGN_PRIVATE_KEYDocuSignRSA private key (PEM) — from secret store
DOCUSIGN_BASE_PATHDocuSignhttps://demo.docusign.net/restapi in sandbox
DROPBOX_SIGN_API_KEYDropbox SignAPI key

DocuSign JWT Grant — five steps (full walk-through in references/docusign.md):

  1. Create the integration key + RSA keypair in the DocuSign admin console.
  2. Grant one-time consent: visit the consent URL once as the impersonated user (.../oauth/auth?response_type=code&scope=signature%20impersonation&client_id=...&redirect_uri=...).
  3. Request a JWT user token (scope: signature impersonation), signed with the RSA private key.
  4. Call /oauth/userinfo to discover the account's correct base path — do not hardcode the prod host while testing.
  5. Use the returned access token + base path for all API calls; refresh before expiry.

Dropbox Sign needs only the API key as a bearer credential — see references/dropbox-sign.md.

bash
# Bad: key in source, prod host while testing
const apiKey = "hs_live_abc123";          # committed secret
const base   = "https://www.docusign.net"; # prod during a test

# Good: from env, sandbox first
export DROPBOX_SIGN_API_KEY="$(op read op://vault/dropbox-sign/key)"
export DOCUSIGN_BASE_PATH="https://demo.docusign.net/restapi"

Send flow — DocuSign

The core object is an Envelope. status: "sent" sends immediately; status: "created" saves a draft. Anchor strings let you place tabs by text in the PDF instead of fixed coordinates.

javascript
import docusign from "docusign-esign";

const env = {
  emailSubject: "Please sign: Offer letter",
  documents: [{
    documentBase64: pdfBuffer.toString("base64"),
    name: "Offer.pdf", fileExtension: "pdf", documentId: "1",
  }],
  recipients: {
    signers: [{
      email: signer.email, name: signer.name,
      recipientId: "1", routingOrder: "1",
      tabs: { signHereTabs: [{ anchorString: "/sig1/", anchorYOffset: "-10" }] },
    }],
  },
  status: "sent", // "created" for a draft you send later
};

const api = new docusign.EnvelopesApi(apiClient); // apiClient configured with JWT token + base path
const result = await api.createEnvelope(accountId, { envelopeDefinition: env });
// store result.envelopeId — your handle for status, webhook correlation, and retrieval

For templates, send with templateId + templateRoles (prefilled tabs) instead of raw documents. Envelope/tabs anatomy and template send are in references/docusign.md.

Send flow — Dropbox Sign

The core call is signature_request/send (or signature_request/send_with_template). Keep testMode: true until you intend to spend a real request.

javascript
import * as DropboxSign from "@dropbox/sign";

const api = new DropboxSign.SignatureRequestApi();
api.username = process.env.DROPBOX_SIGN_API_KEY; // API key as username

const res = await api.signatureRequestSend({
  title: "Offer letter",
  subject: "Please sign",
  signers: [{ emailAddress: signer.email, name: signer.name, order: 0 }],
  files: [pdfBuffer], // or fileUrls
  testMode: true, // flip to false ONLY when going live
});
// store res.body.signatureRequest.signatureRequestId

send_with_template takes templateIds + signers mapped to template roles. Details and embedded creation are in references/dropbox-sign.md.

Embedded vs remote signing

  • Remote (default): provider emails the signer a link. Nothing extra to build.
  • Embedded (signer signs inside your own UI): DocuSign requires a clientUserId on the recipient, then you request a recipient view URL and iframe/redirect to it. Dropbox Sign uses signature_request/create_embedded + the embedded sign URL. Embedded signing is included from the Dropbox Sign Essentials API plan up (it is not a Standard-only feature) — but it still requires a paid API plan, not test_mode alone.

Webhooks / completion

A send is not done when status is sent — it is done when the signer completes and you have pulled the signed document AND its evidence (DocuSign Certificate of Completion, Dropbox Sign audit-trail PDF), retrieved and stored. Fire-and-forget is the most common bug here.

Verify the signature before you trust anything in the payload. The body is attacker-controllable until you have verified it.

  • DocuSign Connect: HMAC-signed; verify the X-DocuSign-Signature-1 header against the raw request body using your Connect HMAC key.
  • Dropbox Sign event callbacks: event_hash = HMAC-SHA256 of event_time + event_type, keyed by your API key.
javascript
import crypto from "node:crypto";

// Dropbox Sign: verify event_hash before processing
function verifyDropboxSign(event, apiKey) {
  const expected = crypto
    .createHmac("sha256", apiKey)
    .update(event.event.event_time + event.event.event_type)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(event.event.event_hash));
}

// On a verified completion event: retrieve BOTH artifacts, idempotently
async function onCompleted(requestId) {
  if (await alreadyHandled(requestId)) return;     // idempotency guard
  const signedPdf  = await api.signatureRequestFiles(requestId, "pdf");
  const auditTrail = await api.signatureRequestFiles(requestId, "pdf", { fileType: "audit" });
  await store(requestId, signedPdf, auditTrail);   // store IDs + bytes, never log bytes
  await markHandled(requestId);
}

For DocuSign, on the Completed envelope event call EnvelopesApi.getDocument for the signed PDF and for certificate to get the Certificate of Completion. HMAC verification code and Connect setup are in references/docusign.md.

Anti-patterns

Anti-patternWhy it is wrongDo instead
Processing a webhook payload without verifying the signatureAnyone can POST a fake completed eventVerify HMAC (X-DocuSign-Signature-1 / event_hash) on the raw body first
Trusting status from the request body you sentStatus lives with the provider, not your hopeRead status from the verified webhook or a status fetch
Sending from prod while still testingBills you and emails real people with test docsDocuSign demo.docusign.net; Dropbox Sign testMode: true
Logging full document/envelope bytes or signer PIILeaks the very PII the signature protectsLog provider IDs only; store bytes in a secret-aware store
Storing the signed PDF but not the audit trailSES is hard to defend in court without who/what/when/whereAlways pull the Certificate of Completion / audit-trail PDF too
Reusing one envelope/request to "retry" a sendDuplicates, double-bills, corrupts statusNew request per send; use an idempotency guard on completion
Hardcoding the API key / RSA private key in sourceSecret leak on first pushEnv vars + secret store; key file path, never inline
Skipping the legal-tier decisionShip a signature that is not legally adequatePick SES/AES/QES first; escalate high-stakes to a lawyer + ../contracts/SKILL.md

Verify

Run scripts/verify.sh <path-to-integration> against the code you produced. It greps the artifact (no live API call) for: webhook signature verification present and not a TODO, no hardcoded API key or BEGIN PRIVATE KEY, a sandbox/test_mode guard, and a completion path that retrieves the signed PDF + audit trail. It is read-only and exits 0 on a clean/empty target.

For data-protection touchpoints (consent, retention of signed docs + PII), flag them and route the policy writing to ../gdpr-privacy/SKILL.md. For non-signing inbound webhook infrastructure, see ../webhooks/SKILL.md.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the E Signature AI skill do?

Use when wiring an e-signature flow with DocuSign or Dropbox Sign — picking the SES/AES/QES legal tier, sending a PDF or template for signature, embedded signing, verifying signing webhooks, retrieving the signed PDF plus audit trail. NOT drafting contract text (that is `contracts`), NOT extracting fields from PDFs (that is `document-processing`).

Why use E Signature on TypingMind?

Because you install it once and use it with any model. E Signature is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install E Signature in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/ericrisco/rsc-harness/tree/main/skills/e-signature. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use E Signature?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with E Signature?

As many as you like. As long as a model supports skills, you can use E Signature with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the E Signature AI skill free?

Yes. It is published on GitHub by ericrisco under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇