Skip to main content
SwiftNDA
Developer Reference

API Documentation

Create, manage, and retrieve NDAs programmatically with the SwiftNDA REST API. Designed for developers and LLM agents.

Signing Flow

The NDA signing process follows a specific lifecycle. Understanding this flow is essential for API consumers who want to automate NDA creation and tracking.

1

Create NDA via API

POST /api/v1/ndas — The response includes senderSigningUrl and recipientSigningUrl. NDA status is draft.

2

Author signs via senderSigningUrl

The NDA creator opens the senderSigningUrl in a browser and signs the NDA. They must be authenticated as the NDA owner. NDA status changes to awaiting_client.

3

Share recipientSigningUrl with recipient

Send the recipientSigningUrl directly to the recipient via email, chat, or any channel. No account is required — anyone with the link can sign.

4

Recipient signs the NDA

The recipient opens the link and signs. No account required. NDA status changes to fully_signed.

5

Final PDF generated

Once both parties have signed, the final NDA PDF (with signatures) and an audit trail PDF are automatically generated. Download via GET /api/v1/ndas/:id/pdf.

Note: If the recipient visits their signing link before the sender has signed, they will see a "waiting for author" message. The sender must sign first.

Getting Started

The SwiftNDA API allows you to create, list, and download NDAs programmatically. All API requests require authentication via an API key.

1. Get an API Key

Sign in to your SwiftNDA account and go to your Profile page. Scroll to the “API Keys” section and create a new key. Copy it immediately — it won't be shown again.

2. Make Your First Request

Verify your API key by fetching your profile:

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://swiftnda.com/api/v1/me

3. List Your NDAs

Retrieve all your NDAs with pagination:

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://swiftnda.com/api/v1/ndas?page=1&pageSize=10

4. Create an NDA

Create a new NDA programmatically (free — drafts never consume quota):

bash
curl -X POST -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "businessName": "Acme Corp",
    "clientCompanyName": "Partner Inc",
    "purpose": "Discuss potential partnership",
    "ndaTermYears": 2,
    "confidentialityTermYears": 3,
    "senderPrintName": "Jane Smith",
    "senderTitle": "CEO",
    "senderCompany": "Acme Corp",
    "senderAddressCountry": "US",
    "senderAddressState": "CA",
    "senderAddressCity": "San Francisco",
    "senderAddressZip": "94105",
    "senderAddressStreet": "123 Market St",
    "governingLaw": "California",
    "jurisdiction": "San Francisco County, California",
    "creationType": "quick"
  }' \
  https://swiftnda.com/api/v1/ndas

Authentication

All API requests must include your API key in the Authorization header using the Bearer token scheme.

http
Authorization: Bearer snda_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

As an alternative to the Bearer scheme, you can send the key in an X-API-Key header.

Keep your API key secret

Never expose your API key in client-side code, public repositories, or browser requests. Always make API calls from your server or a secure environment. You can create up to 5 API keys per account and revoke them at any time from the dashboard (Dashboard → API Keys).

Base URL

text
https://swiftnda.com/api/v1

Endpoints

The SwiftNDA API provides 5 endpoints for managing your NDAs and account.

GET/api/v1/me

Returns the authenticated user's profile and API key metadata. Useful for verifying your API key is valid.

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://swiftnda.com/api/v1/me

Example Response

json
{
  "user": {
    "id": "user_abc123",
    "name": "Jane Smith",
    "email": "jane@example.com",
    "image": "https://lh3.googleusercontent.com/..."
  },
  "apiKey": {
    "id": "key_xyz789",
    "name": "My Production Key"
  }
}

GET/api/v1/ndas

Returns a paginated list of your NDAs, sorted by most recently updated.

Query Parameters

ParameterTypeDefaultDescription
pagenumber1Page number
pageSizenumber20Items per page (1-100)
statusstringFilter: draft, awaiting_client, fully_signed
searchstringSearch company names, descriptions

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://swiftnda.com/api/v1/ndas?page=1&pageSize=10&status=draft"

