Back to Articles
Cryptography & Identity Security
•15 min read•CSPRNG & SHA-256 Implementation Spec

OTP Code Verification for E-Signatures: Complete API & Security Guide (2026)

How does a 6-digit One-Time Password (OTP) transform an ordinary click into a court-admissible electronic signature? Here is the complete engineering blueprint for CSPRNG code generation, hashed-at-rest storage, timing-safe verification, brute-force lockouts, and zero-account AI agent signing ceremonies.

Quick Answer (TL;DR)

Cryptographic OTP Verification Standard • ESIGN, UETA & eIDAS Attribution

OTP code verification in electronic signatures authenticates a signer's identity by issuing a short-lived, 6-digit code generated via a Cryptographically Secure Pseudo-Random Number Generator (crypto.randomInt(100000, 1000000)) to their verified email or phone before binding the signature. In Signbee, OTP verification powers both recipient authentication and zero-account AI agent sending (POST /api/signing/send-otp and POST /api/signing/verify-otp): an unauthenticated AI agent can stage a contract, and the human sender authorizes dispatch with a 6-digit Email OTP. Every verified OTP timestamp and IP is sealed into the PDF's tamper-evident SHA-256 Signing Certificate.

CSPRNG 6-digit generation
SHA-256 hashed at rest + 5-try lockout
Zero-account AI agent auth ready

1. Why OTP Verification Is the Core Identity Layer of E-Signatures

When two companies execute a commercial contract online, the central legal question in any subsequent dispute is never whether a PDF file exists—it is attribution: Can you prove beyond reasonable doubt that the specific human being named on the signature line actually authorized and executed the agreement?

As defined in our OTP verification glossary reference and our architectural overview of email OTP authentication for e-signatures, a static URL link sent via email provides baseline possession evidence, but links can be accidentally forwarded within an organization's Slack channel or CC'd to external legal counsel. Adding an interactive OTP code verification challenge closes that attribution gap.

By requiring the signer to request a fresh, time-bound 6-digit code during the live browser session and submit that code within a strict 10-minute window, the e-signature platform proves real-time control of the mailbox or mobile number at the exact moment of execution. Furthermore, in 2026, OTP verification has taken on a second mission-critical role: enabling autonomous AI agents to stage contracts on behalf of human principals without requiring pre-provisioned OAuth tokens or static API keys.

2. Evidentiary Standards: ESIGN, UETA, and EU eIDAS (SES vs AdES)

Before writing a single line of cryptographic verification code, systems architects must understand how statutory frameworks classify identity verification methods. Across the United States (ESIGN Act, 15 U.S.C. § 7001 and UETA), the United Kingdom (Electronic Communications Act 2000), and the European Union (eIDAS Regulation No 910/2014), signature assurance scales with the strength of the authentication factors bound to the audit trail:

Verification MechanismFactor ClassificationForwarded-Link ProtectionSignbee Audit Certificate BindingTypical Per-Check Cost
Unauthenticated ClickwrapSingle Factor (Session IP only)None (Anyone with URL can click)IP + Timestamp + User-Agent$0.00
Unique Token Signing LinkPossession (Capability URL token)Moderate (Vulnerable if email forwarded)256-bit Token + IP + SHA-256 PDF Hash$0.00 (Included)
Cryptographic Email OTP (6-Digit)Active Inbox Possession (Real-time challenge)High (Forwarded link cannot sign without live OTP)OTP Verified Timestamp + IP + SHA-256 Hash$0.00 on Signbee ($0.25–$0.50 on legacy APIs)
SMS OTP VerificationOut-of-Band SIM/Carrier PossessionHigh (Subject to SS7 / SIM-swap caveats)E.164 Phone + OTP Timestamp + SHA-256 Hash$0.15–$0.90 / SMS on legacy APIs
Hardware PKI Smartcard (QES)Qualified Trust Service Provider (QTSP)Maximum (Hardware USB token + PIN)X.509 Hardware Certificate Chain$5.00–$25.00 / signature + high drop-off

Notice why Cryptographic Email OTP has become the gold standard for B2B SaaS, freelance agreements, NDAs, HR onboarding, and agent-initiated contracts: it stops forwarded-link spoofing cold and proves live inbox possession at the exact second of signing, while maintaining a 98.4% completion conversion rate (compared to sub-40% completion rates when counterparties are forced to install smartcard drivers or undergo biometric passport scans). And unlike legacy vendors we audited in DocuSign API pricing explained, Signbee includes Email OTP verification at zero additional cost across all plans.

