mirror of
https://github.com/documenso/documenso.git
synced 2026-07-12 22:15:01 +10:00
b92c53dbb2
Co-authored-by: Catalin Pit <catalinpit@gmail.com>
515 lines
12 KiB
Plaintext
515 lines
12 KiB
Plaintext
---
|
|
title: Direct Links
|
|
description: Share a URL or embed an iframe to let users sign documents without email invitations.
|
|
---
|
|
|
|
import { Callout } from 'fumadocs-ui/components/callout';
|
|
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
|
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
|
|
|
|
## What Are Direct Links?
|
|
|
|
Direct links are unique URLs tied to a template that allow anyone to:
|
|
|
|
{/* prettier-ignore */}
|
|
<Steps>
|
|
<Step>
|
|
View and sign a document without receiving an email invitation
|
|
</Step>
|
|
<Step>
|
|
Enter their own name and email address
|
|
</Step>
|
|
<Step>
|
|
Complete signature fields and submit the document
|
|
</Step>
|
|
</Steps>
|
|
|
|
When someone uses a direct link, Documenso creates a new document from the template with that person as the signer.
|
|
|
|
### When to Use Direct Links
|
|
|
|
- Collecting signatures from unknown recipients (forms, waivers, petitions)
|
|
- Embedding signing in your website or application
|
|
- Self-service contracts where customers initiate signing
|
|
- Public-facing agreements that anyone can sign
|
|
|
|
### Limitations
|
|
|
|
- Only work with templates, not individual documents
|
|
- Each link is tied to one recipient role in the template
|
|
- Recipients enter their own information (you cannot prefill recipient details)
|
|
|
|
## Creating Direct Link Templates
|
|
|
|
Before embedding, you need a template with direct links enabled.
|
|
|
|
### Via the Dashboard
|
|
|
|
{/* prettier-ignore */}
|
|
<Steps>
|
|
<Step>
|
|
Go to **Templates** and create or select a template
|
|
|
|

|
|
|
|
</Step>
|
|
<Step>
|
|
Click the three-dot menu and select **Direct link**
|
|
</Step>
|
|
<Step>
|
|
Click **Enable direct link signing**
|
|
</Step>
|
|
<Step>
|
|
Choose which recipient in your template will use the direct link
|
|
|
|

|
|
|
|
</Step>
|
|
<Step>
|
|
Copy the generated URL
|
|
</Step>
|
|
</Steps>
|
|
|
|
### Via the API
|
|
|
|
Create a direct link for an existing template:
|
|
|
|
<Tabs items={['curl', 'TypeScript']}>
|
|
<Tab value="curl">
|
|
```bash
|
|
# Create direct link for template
|
|
curl -X POST "https://app.documenso.com/api/v2/template/direct/create" \
|
|
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"templateId": 123,
|
|
"directRecipientId": 1
|
|
}'
|
|
```
|
|
</Tab>
|
|
<Tab value="TypeScript">
|
|
```typescript
|
|
const API_TOKEN = process.env.DOCUMENSO_API_TOKEN;
|
|
const BASE_URL = 'https://app.documenso.com/api/v2';
|
|
|
|
const response = await fetch(`${BASE_URL}/template/direct/create`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: API_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
templateId: 123,
|
|
directRecipientId: 1, // Optional: specific recipient to use
|
|
}),
|
|
});
|
|
|
|
const directLink = await response.json();
|
|
console.log('Direct link token:', directLink.token);
|
|
// URL: https://app.documenso.com/d/{token}
|
|
````
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
### Response
|
|
|
|
```json
|
|
{
|
|
"id": 456,
|
|
"token": "abc123xyz",
|
|
"templateId": 123,
|
|
"directTemplateRecipientId": 1,
|
|
"enabled": true,
|
|
"createdAt": "2025-01-15T10:00:00.000Z"
|
|
}
|
|
````
|
|
|
|
The direct link URL format is:
|
|
|
|
```
|
|
https://app.documenso.com/d/{token}
|
|
```
|
|
|
|