Example Response

json
{
  "success": true,
  "ndas": [
    {
      "id": "nda_abc123-def456-...",
      "status": "draft",
      "clientCompanyName": "Partner Inc",
      "projectDescription": "API integration project",
      "createdAt": "2026-01-15T10:30:00.000Z",
      "updatedAt": "2026-01-15T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 10,
    "total": 42,
    "totalPages": 5
  }
}

POST/api/v1/ndas

Creates a new NDA programmatically. Creation is free: drafts never consume quota. 1 NDA is consumed from your plan when the sender signs it (via the signing URLs in the response); the counterparty signs for free. A draft PDF is generated automatically.

Request Body (JSON)

FieldTypeRequiredDescription
businessNamestringYesYour business name (max 100)
clientCompanyNamestringYesRecipient company name (max 100)
projectDescriptionstringNoProject description (max 500)
purposestringYesPurpose of the NDA (max 300)
ndaTermYearsnumberYesNDA duration in years (1-10)
confidentialityTermYearsnumberYesConfidentiality period (2-20, must be ≥ ndaTermYears)
senderPrintNamestringYesYour full name (max 100)
senderTitlestringYesYour job title (max 100)
senderCompanystringYesYour company name (max 100)
senderAddressCountrystringYesCountry code (e.g., "US")
senderAddressStatestringNoState/Province
senderAddressCitystringYesCity (max 100)
senderAddressZipstringYesZIP/Postal code (max 20)
senderAddressStreetstringYesStreet address (max 200)
senderAddressSuitestringNoSuite/Apt number (max 50)
senderPhonestringNoPhone number (international format)
governingLawstringYesGoverning law (e.g., "California")
jurisdictionstringYesLegal jurisdiction
creationTypestringYes"quick" or "detailed"

Example Request

bash
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "businessName": "Acme Corp",
    "clientCompanyName": "Partner Inc",
    "projectDescription": "API integration project",
    "purpose": "Discuss potential partnership and shared technology",
    "ndaTermYears": 2,
    "confidentialityTermYears": 3,
    "senderPrintName": "Jane Smith",
    "senderTitle": "CEO",
    "senderCompany": "Acme Corp",
    "senderAddressCountry": "US",
    "senderAddressState": "CA",
    "senderAddressCity": "San Francisco",
    "senderAddressZip": "94105",
    "senderAddressStreet": "123 Market St",
    "senderAddressSuite": "Suite 400",
    "senderPhone": "+14155551234",
    "governingLaw": "California",
    "jurisdiction": "San Francisco County, California",
    "creationType": "quick"
  }' \
  https://swiftnda.com/api/v1/ndas

Example Response (201 Created)

json
{
  "success": true,
  "nda": {
    "id": "nda_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "draft",
    "businessName": "Acme Corp",
    "clientCompanyName": "Partner Inc",
    "projectDescription": "API integration project",
    "creationType": "quick",
    "pdfUrl": "/storage/pdfs/nda_a1b2c3d4-...",
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-01-15T10:30:00.000Z",
    "senderSigningUrl": "https://swiftnda.com/ndas/nda_a1b2c3d4-.../sign?role=sender",
    "recipientSigningUrl": "https://swiftnda.com/ndas/nda_a1b2c3d4-.../sign?role=recipient"
  }
}

Signing URL Notes

  • senderSigningUrl — The URL for the NDA author to sign. Requires authentication as the NDA owner.
  • recipientSigningUrl — The URL to share with the recipient. No account required — anyone with the link can sign.
  • If the sender hasn't signed yet, the recipient will see a "waiting for author" message when visiting their signing link.

Validation Error Response (422)

json
{
  "success": false,
  "error": "Validation failed",
  "details": [
    { "field": "businessName", "message": "Business name is required" },
    { "field": "purpose", "message": "Purpose is required" }
  ]
}