3. Zero-Account AI Agent Signing via Signbee's Two-Phase OTP API

In traditional e-signature APIs—including those reviewed in our best e-signature APIs for developers in 2026—an AI agent cannot do anything until a human user manually registers on a vendor website, enters a credit card, navigates to a developer console, creates an API key, and pastes that secret into an environment file.

Signbee pioneered the Zero-Account OTP Send Flow. If a user inside Claude Desktop, Cursor, ChatGPT, or an autonomous agent workflow asks their AI assistant to send a contract to a client—and no SIGNBEE_API_KEY is configured—the agent does not fail with a 401 Unauthorized error. Instead, Signbee executes a seamless two-phase cryptographic handoff:

  1. Phase 1 (Unauthenticated Staging & OTP Dispatch): The AI agent calls POST https://signb.ee/api/v1/send with the contract title, markdown (or pdf_url / pdf_base64), sender_email, and recipient_email. Detecting no API key, Signbee compiles the PDF, stages the document in PENDING_SENDER_VERIFICATION status, and automatically emails a 6-digit OTP code (or magic verification link) to sender_email via POST /api/signing/send-otp.
  2. Phase 2 (Human-in-the-Loop OTP Verification & Party A Execution): The human user reads the 6-digit code from their inbox and either types it back to the AI agent (which calls POST /api/signing/verify-otp) or clicks the verification link. Signbee validates the cryptographic OTP hash, binds Party A's signature with the verified OTP timestamp, and immediately dispatches the signing ceremony email to Party B.
Signbee Two-Step OTP Verification API Flow (send-otp & verify-otp)TypeScript / REST
// STEP 1: Trigger a fresh 6-digit cryptographic OTP code to the signer or sender email
const sendOtpResponse = await fetch("https://signb.ee/api/signing/send-otp", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    signing_token: "sb_tok_98a7f6e5d4c3b2a1908f7e6d5c4b3a21",
    email: "alex.mercer@vanguard-capital.co.uk",
    purpose: "SIGNER_AUTHENTICATION", // or "SENDER_VERIFICATION"
  }),
});

const sendOtpResult = await sendOtpResponse.json();
// => {
//   "otp_sent": true,
//   "masked_email": "al***@vanguard-capital.co.uk",
//   "expires_in_seconds": 600,
//   "remaining_attempts": 5
// }

// STEP 2: Verify the 6-digit OTP code entered by the human user
const verifyOtpResponse = await fetch("https://signb.ee/api/signing/verify-otp", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    signing_token: "sb_tok_98a7f6e5d4c3b2a1908f7e6d5c4b3a21",
    email: "alex.mercer@vanguard-capital.co.uk",
    otp_code: "482917",
  }),
});

if (!verifyOtpResponse.ok) {
  const err = await verifyOtpResponse.json();
  throw new Error(`OTP Verification Failed: ${err.error} (Attempts left: ${err.remaining_attempts})`);
}

const verification = await verifyOtpResponse.json();
// => {
//   "verified": true,
//   "verified_at": "2026-09-30T14:22:09.418Z",
//   "verification_proof_id": "prf_sha256_7d8f9a0b1c2e3f4a5b6c7d8e",
//   "session_unlocked": true
// }

4. Cryptographic Architecture: How to Build Production OTP Verification

Whether you are consuming Signbee's API or auditing an internal identity microservice (for example, when evaluating an open-source e-signature API comparison), implementing OTP code verification securely requires avoiding four subtle cryptographic pitfalls that regularly fail penetration tests.

Pitfall 1: Never Use Math.random() for OTP Generation

In JavaScript runtimes, Math.random() uses the non-cryptographic xorshift128+ algorithm seeded from internal clock state. It is designed for animations and simulations—not security tokens. Worse, naive expressions like Math.floor(100000 + Math.random() * 900000) are predictable if an attacker samples sequential outputs. Always use the operating system's CSPRNG (/dev/urandom or getrandom(2)) via Node's built-in crypto.randomInt(100000, 1000000), which uses rejection sampling to guarantee uniform distribution without modulo bias.

Pitfall 2: Never Store Plaintext OTP Codes in Your Database

An active 6-digit OTP code is functionally equivalent to a short-lived password. If a read-only database replica, log aggregator, or SQL injection vulnerability exposes a signing_otps table containing plaintext code = "482917" columns, an attacker can immediately hijack every in-flight contract ceremony. Production systems must compute a keyed HMAC-SHA256 digest binding the OTP code to the specific document_id, email, and server secret before persisting to PostgreSQL.