|
|
|
|
---
|
|
|
|
## Embedding in an iframe
|
|
|
|
Embed the signing experience directly in your application using an iframe.
|
|
|
|
### Basic iframe Embedding
|
|
|
|
```html
|
|
<iframe
|
|
src="https://app.documenso.com/embed/direct/abc123xyz"
|
|
width="100%"
|
|
height="800"
|
|
frameborder="0"
|
|
allow="clipboard-write"
|
|
></iframe>
|
|
```
|
|
|
|
### Responsive iframe
|
|
|
|
```html
|
|
<div style="position: relative; width: 100%; padding-bottom: 75%; height: 0; overflow: hidden;">
|
|
<iframe
|
|
src="https://app.documenso.com/embed/direct/abc123xyz"
|
|
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;"
|
|
allow="clipboard-write"
|
|
></iframe>
|
|
</div>
|
|
```
|
|
|
|
### React Component Example
|
|
|
|
```tsx
|
|
function DocumentSigner({ token }: { token: string }) {
|
|
return (
|
|
<div className="h-[800px] w-full">
|
|
<iframe
|
|
src={`https://app.documenso.com/embed/direct/${token}`}
|
|
className="h-full w-full border-0"
|
|
allow="clipboard-write"
|
|
title="Sign Document"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
<Callout type="info">
|
|
The embed URL uses `/embed/direct/{token}` instead of `/d/{token}`. The embed version is optimized
|
|
for iframe embedding with reduced navigation.
|
|
</Callout>
|
|
|
|
---
|
|
|
|
## Embedding with Redirect
|
|
|
|
Instead of an iframe, redirect users to the signing page and bring them back after completion.
|
|
|
|
### Simple Redirect
|
|
|
|
```typescript
|
|
function redirectToSigning(token: string) {
|
|
window.location.href = `https://app.documenso.com/d/${token}`;
|
|
}
|
|
```
|
|
|
|
### With Return URL
|
|
|
|
Configure a redirect URL in your template settings to return users to your application after signing:
|
|
|
|
{/* prettier-ignore */}
|
|
<Steps>
|
|
<Step>
|
|
Edit your template
|
|
</Step>
|
|
<Step>
|
|
Go to **Advanced Settings**
|
|
</Step>
|
|
<Step>
|
|
Set **Redirect URL** to your desired return URL (e.g., `https://yourapp.com/signed`)
|
|
</Step>
|
|
</Steps>
|
|
|
|
Or set it via API when creating the template:
|
|
|
|
```typescript
|
|
const response = await fetch(`${BASE_URL}/template/update`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: API_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
templateId: 123,
|
|
meta: {
|
|
redirectUrl: 'https://yourapp.com/signing-complete',
|
|
},
|
|
}),
|
|
});
|
|
```
|
|
|
|
After signing completes, users are automatically redirected to the specified URL.
|
|
|
|
---
|
|
|
|
## URL Parameters
|
|
|
|
Pass additional data through the direct link URL using query parameters.
|
|
|
|
### External ID
|
|
|
|
Track which document belongs to which transaction in your system:
|
|
|
|
```
|
|
https://app.documenso.com/d/abc123xyz?externalId=order-12345
|
|
```
|
|
|
|
The external ID is stored with the created document and included in webhook payloads.
|
|
|
|
### Example: Dynamic External ID
|
|
|
|
```typescript
|
|
function getSigningUrl(token: string, orderId: string) {
|
|
const params = new URLSearchParams({
|
|
externalId: orderId,
|
|
});
|
|
|
|
return `https://app.documenso.com/d/${token}?${params.toString()}`;
|
|
}
|
|
|
|
// Usage
|
|
const url = getSigningUrl('abc123xyz', 'order-12345');
|
|
// https://app.documenso.com/d/abc123xyz?externalId=order-12345
|
|
```
|
|
|
|
### Embed URL Parameters
|
|
|
|
The embed URL supports the same parameters:
|
|
|
|
```
|
|
https://app.documenso.com/embed/direct/abc123xyz?externalId=order-12345
|
|
```
|
|
|
|
---
|
|
|
|
## Security Considerations
|
|
|
|
### Access Authentication
|
|
|
|
Direct links can require authentication before signing. Configure this in your template settings:
|
|
|
|
| Auth Type | Description |
|
|
| --------- | ---------------------------------------------- |
|
|
| None | Anyone with the link can sign |
|
|
| Account | Signer must be logged into a Documenso account |
|
|
|
|
To require authentication, set `globalAccessAuth` when creating or updating the template:
|
|
|
|
```typescript
|
|
const response = await fetch(`${BASE_URL}/template/update`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: API_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
templateId: 123,
|
|
data: {
|
|
globalAccessAuth: ['ACCOUNT'], // Require login
|
|
},
|
|
}),
|
|
});
|
|
```
|
|
|
|
### Disabling Direct Links
|
|
|
|
Temporarily disable a direct link without deleting it:
|
|
|
|
<Tabs items={['curl', 'TypeScript']}>
|
|
<Tab value="curl">
|
|
```bash
|
|
curl -X POST "https://app.documenso.com/api/v2/template/direct/toggle" \
|
|
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"templateId": 123,
|
|
"enabled": false
|
|
}'
|
|
```
|
|
</Tab>
|
|
<Tab value="TypeScript">
|
|
```typescript
|
|
const response = await fetch(`${BASE_URL}/template/direct/toggle`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: API_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
templateId: 123,
|
|
enabled: false,
|
|
}),
|
|
});
|
|
```
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
Re-enable later by setting `enabled: true`. The URL remains the same.
|
|
|
|
### Deleting Direct Links
|
|
|
|
Permanently remove a direct link:
|
|
|
|
```bash
|
|
curl -X POST "https://app.documenso.com/api/v2/template/direct/delete" \
|
|
-H "Authorization: api_xxxxxxxxxxxxxxxx" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"templateId": 123
|
|
}'
|
|
```
|
|
|
|
<Callout type="warn">
|
|
Deleting a direct link invalidates the URL permanently. If you enable direct links again, a new
|
|
URL will be generated.
|
|
</Callout>
|
|
|
|
---
|
|
|
|
## Styling and Customization
|
|
|
|
### Branding
|
|
|
|
The signing experience uses your organisation's branding settings:
|
|
|
|
- Logo
|
|
- Primary color
|
|
- Email customization
|
|
|
|
Configure branding in **Settings** > **Branding** or via team settings.
|
|
|
|
### Signature Options
|
|
|
|
Control which signature input methods are available:
|
|
|
|
```typescript
|
|
const response = await fetch(`${BASE_URL}/template/update`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: API_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
templateId: 123,
|
|
meta: {
|
|
typedSignatureEnabled: true, // Allow typed signatures
|
|
drawSignatureEnabled: true, // Allow drawn signatures
|
|
uploadSignatureEnabled: false, // Disable uploaded signatures
|
|
},
|
|
}),
|
|
});
|
|
```
|
|
|
|
### White-labeling
|
|
|
|
Enterprise plans support white-label embedding with the "Powered by Documenso" badge removed. [Contact sales](mailto:support@documenso.com) for details.
|
|
|
|
---
|
|
|
|
## Handling Completion
|
|
|
|
### Webhook Notifications
|
|
|
|
Set up webhooks to receive notifications when documents are signed:
|
|
|
|
```json
|
|
{
|
|
"event": "DOCUMENT_SIGNED",
|
|
"payload": {
|
|
"id": 123,
|
|
"externalId": "order-12345",
|
|
"title": "contract.pdf",
|
|
"status": "COMPLETED",
|
|
"Recipient": [
|
|
{
|
|
"email": "signer@example.com",
|
|
"name": "John Doe",
|
|
"signingStatus": "SIGNED",
|
|
"signedAt": "2024-01-15T10:30:00.000Z"
|
|
}
|
|
]
|
|
},
|
|
"createdAt": "2024-01-15T10:30:00.000Z",
|
|
"webhookEndpoint": "https://your-endpoint.com/webhook"
|
|
}
|
|
```
|
|
|
|
See [Webhooks](/docs/developers/webhooks) for setup instructions.
|
|
|
|
### Polling for Status
|
|
|
|
If webhooks aren't suitable, poll the document status:
|
|
|
|
```typescript
|
|
async function checkDocumentStatus(externalId: string) {
|
|
const response = await fetch(`${BASE_URL}/envelope?source=TEMPLATE_DIRECT_LINK`, {
|
|
headers: { Authorization: API_TOKEN },
|
|
});
|
|
|
|
const { data } = await response.json();
|
|
|
|
return data.find((doc) => doc.externalId === externalId);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Complete Example
|
|
|
|
This example shows a complete workflow for embedding direct link signing:
|
|
|
|
```typescript
|
|
const API_TOKEN = process.env.DOCUMENSO_API_TOKEN;
|
|
const BASE_URL = 'https://app.documenso.com/api/v2';
|
|
|
|
// 1. Get template with direct link
|
|
async function getDirectLinkTemplate(templateId: number) {
|
|
const response = await fetch(`${BASE_URL}/template/${templateId}`, {
|
|
headers: { Authorization: API_TOKEN },
|
|
});
|
|
|
|
return response.json();
|
|
}
|
|
|
|
// 2. Create direct link if not exists
|
|
async function ensureDirectLink(templateId: number, recipientId: number) {
|
|
const template = await getDirectLinkTemplate(templateId);
|
|
|
|
if (template.directLink?.enabled) {
|
|
return template.directLink.token;
|
|
}
|
|
|
|
const response = await fetch(`${BASE_URL}/template/direct/create`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: API_TOKEN,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
templateId,
|
|
directRecipientId: recipientId,
|
|
}),
|
|
});
|
|
|
|
const directLink = await response.json();
|
|
return directLink.token;
|
|
}
|
|
|
|
// 3. Generate signing URL with tracking
|
|
function getEmbedUrl(token: string, orderId: string) {
|
|
const params = new URLSearchParams({ externalId: orderId });
|
|
return `https://app.documenso.com/embed/direct/${token}?${params}`;
|
|
}
|
|
|
|
// Usage
|
|
const token = await ensureDirectLink(123, 1);
|
|
const embedUrl = getEmbedUrl(token, 'order-12345');
|
|
|
|
// Embed in your page
|
|
document.getElementById('signer-frame').src = embedUrl;
|
|
```
|
|
|
|
---
|
|
|
|
## See Also
|
|
|
|
- [SDKs](/docs/developers/embedding/sdks) - Framework SDK integration
|
|
- [Templates API](/docs/developers/api/templates) - Template management
|
|
- [Webhooks](/docs/developers/webhooks) - Event notifications
|
|
- [Direct Links (User Guide)](/docs/users/documents/direct-links) - End-user documentation
|