Developer integration tourStep 1 of 5
Contract integration

DocuSign proves an account signed. Manav proves a human signed.

A signature from an account, a leaked session, or an AI agent looks identical to a real one - until you check the human layer. Manav binds a passkey assertion to the contract's payload hash, so any tampering breaks the proof.

Before: MEDIUM After: LOW
The signatureEvery contract carries an independently verifiable human signature.
app.docusign.com / envelopes / env_771adff / sign
Contract envelope

Master Services Agreement - Q2 2026

12 pages · between Acme AI Labs and GreenLeaf Designs. Effective May 4, 2026. Authorized signer Asha Raman, VP Operations.


CounterpartyGreenLeaf Designs LLC
Document hasha3f9…d12c
DocuSign envelopeenv_771adff
Anti-fraudStandard SMS OTP only

Uses your device passkey · Face ID, Touch ID, Windows Hello, or YubiKey · falls back to simulator in demo mode

What the passkey binds to

The canonical action payload

SHA-256 of the JSON below is sent to the authenticator as the challenge. Re-signing a different action with the same passkey is impossible.

{
  "actionType":        "contract_signature",
  "actionTitle":       "Sign Master Services Agreement (Q2 2026)",
  "actorHandle":       "asha",
  "organizationSlug":  "acme-ai",
  "externalReference": "docusign_demo_msa_001",
  "issuedAt":          "2026-05-04T18:22:10.000Z",
  "nonce":             "<128-bit base64url>"
}
What you get back. A public proof URL like manav.id/proof/<slug> that anyone - counterparty, auditor, bank - can open without logging in. The verification re-hashes the canonical payload and HMAC-checks the server proof signature, so tampering is immediately visible.
Verified human signature
manav.id/proof/ -
Open public proof

What the contract now carries

SignatureVerified
AlgorithmES256 (passkey) + HMAC-SHA256 (server)
Payload hash
Signed at
Audit log · live

Drop it into your app

Two lines of HTML, three lines of JS. Demo mode accepts mnav_test_demo as the API key, so you can paste this into any localhost page right now.

<script src="../../sdk/manav-sdk.js"></script>
<script>
  const manav = Manav.init({
    apiKey:  'mnav_test_demo',
    orgSlug: 'acme-ai',
  });

  document.querySelector('#sign').onclick = async () => {
    const r = await manav.sign({
      actionType:        'contract_signature',
      actionTitle:       'Sign Master Services Agreement',
      externalReference: 'env_771adff',
    });
    // r → { proofSlug, proofUrl, status: 'verified' }
    window.location = r.proofUrl;
  };
</script>
# Server-to-server: mint a signature inside a trusted flow
curl -X POST ../../api/signatures/create/ \
  -H 'X-Manav-Key: $MANAV_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "actionType":        "contract_signature",
    "actionTitle":       "Sign Master Services Agreement",
    "actorHandle":       "asha",
    "externalReference": "env_771adff"
  }'
// app/components/SignWithManav.tsx
import { useManav } from '@manav/react';

export function SignWithManav({ envelopeId }: { envelopeId: string }) {
  const { sign, signing } = useManav({ orgSlug: 'acme-ai' });

  return (
    <button onClick={() => sign({
      actionType:        'contract_signature',
      actionTitle:       'Sign MSA',
      externalReference: envelopeId,
    })} disabled={signing}>
      {signing ? 'Verifying human…' : 'Sign with Manav'}
    </button>
  );
}
Engineer · 5 min
Keep the tour going.
Next: Admin wire transfer - A $42K wire pauses until a real human signs.
Continue tour