Pitfall 3: Timing Side-Channel Attacks on String Equality (===)

Standard string comparison operators (submittedHash === storedHash) short-circuit and return false on the very first mismatched byte. Over thousands of high-precision HTTP/2 multiplexed requests, statistical timing analysis can distinguish early-byte mismatches from late-byte mismatches. Always compare fixed-length byte buffers using crypto.timingSafeEqual(bufA, bufB).

Pitfall 4: Missing Per-Challenge Attempt Lockouts

A 6-digit decimal code has an entropy pool of 900,000 discrete values (100000 through 999999, representing approximately 19.78 bits of Shannon entropy). That compact size makes it effortless for a human executive to read on a smartphone and type into a desktop browser, but it means cryptographic security relies directly on strict attempt bounding. When each issued OTP challenge is locked after a maximum of 5 failed attempts—forcing the revocation of the challenge hash and requiring a brand-new email dispatch—an attacker guessing randomly has only a 5 in 900,000 (0.00055%) probability of guessing the code before lockout.

Reference Implementation: CSPRNG OTP Generation, Domain-Separated HMAC & Timing-Safe Verificationsrc/lib/crypto-otp.ts
import crypto from "crypto";

const OTP_TTL_MS = 10 * 60 * 1000; // Strict 10-minute expiration window
const MAX_OTP_ATTEMPTS = 5;        // Hard lockout after 5 incorrect guesses

export interface OtpChallengeRecord {
  documentId: string;
  signerEmail: string;
  otpHmacHex: string;
  expiresAt: Date;
  attempts: number;
  consumedAt: Date | null;
}

/**
 * Generates a cryptographically uniform 6-digit OTP code (100000 - 999999)
 * and a domain-separated HMAC-SHA256 digest for database persistence.
 */
export function generateSigningOtpChallenge(
  documentId: string,
  signerEmail: string,
  serverSecret: string
): { rawOtpCode: string; otpHmacHex: string; expiresAt: Date } {
  // 1. OS-entropy CSPRNG integer in [100000, 1000000) — zero modulo bias
  const numericCode = crypto.randomInt(100000, 1000000);
  const rawOtpCode = numericCode.toString().padStart(6, "0");

  // 2. Bind OTP to documentId + normalized email so a code for Doc A cannot unlock Doc B
  const canonicalContext = `${documentId}:${signerEmail.trim().toLowerCase()}:${rawOtpCode}`;
  const otpHmacHex = crypto
    .createHmac("sha256", serverSecret)
    .update(canonicalContext, "utf8")
    .digest("hex");

  const expiresAt = new Date(Date.now() + OTP_TTL_MS);

  return { rawOtpCode, otpHmacHex, expiresAt };
}

/**
 * Verifies a submitted 6-digit OTP code in constant time with strict lockout & TTL checks.
 */
export function verifySigningOtpChallenge(
  submittedCode: string,
  record: OtpChallengeRecord,
  serverSecret: string
): { valid: boolean; reason?: "ALREADY_USED" | "EXPIRED" | "LOCKED_OUT" | "INVALID_CODE" } {
  if (record.consumedAt !== null) {
    return { valid: false, reason: "ALREADY_USED" };
  }

  if (Date.now() > record.expiresAt.getTime()) {
    return { valid: false, reason: "EXPIRED" };
  }

  if (record.attempts >= MAX_OTP_ATTEMPTS) {
    return { valid: false, reason: "LOCKED_OUT" };
  }

  // Recompute domain-separated HMAC-SHA256 for the submitted input
  const sanitizedInput = submittedCode.replace(/\D/g, "").slice(0, 6);
  const candidateContext = `${record.documentId}:${record.signerEmail.trim().toLowerCase()}:${sanitizedInput}`;
  const candidateHmacHex = crypto
    .createHmac("sha256", serverSecret)
    .update(candidateContext, "utf8")
    .digest("hex");

  const storedBuffer = Buffer.from(record.otpHmacHex, "hex");
  const candidateBuffer = Buffer.from(candidateHmacHex, "hex");

  if (
    storedBuffer.length !== candidateBuffer.length ||
    !crypto.timingSafeEqual(storedBuffer, candidateBuffer)
  ) {
    return { valid: false, reason: "INVALID_CODE" };
  }

  return { valid: true };
}

5. Sealing the OTP Audit Trail into the SHA-256 PDF Certificate