GET/api/v1/ndas/:id

Returns full details of a specific NDA including all fields, signatures, and status. Only returns NDAs you own.

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://swiftnda.com/api/v1/ndas/nda_a1b2c3d4-e5f6-7890-abcd-ef1234567890

Example Response

json
{
  "success": true,
  "nda": {
    "id": "nda_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "fully_signed",
    "businessName": "Acme Corp",
    "clientCompanyName": "Partner Inc",
    "projectDescription": "API integration project",
    "duration": 2,
    "pdfUrl": "/storage/pdfs/nda_a1b2c3d4-...",
    "clientEmail": "client@partner.com",
    "emailSentAt": "2026-01-15T11:00:00.000Z",
    "clientSignedAt": "2026-01-16T09:00:00.000Z",
    "userSignedAt": "2026-01-15T10:35:00.000Z",
    "createdAt": "2026-01-15T10:30:00.000Z",
    "updatedAt": "2026-01-16T09:00:00.000Z",
    "purpose": "Discuss potential partnership",
    "ndaTermYears": 2,
    "confidentialityTermYears": 3,
    "creationType": "quick",
    "senderPrintName": "Jane Smith",
    "senderTitle": "CEO",
    "senderCompany": "Acme Corp",
    "senderAddressCountry": "US",
    "senderAddressState": "CA",
    "senderAddressCity": "San Francisco",
    "senderAddressZip": "94105",
    "senderAddressStreet": "123 Market St",
    "governingLaw": "California",
    "jurisdiction": "San Francisco County, California",
    "senderSigningUrl": "https://swiftnda.com/ndas/nda_a1b2c3d4-.../sign?role=sender",
    "recipientSigningUrl": "https://swiftnda.com/ndas/nda_a1b2c3d4-.../sign?role=recipient"
  },
  "signatures": [
    {
      "id": "sig_abc123",
      "signerType": "user",
      "signerName": "Jane Smith",
      "signerEmail": "jane@acme.com",
      "signedAt": "2026-01-15T10:35:00.000Z",
      "ipAddress": "192.168.1.1"
    },
    {
      "id": "sig_def456",
      "signerType": "client",
      "signerName": "Bob Johnson",
      "signerEmail": "bob@partner.com",
      "signedAt": "2026-01-16T09:00:00.000Z",
      "ipAddress": "10.0.0.1"
    }
  ]
}

GET/api/v1/ndas/:id/pdf

Downloads the NDA as a PDF file. Returns binary PDF data withContent-Type: application/pdf.

Example Request

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  -o nda-document.pdf \
  https://swiftnda.com/api/v1/ndas/nda_a1b2c3d4-e5f6-7890-abcd-ef1234567890/pdf

Example with fetch (Node.js)

