Built for developers

Embed agreements into your product.

REST API, idempotency keys, signed webhooks, predictable JSON. SDKs for Node, Python, and Ruby. What you would build if you had two months — without the two months.

cURL
curl https://api.ndakit.com/v1/agreements \
  -H "Authorization: Bearer ndak_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "proposal",
    "party_b_name": "Acme Corp",
    "party_b_email": "ceo@acme.com",
    "amount_cents": 750000,
    "deposit_cents": 250000
  }'

Built for startups + small businesses

Big tools were built for enterprise procurement. We were built for engineers shipping product. No per-seat tax. No envelope caps. No 9-month sales cycles. Just the agreement layer your business needs, drop-in, in 5 minutes.

Embed-first

One line. Lives in your site.

Drop the embed script into any page. Agreements render inline, on your domain, in your typography. Recipients never leave your brand.

HTML
<!-- One line. Drop it anywhere in your site. -->
<script src="https://js.ndakit.com/v1/embed.js"
  data-publishable-key="ndak_pk_live_xxx"
  data-agreement-type="proposal"
  data-on-signed="window.onAgreementSigned"
></script>

Webhooks

Signed, retried, idempotent.

HMAC-SHA256-signed payloads, exponential-backoff retries (1m → 1h → 6h → 24h), and idempotency keys to prevent duplicate handling. Every event below fires from production.

webhook.ts
import { verifyWebhook } from '@ndakit/sdk';

app.post('/webhooks/ndakit', async (req) => {
  const event = await verifyWebhook(req, {
    secret: process.env.NDAKIT_WEBHOOK_SECRET,
  });

  switch (event.type) {
    case 'agreement.signed':
      await db.deals.markSigned(event.data.id);
      break;
    case 'payment.captured':
      await db.deals.markPaid(event.data.id);
      break;
  }

  return res.status(200).send('ok');
});
  • agreement.createdDocument drafted via API or dashboard
  • agreement.sentDelivered to recipient via email or embed
  • agreement.viewedRecipient opened the sign page
  • agreement.signedCounterparty signature captured + sealed
  • agreement.declinedRecipient declined to sign
  • agreement.expiredTTL elapsed before signature
  • payment.capturedStripe / PayPal deposit successful
  • payment.failedCharge failed — retry or escalate

Building blocks

What you get out of the box.

Idempotency keys

Pass Idempotency-Key on any POST and we guarantee exactly-once semantics — no duplicate agreements, ever.

SDKs

Official SDKs for Node, Python, Ruby. Auto-typed responses, webhook verification helpers, retry logic baked in.

Predictable JSON

snake_case fields, ISO-8601 timestamps, errors with stable codes. No envelope wrapping, no surprise nesting.

Edge-fast

API runs on Cloudflare Workers — sub-50ms p95 globally. Sign pages serve from edge cache for instant first paint.

Integration recipes

Common shapes. Already shipped.

Marketplace onboarding

Mandate an NDA before a freelancer can see proprietary briefs. POST /v1/agreements with type=nda; on agreement.signed webhook, unlock the brief feed.

CRM deal-stage automation

Trigger a mutual NDA the moment a deal moves to "Discovery". The agreement renders inline in the deal record; nda.signed advances the stage.

Proposal + deposit in one flow

Send a proposal with a Stripe deposit attached. Agreement signature and payment capture happen in the same recipient session.

Contractor onboarding

Send contractor agreement + NDA + IP assignment as a bundle when an offer is accepted. State-specific overlays apply automatically.

Pricing snapshot

Per-document, no per-seat tax.

Free
$0
10 docs / mo
Starter
$19/mo
100 docs
Growth
$99/mo
1,000 docs
Scale
$399/mo
Unlimited + reseller

Ship agreements this week.

Get a free API key, paste a curl command, see a signed PDF in your inbox. No legal team required.