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.
Create NDA via API
POST /api/v1/ndas — The response includes senderSigningUrl and recipientSigningUrl. NDA status is draft.
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.
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.
Recipient signs the NDA
The recipient opens the link and signs. No account required. NDA status changes to fully_signed.
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:
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://swiftnda.com/api/v1/me3. List Your NDAs
Retrieve all your NDAs with pagination:
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://swiftnda.com/api/v1/ndas?page=1&pageSize=104. Create an NDA
Create a new NDA programmatically (free — drafts never consume quota):
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/ndasAuthentication
All API requests must include your API key in the Authorization header using the Bearer token scheme.
Authorization: Bearer snda_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAs 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
https://swiftnda.com/api/v1Endpoints
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
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://swiftnda.com/api/v1/meExample Response
{
"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
| Parameter | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| pageSize | number | 20 | Items per page (1-100) |
| status | string | — | Filter: draft, awaiting_client, fully_signed |
| search | string | — | Search company names, descriptions |
Example Request
curl -H "Authorization: Bearer YOUR_API_KEY" \
"https://swiftnda.com/api/v1/ndas?page=1&pageSize=10&status=draft"Example Response
{
"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)
| Field | Type | Required | Description |
|---|---|---|---|
| businessName | string | Yes | Your business name (max 100) |
| clientCompanyName | string | Yes | Recipient company name (max 100) |
| projectDescription | string | No | Project description (max 500) |
| purpose | string | Yes | Purpose of the NDA (max 300) |
| ndaTermYears | number | Yes | NDA duration in years (1-10) |
| confidentialityTermYears | number | Yes | Confidentiality period (2-20, must be ≥ ndaTermYears) |
| senderPrintName | string | Yes | Your full name (max 100) |
| senderTitle | string | Yes | Your job title (max 100) |
| senderCompany | string | Yes | Your company name (max 100) |
| senderAddressCountry | string | Yes | Country code (e.g., "US") |
| senderAddressState | string | No | State/Province |
| senderAddressCity | string | Yes | City (max 100) |
| senderAddressZip | string | Yes | ZIP/Postal code (max 20) |
| senderAddressStreet | string | Yes | Street address (max 200) |
| senderAddressSuite | string | No | Suite/Apt number (max 50) |
| senderPhone | string | No | Phone number (international format) |
| governingLaw | string | Yes | Governing law (e.g., "California") |
| jurisdiction | string | Yes | Legal jurisdiction |
| creationType | string | Yes | "quick" or "detailed" |
Example Request
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/ndasExample Response (201 Created)
{
"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)
{
"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
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://swiftnda.com/api/v1/ndas/nda_a1b2c3d4-e5f6-7890-abcd-ef1234567890Example Response
{
"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
curl -H "Authorization: Bearer YOUR_API_KEY" \
-o nda-document.pdf \
https://swiftnda.com/api/v1/ndas/nda_a1b2c3d4-e5f6-7890-abcd-ef1234567890/pdfExample with fetch (Node.js)
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 neededResponse Headers
Content-Type: application/pdfContent-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.
| Status | Meaning | When It Occurs |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | NDA successfully created |
| 401 | Unauthorized | Missing, invalid, or revoked API key |
| 403 | Forbidden | API key lacks permission for this action |
| 404 | Not Found | NDA not found or doesn't belong to you |
| 422 | Unprocessable Entity | Invalid request body or validation errors |
| 429 | Too Many Requests | Rate limit exceeded (see Retry-After header) |
Error Response Format
{
"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
| Header | Description |
|---|---|
| X-RateLimit-Limit | Maximum requests allowed per window (100) |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when the window resets |
| Retry-After | Seconds until limit resets (only on 429) |
When Rate Limited (429)
{
"success": false,
"error": "Rate limit exceeded. Try again in 42 seconds.",
"retryAfter": 42
}Best Practices
- Check
X-RateLimit-Remainingto avoid hitting limits - Implement exponential backoff when receiving 429 responses
- Use the
Retry-Afterheader 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
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
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)