javascript
const response = await fetch(
  "https://swiftnda.com/api/v1/ndas/NDA_ID/pdf",
  { headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const pdfBuffer = await response.arrayBuffer();
// Save to file or process as needed

Response Headers

  • Content-Type: application/pdf
  • Content-Disposition: attachment; filename="nda-Partner_Inc-nda_a1b2c3d4.pdf"

Quota

One rule applies to both the dashboard and the API: drafts are free. 1 NDA is consumed from your plan when you (the sender) sign it. Your counterparty signs for free.

Creating & drafting

Creating an NDA — whether through the dashboard or via POST /api/v1/ndas — is free. You can draft as many NDAs as you like without affecting your quota.

Signing

1 NDA is deducted from your plan when the sender (owner) signs, via the signing URLs returned on creation. The counterparty's signature is always free. Because at most one owner signature is allowed per NDA, each NDA is charged exactly once.

Quota Exhausted

Creation never fails on quota — POST /api/v1/ndas does not return 402. When your quota is exhausted, the owner's signature is blocked with a 403 status and an upgrade prompt. A counterparty can still complete an NDA whose owner has already signed. Upgrade your plan or wait for the next billing cycle to sign more NDAs.

Error Codes

All error responses follow a consistent JSON format with a success: false field.

StatusMeaningWhen It Occurs
200OKRequest succeeded
201CreatedNDA successfully created
401UnauthorizedMissing, invalid, or revoked API key
403ForbiddenAPI key lacks permission for this action
404Not FoundNDA not found or doesn't belong to you
422Unprocessable EntityInvalid request body or validation errors
429Too Many RequestsRate limit exceeded (see Retry-After header)

Error Response Format

json
{
  "success": false,
  "error": "Human-readable error message",
  "code": "OPTIONAL_ERROR_CODE",
  "details": [
    { "field": "fieldName", "message": "Field-specific error" }
  ]
}

Rate Limits

API requests are rate-limited to 100 requests per minute per API key. Rate limit information is included in response headers.

Rate Limit Headers

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per window (100)
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterSeconds until limit resets (only on 429)

When Rate Limited (429)

json
{
  "success": false,
  "error": "Rate limit exceeded. Try again in 42 seconds.",
  "retryAfter": 42
}

Best Practices

  • Check X-RateLimit-Remaining to avoid hitting limits
  • Implement exponential backoff when receiving 429 responses
  • Use the Retry-After header to know when to retry
  • Cache responses where possible to reduce API calls

LLM Agent Compatibility

The SwiftNDA API is designed to be easily consumed by LLM agents and AI assistants. Here's what makes it agent-friendly:

Consistent JSON Responses

Every response includes a success boolean. Errors include descriptive messages and field-level validation details.

Predictable Error Handling

HTTP status codes follow REST conventions. Error codes likePDF_GENERATION_FAILED enable programmatic error handling without parsing messages.

Full CRUD via API

Create NDAs, list with pagination and filtering, retrieve details, and download PDFs — all via simple REST endpoints with Bearer token auth.

Minimal Authentication

A single API key in the Authorization header is all that's needed. No OAuth flows, no token refresh — just a persistent Bearer token.

Example: Node.js / TypeScript

typescript
const API_KEY = process.env.SWIFTNDA_API_KEY;
const BASE_URL = "https://swiftnda.com/api/v1";

// List all draft NDAs
const response = await fetch(`${BASE_URL}/ndas?status=draft`, {
  headers: { Authorization: `Bearer ${API_KEY}` },
});
const data = await response.json();
console.log(`Found ${data.pagination.total} draft NDAs`);

// Create a new NDA
const createResponse = await fetch(`${BASE_URL}/ndas`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    businessName: "Acme Corp",
    clientCompanyName: "Partner Inc",
    purpose: "Discuss partnership",
    ndaTermYears: 2,
    confidentialityTermYears: 3,
    senderPrintName: "Jane Smith",
    senderTitle: "CEO",
    senderCompany: "Acme Corp",
    senderAddressCountry: "US",
    senderAddressCity: "San Francisco",
    senderAddressZip: "94105",
    senderAddressStreet: "123 Market St",
    governingLaw: "California",
    jurisdiction: "San Francisco County, California",
    creationType: "quick",
  }),
});

if (createResponse.status === 201) {
  const newNda = await createResponse.json();
  console.log(`Created NDA: ${newNda.nda.id}`);
  // Creation is free; send the sender's signing URL to sign (which consumes quota).
  console.log(`Sign here: ${newNda.nda.senderSigningUrl}`);
}

Example: Python

python
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://swiftnda.com/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# List NDAs
response = requests.get(f"{BASE_URL}/ndas", headers=headers)
data = response.json()
print(f"Found {data['pagination']['total']} NDAs")

# Download a PDF
pdf_response = requests.get(
    f"{BASE_URL}/ndas/{nda_id}/pdf", headers=headers
)
with open("nda.pdf", "wb") as f:
    f.write(pdf_response.content)