Verifying the 6-digit code in memory is only half of the engineering requirement. If an agreement is challenged in commercial litigation three years after execution, the SaaS vendor's internal PostgreSQL table might have rotated logs—which is why the PDF document itself must be a self-contained, tamper-evident cryptographic artifact.

When a document is completed on Signbee, our compilation engine appends an immutable A4 Certificate of Completion directly to the final PDF before computing the master SHA-256 checksum. That certificate permanently records:

  • Document Identifier & Master SHA-256 Hash: A 64-character hexadecimal SHA-256 digest computed over the final signed PDF byte stream, verifiable publicly at https://signb.ee/verify/[documentId].
  • Party A (Sender) Authentication Record: Full legal name, verified email address, authentication mechanism (Bearer API Key ID or Verified 6-Digit Email OTP timestamp), originating IP address, and ISO 8601 UTC dispatch timestamp.
  • Party B (Recipient) Authentication & Execution Record: Full legal name, verified email address, signing token verification, OTP verification UTC timestamp, originating IP address, browser User-Agent fingerprint, signature specimen, and final completion timestamp.
GET /api/v1/documents/[id] — Cryptographic Audit & OTP Verification Ledgerapplication/json
{
  "document_id": "doc_01j8z9k4m2n5p7q8r9s0t1u2v3",
  "title": "Series Seed Preferred Stock Purchase Agreement",
  "status": "SIGNED",
  "sha256_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  "verification_url": "https://signb.ee/verify/doc_01j8z9k4m2n5p7q8r9s0t1u2v3",
  "audit_trail": {
    "sender": {
      "name": "Clara Vance",
      "email": "clara@horizon-ventures.vc",
      "auth_method": "EMAIL_OTP_6_DIGIT",
      "otp_verified_at": "2026-09-30T14:18:02.114Z",
      "ip_address": "185.220.101.42",
      "signed_at": "2026-09-30T14:18:02.114Z"
    },
    "recipient": {
      "name": "Alex Mercer",
      "email": "alex.mercer@vanguard-capital.co.uk",
      "auth_method": "SIGNING_TOKEN_AND_EMAIL_OTP",
      "otp_verified_at": "2026-09-30T14:22:09.418Z",
      "ip_address": "81.2.69.142",
      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6_1) AppleWebKit/605.1.15",
      "signed_at": "2026-09-30T14:23:41.892Z"
    }
  }
}

6. Email OTP vs SMS OTP: Why NIST & Enterprise Security Teams Prefer Email OTP in 2026

Historically, legacy e-signature vendors marketed SMS text message OTP as a premium upgrade over email authentication, charging $0.25 to $0.90 per SMS verification. However, modern enterprise security architecture and NIST SP 800-63B guidelines highlight significant structural advantages for Email OTP in B2B contract execution:

Security & Operational VectorCryptographic Email OTP (Signbee)Legacy PSTN / SMS OTP
Transport Layer EncryptionTLS 1.3 + DKIM + SPF + DMARC verifiedUnencrypted SS7 / SMPP carrier hops
Corporate Identity AlignmentTied to Google Workspace / Okta / Entra ID SSO & hardware passkeysTied to consumer mobile carrier SIM card
SIM-Swap & Port-Out VulnerabilityImmune to telecom store social engineeringVulnerable to carrier SIM-swap attacks
Employee Offboarding RevocationInstant (IT revokes corporate email access)Delayed (Personal mobile number stays with ex-employee)
International Deliverability99.9% global inbox reach (Wi-Fi, airline, roaming)Frequent A2P 10DLC filtering & roaming failures
Unit Economics$0.00 (Included in all Signbee plans)$0.15 – $0.90 per verification attempt

In B2B contracting, an executive's corporate email account (cfo@company.com) is protected by enterprise Single Sign-On (Okta, Microsoft Entra ID, or Google Workspace), hardware FIDO2/WebAuthn passkeys, and instant IT revocation if the employee leaves the firm. By anchoring OTP verification to the corporate domain mailbox, you inherit the organization's enterprise identity posture without paying telecom toll surcharges. For teams evaluating overall platform TCO, compare this in our 2026 e-signature API pricing comparison and affordable e-signature API integration guide.

7. UX Engineering for High-Conversion OTP Signing Ceremonies

If you are building a custom onboarding flow or evaluating a white-label e-signature API, small details in how the 6-digit OTP input is rendered have an outsized impact on mobile completion rates:

  • Use autocomplete="one-time-code" and inputMode="numeric": On iOS Safari, macOS Safari, and Android Chrome, setting these HTML attributes triggers the native numeric keypad and allows the operating system to auto-suggest the 6-digit code directly from the incoming notification banner with a single tap.
  • Support Full-String Paste Across Digit Boxes: Over 62% of desktop signers copy the 6-digit code from their email client using Cmd+C / Ctrl+C and press Cmd+V in the first input box. Always attach an onPaste handler that strips whitespace, distributes all 6 digits across the input state, and auto-submits the verification request immediately upon the 6th digit.
  • Display a Clear Resend Cooldown Timer: Transactional emails typically arrive in 800ms to 2.5 seconds, but corporate MIME gateways (such as Mimecast or Proofpoint) occasionally hold incoming emails for 10–15 seconds during link inspection. Displaying a 30-second countdown timer before enabling the “Resend Code” button prevents impatient users from invalidating their first OTP code while it is still in flight.

8. Testing OTP E-Signature Flows in Production for Free

You do not need an enterprise contract to deploy cryptographic OTP e-signatures. As covered in our guide to using a free e-signature API, Signbee gives every developer 3 free legally binding documents per month with full REST API, Model Context Protocol (npx -y signbee-mcp), Email OTP verification, and SHA-256 certificate verification included.

9. Frequently Asked Questions: OTP Code Verification for E-Signatures

What is OTP code verification in electronic signatures?

OTP (One-Time Password) code verification is a cryptographic identity authentication step during an electronic signature ceremony. Before a sender can dispatch a staged agreement or a recipient can execute a contract, the platform generates a single-use 6-digit numerical code using a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG) and delivers it via email or SMS. Entering the valid code proves possession of the verified inbox or mobile device at a specific UTC timestamp, strengthening non-repudiation under ESIGN, UETA, and eIDAS.

How does Signbee use OTP code verification for zero-account AI agent contract sending?

Signbee allows autonomous AI agents (such as Claude MCP, OpenAI Agents SDK, and Cursor) to stage a contract via POST /api/v1/send even when the human user has not created a Signbee account or API key. When an unauthenticated request arrives, Signbee stages the contract in a PENDING_SENDER_VERIFICATION state and triggers a 6-digit Email OTP via POST /api/signing/send-otp. Once the sender verifies the code via POST /api/signing/verify-otp, Signbee binds Party A's signature and dispatches the signing ceremony link to Party B.

Why should 6-digit OTP verification codes never be generated with Math.random()?

Standard Math.random() implementations in JavaScript (such as V8's xorshift128+) are not cryptographically secure. If an attacker observes a sequence of generated nonces or timestamps, they can reconstruct the internal PRNG state and predict future 6-digit OTP codes. Production e-signature systems must use OS-entropy backed CSPRNG primitives such as Node.js crypto.randomInt(100000, 1000000) or Python secrets.randbelow(900000) + 100000, which eliminate modulo bias and state predictability.

How do you prevent brute-force attacks against a 6-digit OTP code verification endpoint?

Because a 6-digit numerical OTP has exactly 900,000 possible combinations (100000 through 999999), an unprotected HTTP endpoint could be brute-forced in minutes. Production OTP verification requires four layered defenses: (1) strict per-document attempt counters that permanently invalidate the OTP after 5 failed attempts, (2) short 10-minute Time-To-Live (TTL) expiration windows, (3) IP and email sliding-window rate limiting, and (4) constant-time HMAC-SHA256 digest comparisons via crypto.timingSafeEqual.

Is Email OTP code verification legally sufficient under ESIGN, UETA, and eIDAS?

Yes. Under the US ESIGN Act, UETA, the UK Electronic Communications Act 2000, and EU eIDAS Regulation (Article 25), electronic signatures are legally enforceable for the vast majority of commercial, employment, software, and real estate agreements when intent and attribution are demonstrated. Recording a verified OTP event—alongside the signer's email address, originating IP address, user-agent, and a tamper-evident SHA-256 PDF hash—provides strong multi-factor evidentiary attribution.

Does Signbee charge per-message fees for Email OTP verification like DocuSign or BoldSign?

No. While legacy providers like DocuSign and BoldSign meter identity verification and OTP challenges as costly per-envelope or per-SMS add-ons, Signbee includes cryptographic Email OTP verification, IP/user-agent audit logging, and SHA-256 Signing Certificates across all tiers at zero extra cost—including the free 3-document monthly allowance, non-expiring $0.20–$0.50 credit packs, and the $29/month Unlimited Business plan.

Add Cryptographic OTP & SHA-256 E-Signatures in One API Call

Authenticate human signers and autonomous AI agents with zero per-verification surcharges. Start with 3 free documents every month.