Compare commits

..

4 Commits

1571 changed files with 54422 additions and 159322 deletions

View File

@ -1,7 +1,4 @@
You are an expert in TypeScript, Node.js, Remix, React, Shadcn UI and Tailwind.
Code Style and Structure: Code Style and Structure:
- Write concise, technical TypeScript code with accurate examples - Write concise, technical TypeScript code with accurate examples
- Use functional and declarative programming patterns; avoid classes - Use functional and declarative programming patterns; avoid classes
- Prefer iteration and modularization over code duplication - Prefer iteration and modularization over code duplication
@ -9,25 +6,20 @@ Code Style and Structure:
- Structure files: exported component, subcomponents, helpers, static content, types - Structure files: exported component, subcomponents, helpers, static content, types
Naming Conventions: Naming Conventions:
- Use lowercase with dashes for directories (e.g., components/auth-wizard) - Use lowercase with dashes for directories (e.g., components/auth-wizard)
- Favor named exports for components - Favor named exports for components
TypeScript Usage: TypeScript Usage:
- Use TypeScript for all code; prefer interfaces over types
- Use TypeScript for all code; prefer types over interfaces - Avoid enums; use maps instead
- Use functional components with TypeScript interfaces - Use functional components with TypeScript interfaces
Syntax and Formatting: Syntax and Formatting:
- Use the "function" keyword for pure functions
- Create functions using `const fn = () => {}`
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements - Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements
- Use declarative JSX - Use declarative JSX
- Never use 'use client'
- Never use 1 line if statements
Error Handling and Validation: Error Handling and Validation:
- Prioritize error handling: handle errors and edge cases early - Prioritize error handling: handle errors and edge cases early
- Use early returns and guard clauses - Use early returns and guard clauses
- Implement proper error logging and user-friendly messages - Implement proper error logging and user-friendly messages
@ -36,40 +28,21 @@ Error Handling and Validation:
- Use error boundaries for unexpected errors - Use error boundaries for unexpected errors
UI and Styling: UI and Styling:
- Use Shadcn UI, Radix, and Tailwind Aria for components and styling - Use Shadcn UI, Radix, and Tailwind Aria for components and styling
- Implement responsive design with Tailwind CSS; use a mobile-first approach - Implement responsive design with Tailwind CSS; use a mobile-first approach
- When using Lucide icons, prefer the longhand names, for example HomeIcon instead of Home
React forms Performance Optimization:
- Minimize 'use client', 'useEffect', and 'setState'; favor React Server Components (RSC)
- Wrap client components in Suspense with fallback
- Use dynamic loading for non-critical components
- Optimize images: use WebP format, include size data, implement lazy loading
- Use zod for form validation react-hook-form for forms Key Conventions:
- Look at TeamCreateDialog.tsx as an example of form usage - Use 'nuqs' for URL search parameter state management
- Use <Form> <FormItem> elements, and also wrap the contents of form in a fieldset which should have the :disabled attribute when the form is loading - Optimize Web Vitals (LCP, CLS, FID)
- Limit 'use client':
- Favor server components and Next.js SSR
- Use only for Web API access in small components
- Avoid for data fetching or state management
TRPC Specifics Follow Next.js docs for Data Fetching, Rendering, and Routing
- Every route should be in it's own file, example routers/teams/create-team.ts
- Every route should have a types file associated with it, example routers/teams/create-team.types.ts. These files should have the OpenAPI meta, and request/response zod schemas
- The request/response schemas should be named like Z[RouteName]RequestSchema and Z[RouteName]ResponseSchema
- Use create-team.ts and create-team.types.ts as an example when creating new routes.
- When creating the OpenAPI meta, only use GET and POST requests, do not use any other REST methods
- Deconstruct the input argument on it's one line of code.
Toast usage
- Use the t`string` macro from @lingui/react/macro to display toast messages
Remix/ReactRouter Usage
- Use (params: Route.Params) to get the params from the route
- Use (loaderData: Route.LoaderData) to get the loader data from the route
- When using loaderdata, deconstruct the data you need from the loader data inside the function body
- Do not use json() to return data, directly return the data
Translations
- Use <Trans>string</Trans> to display translations in jsx code, this should be imported from @lingui/react/macro
- Use the t`string` macro from @lingui/react/macro to display translations in typescript code
- t should be imported as const { t } = useLingui() where useLingui is imported from @lingui/react/macro
- String in constants should be using the t`string` macro

View File

@ -13,10 +13,6 @@ NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="DEADBEEF"
# https://docs.documenso.com/developers/self-hosting/setting-up-oauth-providers#google-oauth-gmail # https://docs.documenso.com/developers/self-hosting/setting-up-oauth-providers#google-oauth-gmail
NEXT_PRIVATE_GOOGLE_CLIENT_ID="" NEXT_PRIVATE_GOOGLE_CLIENT_ID=""
NEXT_PRIVATE_GOOGLE_CLIENT_SECRET="" NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=""
# Find documentation on setting up Microsoft OAuth here:
# https://docs.documenso.com/developers/self-hosting/setting-up-oauth-providers#microsoft-oauth-azure-ad
NEXT_PRIVATE_MICROSOFT_CLIENT_ID=""
NEXT_PRIVATE_MICROSOFT_CLIENT_SECRET=""
NEXT_PRIVATE_OIDC_WELL_KNOWN="" NEXT_PRIVATE_OIDC_WELL_KNOWN=""
NEXT_PRIVATE_OIDC_CLIENT_ID="" NEXT_PRIVATE_OIDC_CLIENT_ID=""
@ -29,10 +25,6 @@ NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
# URL used by the web app to request itself (e.g. local background jobs) # URL used by the web app to request itself (e.g. local background jobs)
NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000" NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000"
# [[SERVER]]
# OPTIONAL: The port the server will listen on. Defaults to 3000.
PORT=3000
# [[DATABASE]] # [[DATABASE]]
NEXT_PRIVATE_DATABASE_URL="postgres://documenso:password@127.0.0.1:54320/documenso" NEXT_PRIVATE_DATABASE_URL="postgres://documenso:password@127.0.0.1:54320/documenso"
# Defines the URL to use for the database when running migrations and other commands that won't work with a connection pool. # Defines the URL to use for the database when running migrations and other commands that won't work with a connection pool.
@ -113,12 +105,6 @@ NEXT_PRIVATE_MAILCHANNELS_DKIM_PRIVATE_KEY=
# OPTIONAL: Displays the maximum document upload limit to the user in MBs # OPTIONAL: Displays the maximum document upload limit to the user in MBs
NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=5 NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=5
# [[EE ONLY]]
# OPTIONAL: The AWS SES API KEY to verify email domains with.
NEXT_PRIVATE_SES_ACCESS_KEY_ID=
NEXT_PRIVATE_SES_SECRET_ACCESS_KEY=
NEXT_PRIVATE_SES_REGION=
# [[STRIPE]] # [[STRIPE]]
NEXT_PRIVATE_STRIPE_API_KEY= NEXT_PRIVATE_STRIPE_API_KEY=
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET= NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET=
@ -141,8 +127,4 @@ E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com"
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123" E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
# [[LOGGER]] # [[LOGGER]]
# OPTIONAL: The file to save the logger output to. Will disable stdout if provided. NEXT_PRIVATE_LOGGER_HONEY_BADGER_API_KEY=
NEXT_PRIVATE_LOGGER_FILE_PATH=
# [[PLAIN SUPPORT]]
NEXT_PRIVATE_PLAIN_API_KEY=

View File

@ -1,3 +1,8 @@
---
name: Pull Request
about: Submit changes to the project for review and inclusion
---
## Description ## Description
<!--- Describe the changes introduced by this pull request. --> <!--- Describe the changes introduced by this pull request. -->

View File

@ -31,9 +31,6 @@ jobs:
- name: Build app - name: Build app
run: npm run build run: npm run build
- name: Install playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests - name: Run Playwright tests
run: npm run ci run: npm run ci
env: env:

View File

@ -20,6 +20,8 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
token: ${{ secrets.GH_PAT }}
- uses: ./.github/actions/node-install - uses: ./.github/actions/node-install

10
.gitignore vendored
View File

@ -50,13 +50,3 @@ yarn-error.log*
!.vscode/tasks.json !.vscode/tasks.json
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
# logs
logs.json
# claude
.claude
CLAUDE.md
# agents
.specs

2
.npmrc
View File

@ -1,3 +1 @@
auto-install-peers = true auto-install-peers = true
legacy-peer-deps = true
prefer-dedupe = true

View File

@ -1,57 +0,0 @@
# Agent Guidelines for Documenso
## Build/Test/Lint Commands
- `npm run build` - Build all packages
- `npm run lint` - Lint all packages
- `npm run lint:fix` - Auto-fix linting issues
- `npm run test:e2e` - Run E2E tests with Playwright
- `npm run test:dev -w @documenso/app-tests` - Run single E2E test in dev mode
- `npm run test-ui:dev -w @documenso/app-tests` - Run E2E tests with UI
- `npm run format` - Format code with Prettier
- `npm run dev` - Start development server for Remix app
## Code Style Guidelines
- Use TypeScript for all code; prefer `type` over `interface`
- Use functional components with `const Component = () => {}`
- Never use classes; prefer functional/declarative patterns
- Use descriptive variable names with auxiliary verbs (isLoading, hasError)
- Directory names: lowercase with dashes (auth-wizard)
- Use named exports for components
- Never use 'use client' directive
- Never use 1-line if statements
- Structure files: exported component, subcomponents, helpers, static content, types
## Error Handling & Validation
- Use custom AppError class when throwing errors
- When catching errors on the frontend use `const error = AppError.parse(error)` to get the error code
- Use early returns and guard clauses
- Use Zod for form validation and react-hook-form for forms
- Use error boundaries for unexpected errors
## UI & Styling
- Use Shadcn UI, Radix, and Tailwind CSS with mobile-first approach
- Use `<Form>` `<FormItem>` elements with fieldset having `:disabled` attribute when loading
- Use Lucide icons with longhand names (HomeIcon vs Home)
## TRPC Routes
- Each route in own file: `routers/teams/create-team.ts`
- Associated types file: `routers/teams/create-team.types.ts`
- Request/response schemas: `Z[RouteName]RequestSchema`, `Z[RouteName]ResponseSchema`
- Only use GET and POST methods in OpenAPI meta
- Deconstruct input argument on its own line
- Prefer route names such as get/getMany/find/create/update/delete
- "create" routes request schema should have the ID and data in the top level
- "update" routes request schema should have the ID in the top level and the data in a nested "data" object
## Translations & Remix
- Use `<Trans>string</Trans>` for JSX translations from `@lingui/react/macro`
- Use `t\`string\`` macro for TypeScript translations
- Use `(params: Route.Params)` and `(loaderData: Route.LoaderData)` for routes
- Directly return data from loaders, don't use `json()`
- Use `superLoaderJson` when sending complex data through loaders such as dates or prisma decimals

View File

@ -1,692 +0,0 @@
# Documenso Code Style Guide
This document captures the code style, patterns, and conventions used in the Documenso codebase. It covers both enforceable rules and subjective "taste" elements that make our code consistent and maintainable.
## Table of Contents
1. [General Principles](#general-principles)
2. [TypeScript Conventions](#typescript-conventions)
3. [Imports & Dependencies](#imports--dependencies)
4. [Functions & Methods](#functions--methods)
5. [React & Components](#react--components)
6. [Error Handling](#error-handling)
7. [Async/Await Patterns](#asyncawait-patterns)
8. [Whitespace & Formatting](#whitespace--formatting)
9. [Naming Conventions](#naming-conventions)
10. [Pattern Matching](#pattern-matching)
11. [Database & Prisma](#database--prisma)
12. [TRPC Patterns](#trpc-patterns)
---
## General Principles
- **Functional over Object-Oriented**: Prefer functional programming patterns over classes
- **Explicit over Implicit**: Be explicit about types, return values, and error cases
- **Early Returns**: Use guard clauses and early returns to reduce nesting
- **Immutability**: Favor `const` over `let`; avoid mutation where possible
---
## TypeScript Conventions
### Type Definitions
```typescript
// ✅ Prefer `type` over `interface`
type CreateDocumentOptions = {
templateId: number;
userId: number;
recipients: Recipient[];
};
// ❌ Avoid interfaces unless absolutely necessary
interface CreateDocumentOptions {
templateId: number;
}
```
### Type Imports
```typescript
// ✅ Use `type` keyword for type-only imports
import type { Document, Recipient } from '@prisma/client';
import { DocumentStatus } from '@prisma/client';
// Types in function signatures
export const findDocuments = async ({ userId, teamId }: FindDocumentsOptions) => {
// ...
};
```
### Inline Types for Function Parameters
```typescript
// ✅ Extract inline types to named types
type FinalRecipient = Pick<Recipient, 'name' | 'email' | 'role' | 'authOptions'> & {
templateRecipientId: number;
fields: Field[];
};
const finalRecipients: FinalRecipient[] = [];
```
---
## Imports & Dependencies
### Import Organization
Imports should be organized in the following order with blank lines between groups:
```typescript
// 1. React imports
import { useCallback, useEffect, useMemo } from 'react';
// 2. Third-party library imports (alphabetically)
import { zodResolver } from '@hookform/resolvers/zod';
import { Trans } from '@lingui/react/macro';
import type { Document, Recipient } from '@prisma/client';
import { DocumentStatus, RecipientRole } from '@prisma/client';
import { match } from 'ts-pattern';
// 3. Internal package imports (from @documenso/*)
import { AppError } from '@documenso/lib/errors/app-error';
import { prisma } from '@documenso/prisma';
import { Button } from '@documenso/ui/primitives/button';
// 4. Relative imports
import { getTeamById } from '../team/get-team';
import type { FindResultResponse } from './types';
```
### Destructuring Imports
```typescript
// ✅ Destructure specific exports
// ✅ Use type imports for types
import type { Document } from '@prisma/client';
import { Button } from '@documenso/ui/primitives/button';
import { Input } from '@documenso/ui/primitives/input';
```
---
## Functions & Methods
### Arrow Functions
```typescript
// ✅ Always use arrow functions for functions
export const createDocument = async ({
userId,
title,
}: CreateDocumentOptions) => {
// ...
};
// ✅ Callbacks and handlers
const onSubmit = useCallback(async () => {
// ...
}, [dependencies]);
// ❌ Avoid regular function declarations
function createDocument() {
// ...
}
```
### Function Parameters
```typescript
// ✅ Use destructured object parameters for multiple params
export const findDocuments = async ({
userId,
teamId,
status = ExtendedDocumentStatus.ALL,
page = 1,
perPage = 10,
}: FindDocumentsOptions) => {
// ...
};
// ✅ Destructure on separate line when needed
const onFormSubmit = form.handleSubmit(onSubmit);
// ✅ Deconstruct nested properties explicitly
const { user } = ctx;
const { templateId } = input;
```
---
## React & Components
### Component Definition
```typescript
// ✅ Use const with arrow function
export const AddSignersFormPartial = ({
documentFlow,
recipients,
fields,
onSubmit,
}: AddSignersFormProps) => {
// ...
};
// ❌ Never use classes
class MyComponent extends React.Component {
// ...
}
```
### Hooks
```typescript
// ✅ Group related hooks together with blank line separation
const { _ } = useLingui();
const { toast } = useToast();
const { currentStep, totalSteps, previousStep } = useStep();
const form = useForm<TFormSchema>({
resolver: zodResolver(ZFormSchema),
defaultValues: {
// ...
},
});
```
### Event Handlers
```typescript
// ✅ Use arrow functions with descriptive names
const onFormSubmit = async () => {
await form.trigger();
// ...
};
const onFieldCopy = useCallback(
(event?: KeyboardEvent | null) => {
event?.preventDefault();
// ...
},
[dependencies],
);
// ✅ Inline handlers for simple operations
<Button onClick={() => setOpen(false)}>Close</Button>
```
### State Management
```typescript
// ✅ Descriptive state names with auxiliary verbs
const [isLoading, setIsLoading] = useState(false);
const [hasError, setHasError] = useState(false);
const [showAdvancedSettings, setShowAdvancedSettings] = useState(false);
// ✅ Complex state in single useState when related
const [coords, setCoords] = useState({
x: 0,
y: 0,
});
```
---
## Error Handling
### Try-Catch Blocks
```typescript
// ✅ Use try-catch for operations that might fail
try {
const document = await getDocumentById({
documentId: Number(documentId),
userId: user.id,
});
return {
status: 200,
body: document,
};
} catch (err) {
return {
status: 404,
body: {
message: 'Document not found',
},
};
}
```
### Throwing Errors
```typescript
// ✅ Use AppError for application errors
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Template not found',
});
// ✅ Use descriptive error messages
if (!template) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: `Template with ID ${templateId} not found`,
});
}
```
### Error Parsing on Frontend
```typescript
// ✅ Parse errors on the frontend
try {
await updateOrganisation({ organisationId, data });
} catch (err) {
const error = AppError.parseError(err);
console.error(error);
toast({
title: t`An error occurred`,
description: error.message,
variant: 'destructive',
});
}
```
---
## Async/Await Patterns
### Async Function Definitions
```typescript
// ✅ Mark async functions clearly
export const createDocument = async ({
userId,
title,
}: Options): Promise<Document> => {
// ...
};
// ✅ Use await for promises
const document = await prisma.document.create({ data });
// ✅ Use Promise.all for parallel operations
const [document, recipients] = await Promise.all([
getDocumentById({ documentId }),
getRecipientsForDocument({ documentId }),
]);
```
### Void for Fire-and-Forget
```typescript
// ✅ Use void for intentionally unwaited promises
void handleAutoSave();
// ✅ Or in event handlers
onClick={() => void onFormSubmit()}
```
---
## Whitespace & Formatting
### Blank Lines Between Concepts
```typescript
// ✅ Blank line after imports
import { prisma } from '@documenso/prisma';
export const findDocuments = async () => {
// ...
};
// ✅ Blank line between logical sections
const user = await prisma.user.findFirst({ where: { id: userId } });
let team = null;
if (teamId !== undefined) {
team = await getTeamById({ userId, teamId });
}
// ✅ Blank line before return statements
const result = await someOperation();
return result;
```
### Function/Method Spacing
```typescript
// ✅ No blank lines between chained methods in same operation
const documents = await prisma.document
.findMany({ where: { userId } })
.then((docs) => docs.map(maskTokens));
// ✅ Blank line between different operations
const document = await createDocument({ userId });
await sendDocument({ documentId: document.id });
return document;
```
### Object and Array Formatting
```typescript
// ✅ Multi-line when complex
const options = {
userId,
teamId,
status: ExtendedDocumentStatus.ALL,
page: 1,
};
// ✅ Single line when simple
const coords = { x: 0, y: 0 };
// ✅ Array items on separate lines when objects
const recipients = [
{
name: 'John',
email: 'john@example.com',
},
{
name: 'Jane',
email: 'jane@example.com',
},
];
```
---
## Naming Conventions
### Variables
```typescript
// ✅ camelCase for variables and functions
const documentId = 123;
const onSubmit = () => {};
// ✅ Descriptive names with auxiliary verbs for booleans
const isLoading = false;
const hasError = false;
const canEdit = true;
const shouldRender = true;
// ✅ Prefix with $ for DOM elements
const $page = document.querySelector('.page');
const $inputRef = useRef<HTMLInputElement>(null);
```
### Types and Schemas
```typescript
// ✅ PascalCase for types
type CreateDocumentOptions = {
userId: number;
};
// ✅ Prefix Zod schemas with Z
const ZCreateDocumentSchema = z.object({
title: z.string(),
});
// ✅ Prefix type from Zod schema with T
type TCreateDocumentSchema = z.infer<typeof ZCreateDocumentSchema>;
```
### Constants
```typescript
// ✅ UPPER_SNAKE_CASE for true constants
const DEFAULT_DOCUMENT_DATE_FORMAT = 'dd/MM/yyyy';
const MAX_FILE_SIZE = 1024 * 1024 * 5;
// ✅ camelCase for const variables that aren't "constants"
const userId = await getUserId();
```
### Functions
```typescript
// ✅ Verb-based names for functions
const createDocument = async () => {};
const findDocuments = async () => {};
const updateDocument = async () => {};
const deleteDocument = async () => {};
// ✅ On prefix for event handlers
const onSubmit = () => {};
const onClick = () => {};
const onFieldCopy = () => {}; // 'on' is also acceptable
```
### Clarity Over Brevity
```typescript
// ✅ Prefer descriptive names over abbreviations
const superLongMethodThatIsCorrect = () => {};
const recipientAuthenticationOptions = {};
const documentMetadata = {};
// ❌ Avoid abbreviations that sacrifice clarity
const supLongMethThatIsCorrect = () => {};
const recipAuthOpts = {};
const docMeta = {};
// ✅ Common abbreviations that are widely understood are acceptable
const userId = 123;
const htmlElement = document.querySelector('div');
const apiResponse = await fetch('/api');
```
---
## Pattern Matching
### Using ts-pattern
```typescript
import { match } from 'ts-pattern';
// ✅ Use match for complex conditionals
const result = match(status)
.with(ExtendedDocumentStatus.DRAFT, () => ({
status: 'draft',
}))
.with(ExtendedDocumentStatus.PENDING, () => ({
status: 'pending',
}))
.with(ExtendedDocumentStatus.COMPLETED, () => ({
status: 'completed',
}))
.exhaustive();
// ✅ Use .otherwise() for default case when not exhaustive
const value = match(type)
.with('text', () => 'Text field')
.with('number', () => 'Number field')
.otherwise(() => 'Unknown field');
```
---
## Database & Prisma
### Query Structure
```typescript
// ✅ Destructure commonly used fields
const { id, email, name } = user;
// ✅ Use select to limit returned fields
const user = await prisma.user.findFirst({
where: { id: userId },
select: {
id: true,
email: true,
name: true,
},
});
// ✅ Use include for relations
const document = await prisma.document.findFirst({
where: { id: documentId },
include: {
recipients: true,
fields: true,
},
});
```
### Transactions
```typescript
// ✅ Use transactions for related operations
return await prisma.$transaction(async (tx) => {
const document = await tx.document.create({ data });
await tx.field.createMany({ data: fieldsData });
await tx.documentAuditLog.create({ data: auditData });
return document;
});
```
### Where Clauses
```typescript
// ✅ Build complex where clauses separately
const whereClause: Prisma.DocumentWhereInput = {
AND: [
{ userId: user.id },
{ deletedAt: null },
{ status: { in: [DocumentStatus.DRAFT, DocumentStatus.PENDING] } },
],
};
const documents = await prisma.document.findMany({
where: whereClause,
});
```
---
## TRPC Patterns
### Router Structure
```typescript
// ✅ Destructure context and input at start
.query(async ({ input, ctx }) => {
const { teamId } = ctx;
const { templateId } = input;
ctx.logger.info({
input: { templateId },
});
return await getTemplateById({
id: templateId,
userId: ctx.user.id,
teamId,
});
});
```
### Request/Response Schemas
```typescript
// ✅ Name schemas clearly
const ZCreateDocumentRequestSchema = z.object({
title: z.string(),
recipients: z.array(ZRecipientSchema),
});
const ZCreateDocumentResponseSchema = z.object({
documentId: z.number(),
status: z.string(),
});
```
### Error Handling in TRPC
```typescript
// ✅ Catch and transform errors appropriately
try {
const result = await createDocument({ userId, data });
return result;
} catch (err) {
return AppError.toRestAPIError(err);
}
// ✅ Or throw AppError directly
if (!template) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Template not found',
});
}
```
---
## Additional Patterns
### Optional Chaining
```typescript
// ✅ Use optional chaining for potentially undefined values
const email = user?.email;
const recipientToken = recipient?.token ?? '';
// ✅ Use nullish coalescing for defaults
const pageSize = perPage ?? 10;
const status = documentStatus ?? DocumentStatus.DRAFT;
```
### Array Operations
```typescript
// ✅ Use functional array methods
const activeRecipients = recipients.filter((r) => r.signingStatus === 'SIGNED');
const recipientEmails = recipients.map((r) => r.email);
const hasSignedRecipients = recipients.some((r) => r.signingStatus === 'SIGNED');
// ✅ Use find instead of filter + [0]
const recipient = recipients.find((r) => r.id === recipientId);
```
### Conditional Rendering
```typescript
// ✅ Use && for conditional rendering
{isLoading && <Loader />}
// ✅ Use ternary for either/or
{isLoading ? <Loader /> : <Content />}
// ✅ Extract complex conditions to variables
const shouldShowAdvanced = isAdmin && hasPermission && !isDisabled;
{shouldShowAdvanced && <AdvancedSettings />}
```
---
## When in Doubt
- **Consistency**: Follow the patterns you see in similar files
- **Readability**: Favor code that's easy to read over clever one-liners
- **Explicitness**: Be explicit rather than implicit
- **Whitespace**: Use blank lines to separate logical sections
- **Early Returns**: Use guard clauses to reduce nesting
- **Functional**: Prefer functional patterns over imperative ones

View File

@ -49,6 +49,8 @@ Join us in creating the next generation of open trust infrastructure.
## Community and Next Steps 🎯 ## Community and Next Steps 🎯
We're currently working on a redesign of the application, including a revamp of the codebase, so Documenso can be more intuitive to use and robust to develop upon.
- Check out the first source code release in this repository and test it. - Check out the first source code release in this repository and test it.
- Tell us what you think in the [Discussions](https://github.com/documenso/documenso/discussions). - Tell us what you think in the [Discussions](https://github.com/documenso/documenso/discussions).
- Join the [Discord server](https://documen.so/discord) for any questions and getting to know to other community members. - Join the [Discord server](https://documen.so/discord) for any questions and getting to know to other community members.
@ -214,6 +216,8 @@ For detailed instructions on how to configure and run the Docker container, plea
We support a variety of deployment methods, and are actively working on adding more. Stay tuned for updates! We support a variety of deployment methods, and are actively working on adding more. Stay tuned for updates!
> Please note that the below deployment methods are for v0.9, we will update these to v1.0 once it has been released.
### Fetch, configure, and build ### Fetch, configure, and build
First, clone the code from Github: First, clone the code from Github:
@ -243,20 +247,20 @@ Now you can install the dependencies and build it:
``` ```
npm i npm i
npm run build npm run build:web
npm run prisma:migrate-deploy npm run prisma:migrate-deploy
``` ```
Finally, you can start it with: Finally, you can start it with:
``` ```
cd apps/remix cd apps/web
npm run start npm run start
``` ```
This will start the server on `localhost:3000`. For now, any reverse proxy can then do the frontend and SSL termination. This will start the server on `localhost:3000`. For now, any reverse proxy can then do the frontend and SSL termination.
> If you want to run with another port than 3000, you can start the application with `next -p <ANY PORT>` from the `apps/remix` folder. > If you want to run with another port than 3000, you can start the application with `next -p <ANY PORT>` from the `apps/web` folder.
### Run as a service ### Run as a service
@ -271,7 +275,7 @@ After=network.target
Environment=PATH=/path/to/your/node/binaries Environment=PATH=/path/to/your/node/binaries
Type=simple Type=simple
User=www-data User=www-data
WorkingDirectory=/var/www/documenso/apps/remix WorkingDirectory=/var/www/documenso/apps/web
ExecStart=/usr/bin/next start -p 3500 ExecStart=/usr/bin/next start -p 3500
TimeoutSec=15 TimeoutSec=15
Restart=always Restart=always
@ -306,7 +310,7 @@ The Web UI can be found at http://localhost:9000, while the SMTP port will be on
### Support IPv6 ### Support IPv6
If you are deploying to a cluster that uses only IPv6, You can use a custom command to pass a parameter to the Remix start command If you are deploying to a cluster that uses only IPv6, You can use a custom command to pass a parameter to the Next.js start command
For local docker run For local docker run

View File

@ -10,26 +10,15 @@ For the digital signature of your documents you need a signing certificate in .p
`openssl req -new -x509 -key private.key -out certificate.crt -days 365` `openssl req -new -x509 -key private.key -out certificate.crt -days 365`
This will prompt you to enter some information, such as the Common Name (CN) for the certificate. Make sure you enter the correct information. The `-days` parameter sets the number of days for which the certificate is valid. This will prompt you to enter some information, such as the Common Name (CN) for the certificate. Make sure you enter the correct information. The -days parameter sets the number of days for which the certificate is valid.
3. Combine the private key and the self-signed certificate to create the p12 certificate. You can run the following commands to do this: 3. Combine the private key and the self-signed certificate to create the p12 certificate. You can run the following command to do this:
```bash `openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt`
# Set certificate password securely (won't appear in command history)
read -s -p "Enter certificate password: " CERT_PASS
echo
# Create the p12 certificate using the environment variable 4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt \
-password env:CERT_PASS \
-keypbe PBE-SHA1-3DES \
-certpbe PBE-SHA1-3DES \
-macalg sha1
```
4. **IMPORTANT**: A certificate password is required to prevent signing failures. Make sure to use a strong password (minimum 4 characters) when prompted. Certificates without passwords will cause "Failed to get private key bags" errors during document signing. 5. Place the certificate `/apps/web/resources/certificate.p12` (If the path does not exist, it needs to be created)
5. Place the certificate `/apps/remix/resources/certificate.p12` (If the path does not exist, it needs to be created)
## Docker ## Docker

View File

@ -34,8 +34,3 @@ yarn-error.log*
# typescript # typescript
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
# next-sitemap output
/public/sitemap.xml
/public/robots.txt
/public/sitemap-*.xml

View File

@ -1,5 +0,0 @@
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://docs.documenso.com', // Replace with your actual site URL
generateRobotsTxt: true, // Generates robots.txt
};

View File

@ -1,5 +1,3 @@
import nextra from 'nextra';
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
transpilePackages: [ transpilePackages: [
@ -11,10 +9,9 @@ const nextConfig = {
], ],
}; };
const withNextra = nextra({ const withNextra = require('nextra')({
theme: 'nextra-theme-docs', theme: 'nextra-theme-docs',
themeConfig: './theme.config.tsx', themeConfig: './theme.config.tsx',
codeHighlight: true,
}); });
export default withNextra(nextConfig); module.exports = withNextra(nextConfig);

View File

@ -4,7 +4,7 @@
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev -p 3002", "dev": "next dev -p 3002",
"build": "next build && next-sitemap", "build": "next build",
"start": "next start -p 3002", "start": "next start -p 3002",
"lint:fix": "next lint --fix", "lint:fix": "next lint --fix",
"clean": "rimraf .next && rimraf node_modules" "clean": "rimraf .next && rimraf node_modules"
@ -15,7 +15,7 @@
"@documenso/tailwind-config": "*", "@documenso/tailwind-config": "*",
"@documenso/trpc": "*", "@documenso/trpc": "*",
"@documenso/ui": "*", "@documenso/ui": "*",
"next": "14.2.28", "next": "14.2.6",
"next-plausible": "^3.12.0", "next-plausible": "^3.12.0",
"nextra": "^2.13.4", "nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4", "nextra-theme-docs": "^2.13.4",
@ -26,7 +26,6 @@
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"next-sitemap": "^4.2.3",
"typescript": "5.6.2" "typescript": "5.6.2"
} }
} }

View File

@ -5,7 +5,6 @@
"title": "Development & Deployment" "title": "Development & Deployment"
}, },
"local-development": "Local Development", "local-development": "Local Development",
"developer-mode": "Developer Mode",
"self-hosting": "Self Hosting", "self-hosting": "Self Hosting",
"contributing": "Contributing", "contributing": "Contributing",
"-- API & Integration Guides": { "-- API & Integration Guides": {

View File

@ -25,7 +25,7 @@ The translation files are organized into folders represented by their respective
Each PO file contains translations which look like this: Each PO file contains translations which look like this:
```po ```po
#: apps/remix/app/(signing)/sign/[token]/no-longer-available.tsx:61 #: apps/web/src/app/(signing)/sign/[token]/no-longer-available.tsx:61
msgid "Want to send slick signing links like this one? <0>Check out Documenso.</0>" msgid "Want to send slick signing links like this one? <0>Check out Documenso.</0>"
msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüfen Sie Documenso.</0>" msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüfen Sie Documenso.</0>"
``` ```

View File

@ -1,18 +0,0 @@
---
title: Field Coordinates
description: Learn how to get the coordinates of a field in a document.
---
## Field Coordinates
Field coordinates represent the position of a field in a document. They are returned in the `pageX` and `pageY` properties of the field.
To enable field coordinates, you can use the `devmode` query parameter.
```bash
https://app.documenso.com/documents/<document-id>/edit?devmode=true
```
You should then see the coordinates on top of each field.
![Field Coordinates](/developer-mode/field-coordinates.webp)

View File

@ -44,7 +44,7 @@ Before using the `EmbedCreateDocument` component, you'll need to obtain a presig
You can create a presign token by making a request to: You can create a presign token by making a request to:
``` ```
POST /api/v2/embedding/create-presign-token POST /api/v2-beta/embedding/create-presign-token
``` ```
This API endpoint requires authentication with your Documenso API key. The token has a default expiration of 1 hour, but you can customize this duration based on your security requirements. This API endpoint requires authentication with your Documenso API key. The token has a default expiration of 1 hour, but you can customize this duration based on your security requirements.
@ -134,7 +134,7 @@ import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/
function DocumentCreator() { function DocumentCreator() {
// In a real application, you would fetch this token from your backend // In a real application, you would fetch this token from your backend
// using your API key at /api/v2/embedding/create-presign-token // using your API key at /api/v2-beta/embedding/create-presign-token
const presignToken = 'YOUR_PRESIGN_TOKEN'; const presignToken = 'YOUR_PRESIGN_TOKEN';
const [documentId, setDocumentId] = useState<number | null>(null); const [documentId, setDocumentId] = useState<number | null>(null);

View File

@ -1,6 +1,5 @@
{ {
"index": "Get Started", "index": "Get Started",
"authentication": "Authentication", "authentication": "Authentication",
"rate-limits": "Rate Limits",
"versioning": "Versioning" "versioning": "Versioning"
} }

View File

@ -9,11 +9,11 @@ Documenso uses API keys for authentication. An API key is a unique token that is
## Creating an API Key ## Creating an API Key
To create an API key, navigate to the user settings page. Click on your avatar in the top right corner of the dashboard and select "Team Settings" from the dropdown menu. To create an API key, navigate to the user settings page. Click on your avatar in the top right corner of the dashboard and select "**[User settings](https://app.documenso.com/settings)**" from the dropdown menu.
![A screenshot of the Documenso's dashboard that shows the dropdown menu when you click on your user avatar](/public-api-images/documenso-user-dropdown-menu.webp) ![A screenshot of the Documenso's dashboard that shows the dropdown menu when you click on your user avatar](/public-api-images/documenso-user-dropdown-menu.webp)
Once you're on the settings page, navigate to the **API Tokens** tab. This page lists your existing keys and enables you to create new ones. Once you're on the user settings page, navigate to the "**[API Tokens](https://app.documenso.com/settings/tokens)**" tab. The "API Token" page lists your existing keys and enables you to create new ones.
![A screenshot of the Documenso's user settings page that shows the API Tokens page](/public-api-images/api-tokens-page-documenso.webp) ![A screenshot of the Documenso's user settings page that shows the API Tokens page](/public-api-images/api-tokens-page-documenso.webp)
@ -37,17 +37,31 @@ You must include the API key in the `Authorization` request header to authentica
Here's a sample API request using cURL: Here's a sample API request using cURL:
```bash ```bash
curl --location 'https://app.documenso.com/api/v2/envelope/create' \ curl --location 'https://app.documenso.com/api/v1/documents?page=1&perPage=1' \
--header 'Authorization: api_xxxxxxxxxxxxxxxx' \ --header 'Authorization: api_xxxxxxxxxxxxxxxx'
--form 'payload={ "title": "Some Title", "type": "DOCUMENT" }'
``` ```
Here's a sample response from the API based on the above cURL request: Here's a sample response from the API based on the above cURL request:
```json ```json
{ {
"id": "envelope_xxxxxxxxxxxxx" "documents": [
{
"id": 11,
"userId": 2,
"teamId": null,
"title": "documenso",
"status": "PENDING",
"documentDataId": "ab2ecm1npk11rt5sp398waf7h",
"createdAt": "2024-04-25T11:05:18.420Z",
"updatedAt": "2024-04-25T11:05:36.328Z",
"completedAt": null
}
],
"totalPages": 1
} }
``` ```
The API key has access to your account and all its resources. Please keep it secure and do not share it with others. If you suspect your key has been compromised, you can revoke it from the same page you created it from. ![A screenshot of a cURL request to the Documenso public API with the API key in the Authorization header](/public-api-images/documenso-api-authorization.webp)
The API key has access to your account and all its resources. Please keep it secure and do not share it with others. If you suspect your key has been compromised, you can revoke it from the "API Tokens" page in your user settings.

View File

@ -9,13 +9,19 @@ import { Callout, Steps } from 'nextra/components';
Documenso provides a public REST API enabling you to interact with your documents programmatically. The API exposes various HTTP endpoints that allow you to perform operations such as: Documenso provides a public REST API enabling you to interact with your documents programmatically. The API exposes various HTTP endpoints that allow you to perform operations such as:
- Retrieving, uploading, deleting, and sending documents for signing - retrieving, uploading, deleting, and sending documents for signing
- Creating, updating, and deleting recipients - creating, updating, and deleting recipients
- Creating, updating, and deleting document fields - creating, updating, and deleting document fields
The documentation walks you through creating API keys and using them to authenticate your API requests. You'll also learn about the available endpoints, request and response formats, and how to use the API. The documentation walks you through creating API keys and using them to authenticate your API requests. You'll also learn about the available endpoints, request and response formats, and how to use the API.
## API V2 - Stable ## API V1 - Stable
Check out the [API V1 documentation](https://app.documenso.com/api/v1/openapi) for details about the API endpoints, request parameters, response formats, and authentication methods.
## API V2 - Beta
<Callout type="warning">API V2 is currently beta, and will be subject to breaking changes</Callout>
Check out the [API V2 documentation](https://documen.so/api-v2-docs) for details about the API endpoints, request parameters, response formats, and authentication methods. Check out the [API V2 documentation](https://documen.so/api-v2-docs) for details about the API endpoints, request parameters, response formats, and authentication methods.
@ -26,15 +32,18 @@ Our new API V2 supports the following typed SDKs:
- [Go](https://github.com/documenso/sdk-go) - [Go](https://github.com/documenso/sdk-go)
<Callout type="info"> <Callout type="info">
For the staging API, please use the following base URL: `https://stg-app.documenso.com/api/v2/` For the staging API, please use the following base URL:
`https://stg-app.documenso.dev/api/v2-beta/`
</Callout> </Callout>
## API V1 - Deprecated 🚀 [V2 Announcement](https://documen.so/sdk-blog)
Check out the [API V1 documentation](https://app.documenso.com/api/v1/openapi) for details about the API endpoints, request parameters, response formats, and authentication methods.
📖 [Documentation](https://documen.so/api-v2-docs) 📖 [Documentation](https://documen.so/api-v2-docs)
💬 [Leave Feedback](https://documen.so/sdk-feedback)
🔔 [Breaking Changes](https://documen.so/sdk-breaking)
## Availability ## Availability
The API is available to individual users, teams and higher plans. [Fair Use](https://documen.so/fair) applies. The API is available to individual users, teams and higher plans. [Fair Use](https://documen.so/fair) applies.

View File

@ -1,54 +0,0 @@
import { Callout } from 'nextra/components';
# Rate Limits
Documenso enforces rate limits on all API endpoints to ensure service stability.
## HTTP Rate Limits
**Limit:** 100 requests per minute per IP address
**Response:** 429 Too Many Requests
### Rate Limit Response
```json
{
"error": "Too many requests, please try again later."
}
```
<Callout type="warning">
No rate limit headers are currently provided. When you receive a 429 response, wait at least 60
seconds before retrying.
</Callout>
## Resource Limits
Beyond HTTP rate limits, your account has usage limits based on your subscription plan.
### Plan Limits
| Resource | Free | Paid | Self-hosted | Enterprise |
| ---------------- | ---- | --------- | ----------- | ---------- |
| Documents/month | 5 | Unlimited | Unlimited | Unlimited |
| Total Recipients | 10 | Unlimited | Unlimited | Unlimited |
| Direct Templates | 3 | Unlimited | Unlimited | Unlimited |
### Error Response
When you exceed a resource limit:
```json
{
"error": "You have reached your document limit for this month. Please upgrade your plan.",
"code": "LIMIT_EXCEEDED",
"statusCode": 400
}
```
## Error Codes
| Code | Status | Description |
| ------------------- | ------ | ----------------------------- |
| `TOO_MANY_REQUESTS` | 429 | HTTP rate limit exceeded |
| `LIMIT_EXCEEDED` | 400 | Resource usage limit exceeded |

View File

@ -7,246 +7,550 @@ import { Callout, Steps } from 'nextra/components';
# API Reference # API Reference
On this page we will refer to both Documents and Templates as Envelopes for convenience, unless otherwise specified. The Swagger UI for the API is available at [/api/v1/openapi](https://app.documenso.com/api/v1/openapi). This page provides detailed information about the API endpoints, request and response formats, and authentication requirements.
<Callout type="info"> ## Upload a Document
This page is used to demonstrate some of the endpoints and how to use them. For the full API
reference, please see the [API Reference](https://openapi.documenso.com/).
</Callout>
## Get Envelope Uploading a document to your Documenso account requires a two-step process.
For the vast majority of use cases, you will need to retrieve the envelope to get details for further operations. <Steps>
The main details you generally want to extract are the following: ### Create Document
- **Recipients** - The individuals who will be signing the document First, you need to make a `POST` request to the `/api/v1/documents` endpoint, which takes a JSON payload with the following fields:
- **Fields** - The fields the user will sign
- **Items** - The PDF files the user will see and sign
This is done by doing a the following GET [request](https://openapi.documenso.com/reference#tag/envelope/POST/envelope/create)
```sh
curl -X GET "https://app.documenso.com/api/v2/envelope/envelope_xxxxxxxxxxxxx" \
-H "Authorization: api_xxxxxxxxxxxxxx"
```
A successful response looks as follows:
```json ```json
{ {
"internalVersion": 2, "title": "string",
"type": "TEMPLATE", "externalId": "string",
"status": "DRAFT",
"source": "TEMPLATE",
"visibility": "EVERYONE",
"templateType": "PRIVATE",
"id": "envelope_xxxxxxxxxxxxxxxx",
"secondaryId": "template_9",
"externalId": null,
"createdAt": "2025-11-12T11:36:38.391Z",
"updatedAt": "2025-11-12T11:36:55.648Z",
"completedAt": null,
"deletedAt": null,
"title": "Title",
"recipients": [ "recipients": [
{ {
"envelopeId": "envelope_xxxxxxxxxxxxxxxx", "name": "string",
"email": "user@example.com",
"role": "SIGNER", "role": "SIGNER",
"readStatus": "NOT_OPENED", "signingOrder": 0
"signingStatus": "NOT_SIGNED",
"sendStatus": "NOT_SENT",
"id": 0,
"email": "recipient+1@documenso.com",
"name": "",
"token": "cxH2Ss79Hj94M1U3PxRAG",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": [],
"actionAuth": []
},
"signingOrder": 1,
"rejectionReason": null
}
]
"envelopeItems": [
{
"envelopeId": "envelope_xxxxxxxxxxxxxxxx",
"id": "envelope_item_xxxxxxxxxxxxxxxxx",
"title": "FileOne",
"order": 1
} }
], ],
// Other attributes "meta": {
"subject": "string",
"message": "string",
"timezone": "Etc/UTC",
"dateFormat": "yyyy-MM-dd hh:mm a",
"redirectUrl": "string",
"signingOrder": "PARALLEL"
},
"authOptions": {
"globalAccessAuth": "ACCOUNT",
"globalActionAuth": "ACCOUNT"
},
"formValues": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
} }
``` ```
## Create Envelope - `title` _(required)_ - This represents the document's title.
- `externalId` - This is an optional field that you can use to store an external identifier for the document. This can be useful for tracking the document in your system.
This example request will create a document with the following: - `recipients` _(required)_ - This is an array of recipient objects. Each recipient object has the following fields:
- `name` - The name of the recipient.
- Two PDF files - `email` - The email address of the recipient.
- Two recipients with one field each - `role` - The role of the recipient. See the [available roles](/users/signing-documents#roles).
- `signingOrder` - The order in which the recipient should sign the document. This is an integer value starting from 0.
You will need to: - `meta` - This object contains additional metadata for the document. It has the following fields:
- `subject` - The subject of the email that will be sent to the recipients.
- Replace api_xxxxxxxxxxxxxx with your API key - `message` - The message of the email that will be sent to the recipients.
- Replace the file paths with the actual paths to your files - `timezone` - The timezone in which the document should be signed.
- `dateFormat` - The date format that should be used in the document.
Note that the identifier on a field is linking to the files you upload. It can either be the index of the file or the filename. In this example it uses the index of the file. - `redirectUrl` - The URL to which the user should be redirected after signing the document.
- `signingOrder` - The signing order for the document. This can be either `SEQUENTIAL` or `PARALLEL`.
```sh - `authOptions` - This object contains authentication options for the document. It has the following fields:
curl -X POST "https://app.documenso.com/api/v2/envelope/create" \ - `globalAccessAuth` - The authentication level required to access the document. This can be either `ACCOUNT` or `null`.
-H "Authorization: api_xxxxxxxxxxxxxx" \ - If the document is set to `ACCOUNT`, all recipients must authenticate with their Documenso account to access it.
-H "Content-Type: multipart/form-data" \ - The document can be accessed without a Documenso account if it's set to `null`.
-F 'payload={ - `globalActionAuth` - The authentication level required to perform actions on the document. This can be `ACCOUNT`, `PASSKEY`, `TWO_FACTOR_AUTH`, or `null`.
"type": "DOCUMENT", - If the document is set to `ACCOUNT`, all recipients must authenticate with their Documenso account to perform actions on the document.
"title": "Envelope Full Field Test", - If it's set to `PASSKEY`, all recipients must have the passkey active to perform actions on the document.
"recipients": [ - If it's set to `TWO_FACTOR_AUTH`, all recipients must have the two-factor authentication active to perform actions on the document.
{ - If it's set to `null`, all the recipients can perform actions on the document without any authentication.
"email": "recipient+1@example.com", - `formValues` - This object contains additional form values for the document. This property only works with native PDF fields and accepts three types: number, text and boolean.
"name": "Recipient One",
"role": "SIGNER",
"fields": [
{
"identifier": 0,
"type": "SIGNATURE",
"page": 1,
"positionX": 0,
"positionY": 0,
"width": 50,
"height": 50
}
]
},
{
"email": "recipient-2@example.com",
"name": "Recipient Two",
"role": "SIGNER",
"fields": [
{
"identifier": 1,
"type": "SIGNATURE",
"page": 1,
"positionX": 0,
"positionY": 0,
"width": 50,
"height": 50
}
]
}
]
}' \
-F "files=@./field-font-alignment.pdf;type=application/pdf" \
-F "files=@./field-meta.pdf;type=application/pdf"
```
<Callout type="info"> <Callout type="info">
See the full request and response formats for the create endpoint The `globalActionAuth` property is only available for Enterprise accounts.
[here](https://openapi.documenso.com/reference#tag/envelope/POST/envelope/create)
</Callout> </Callout>
## Use Template Here's an example of the JSON payload for uploading a document:
```json
{
"title": "my-document.pdf",
"externalId": "12345",
"recipients": [
{
"name": "Alex Blake",
"email": "alexblake@email.com",
"role": "SIGNER",
"signingOrder": 1
},
{
"name": "Ash Drew",
"email": "ashdrew@email.com",
"role": "SIGNER",
"signingOrder": 0
}
],
"meta": {
"subject": "Sign the document",
"message": "Hey there, please sign this document.",
"timezone": "Europe/London",
"dateFormat": "Day, Month Year",
"redirectUrl": "https://mysite.com/welcome",
"signingOrder": "SEQUENTIAL"
},
"authOptions": {
"globalAccessAuth": "ACCOUNT",
"globalActionAuth": "PASSKEY"
}
}
```
### Upload to S3
A successful API call to the `/api/v1/documents` endpoint returns a JSON response containing the upload URL, document ID, and recipient information.
The upload URL is a pre-signed S3 URL that you can use to upload the document to the Documenso (or your) S3 bucket. You need to make a `PUT` request to this URL to upload the document.
```json
{
"uploadUrl": "https://<url>/<bucket-name>/<id>/my-document.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<credentials>&X-Amz-Date=<date>&X-Amz-Expires=3600&X-Amz-Signature=<signature>&X-Amz-SignedHeaders=host&x-id=PutObject",
"documentId": 51,
"recipients": [
{
"recipientId": 11,
"name": "Alex Blake",
"email": "alexblake@email.com",
"token": "<unique-signer-token>",
"role": "SIGNER",
"signingOrder": 1,
"signingUrl": "https://app.documenso.com/sign/<unique-signer-token>"
},
{
"recipientId": 12,
"name": "Ash Drew",
"email": "ashdrew@email.com",
"token": "<unique-signer-token>",
"role": "SIGNER",
"signingOrder": 0,
"signingUrl": "https://app.documenso.com/sign/<unique-signer-token>"
}
]
}
```
When you make the `PUT` request to the pre-signed URL, you need to include the document file you want to upload. The image below shows how to upload a document to the S3 bucket via Postman.
![Upload document to S3](/api-reference/upload-document-to-s3.webp)
Here's an example of how to upload a document using cURL:
```bash
curl --location --request PUT 'https://<url>/<bucket-name>/<id>/my-document.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<credentials>&X-Amz-Date=<date>&X-Amz-Expires=3600&X-Amz-Signature=<signature>&X-Amz-SignedHeaders=host&x-id=PutObject' \
--form '=@"/Users/my-user/Documents/documenso.pdf"'
```
Once the document is successfully uploaded, you can access it in your Documenso account dashboard. The screenshot below shows the document that was uploaded via the API.
![Uploaded Document](/api-reference/document-uploaded-to-documenso-via-api.webp)
</Steps>
## Generate Document From Template
Documenso allows you to generate documents from templates. This is useful when you have a standard document format you want to reuse. Documenso allows you to generate documents from templates. This is useful when you have a standard document format you want to reuse.
The API endpoint for generating a document from a template is `/api/v2/envelopes/use`, and it takes a JSON payload with the following fields: The API endpoint for generating a document from a template is `/api/v1/templates/{templateId}/generate-document`, and it takes a JSON payload with the following fields:
<Callout type="info"> ```json
See the full request and response formats for the use endpoint {
[here](https://openapi.documenso.com/reference#tag/envelope/POST/envelope/use) "title": "string",
</Callout> "externalId": "string",
"recipients": [
{
"id": 0,
"name": "string",
"email": "user@example.com",
"signingOrder": 0
}
],
"meta": {
"subject": "string",
"message": "string",
"timezone": "string",
"dateFormat": "string",
"redirectUrl": "string",
"signingOrder": "PARALLEL"
},
"authOptions": {
"globalAccessAuth": "ACCOUNT",
"globalActionAuth": "ACCOUNT"
},
"formValues": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
}
```
The JSON payload is identical to the payload for uploading a document, so you can read more about the fields in the [Create Document](/developers/public-api/reference#create-document) step. For this API endpoint, the `recipients` property is required.
<Steps> <Steps>
### Grab the Template ID ### Grab the Template ID
The first step is to retrieve the ID of the template you want to use. This can be done via the API or from the Documenso UI. The first step is to retrieve the template ID from the Documenso dashboard. You can find the template ID in the URL by navigating to the template details page.
You can get the ID by navigating to the template page and looking at the URL. The ID is the last part of the URL which looks like this "envelope_xxxxxxxx" ![Template ID](/api-reference/documenso-template-id.webp)
In this case, the template ID is "99999".
### Retrieve the Recipient(s) ID(s) ### Retrieve the Recipient(s) ID(s)
Once you have the template ID, you will want to retrieve the full template so you can see the recipients. Once you have the template ID, the next step involves retrieving the ID(s) of the recipient(s) from the template. You can do this by making a GET request to `/api/v1/templates/{template-id}`.
This is optional, and you only will want to do this if you want to modify the recipient details prior to creating the new document. A successful response looks as follows:
See the [Get Envelope](#get-envelope) section for more details on how to retrieve the envelope.
### Generate the Document
To generate a document from the template, you need to make a POST request to the [`/api/v2/envelope/use`](https://openapi.documenso.com/reference#tag/envelope/POST/envelope/use) endpoint.
You will need to replace the following:
- `api_xxxxxxxxxxxxxx` with your API key
- `envelope_xxxxxxxxxxxxxxx` with the template ID
- `RECIPIENT_ID_HERE` with the recipient ID you want to modify prior to sending
- `RECIPIENT_EMAIL_HERE` with the new recipient email you want to use
- `RECIPIENT_NAME_HERE` with the new recipient name you want to use
If you want to send the document immediately, you can add the `distributeDocument` parameter to the payload.
```sh
curl -X POST "https://app.documenso.com/api/v2/envelope/use" \
-H "Authorization: api_xxxxxxxxxxxxxx" \
-H "Content-Type: multipart/form-data" \
-F 'payload={
"envelopeId": "envelope_xxxxxxxxxxxxxxx",
"recipients": [
{
"id": RECIPIENT_ID_HERE,
"email": "RECIPIENT_EMAIL_HERE",
"name": "RECIPIENT_NAME_HERE"
}
]
}'
```
#### Generate the Document with Custom Files
You can also generate a document from a template using custom PDF files to replace the template's default PDF files.
To do this, you will need to grab the `envelopeItemId` of the item you want to replace, this is found in the GET request in the previous step.
You will need to replace the following:
- `CUSTOM_FILE_NAME_HERE.pdf` with the custom file name
- `envelope_item_xxxxxxxxxxxxxxxxx` with the `envelopeItemId` of the item you want to replace
```sh
curl -X POST "https://app.documenso.com/api/v2/envelope/use" \
-H "Authorization: api_xxxxxxxxxxxxxx" \
-H "Content-Type: multipart/form-data" \
-F 'payload={
"envelopeId": "envelope_xxxxxxxxxxxxxxx",
"recipients": [
{
"id": RECIPIENT_ID_HERE,
"email": "RECIPIENT_EMAIL_HERE",
"name": "RECIPIENT_NAME_HERE"
}
],
"customDocumentData": [
{
"identifier": "CUSTOM_FILE_NAME_HERE.pdf",
"envelopeItemId": "envelope_item_xxxxxxxxxxxxxxxxx"
}
]
}' \
-F "files=@./CUSTOM_FILE_NAME_HERE.pdf;type=application/pdf"
```
You can now access the document in your Documenso account dashboard.
#### Pre-fill Fields On Document Creation
The API allows you to pre-fill fields on document creation. This is useful when you want to create a document from an existing template and pre-fill the fields with specific values.
```json ```json
{ {
"id": 0,
"externalId": "string",
"type": "PUBLIC",
"title": "string",
"userId": 0,
"teamId": 0,
"templateDocumentDataId": "string",
"createdAt": "2024-10-11T08:46:58.247Z",
"updatedAt": "2024-10-11T08:46:58.247Z",
"templateMeta": {
"id": "string",
"subject": "string",
"message": "string",
"timezone": "string",
"dateFormat": "string",
"templateId": 0,
"redirectUrl": "string",
"signingOrder": "PARALLEL"
},
"directLink": {
"token": "string",
"enabled": true
},
"templateDocumentData": {
"id": "string",
"type": "S3_PATH",
"data": "string"
},
"Field": [
{
"id": 0,
"recipientId": 0,
"type": "SIGNATURE",
"page": 0,
"positionX": "string",
"positionY": "string",
"width": "string",
"height": "string"
}
],
"Recipient": [
{
"id": 0,
"email": "user@example.com",
"name": "string",
"signingOrder": 0,
"authOptions": "string",
"role": "CC"
}
]
}
```
You'll need the recipient(s) ID(s) for the next step.
### Generate the Document
To generate a document from the template, you need to make a POST request to the `/api/v1/templates/{template-id}/generate-document` endpoint.
At the minimum, you must provide the `recipients` array in the JSON payload. Here's an example of the JSON payload:
```json
{
"recipients": [
{
"id": 0,
"name": "Ash Drew",
"email": "ashdrew@email.com",
"signingOrder": 0
}
]
}
```
Filling the `recipients` array with the corresponding recipient for each template placeholder recipient is recommended. For example, if the template has two placeholders, you should provide at least two recipients in the `recipients` array. Otherwise, the document will be sent to inexistent recipients such as `<recipient.1@documenso.com>`. However, the recipients can always be edited via the API or the web app.
A successful response will contain the document ID and recipient(s) information.
```json
{
"documentId": 999,
"recipients": [
{
"recipientId": 0,
"name": "Ash Drew",
"email": "ashdrew@email.com",
"token": "<signing-token>",
"role": "SIGNER",
"signingOrder": null,
"signingUrl": "https://app.documenso.com/sign/<signing-token>"
}
]
}
```
You can now access the document in your Documenso account dashboard. The screenshot below shows the document that was generated from the template.
![Generated Document](/api-reference/document-generated-from-template.webp)
</Steps>
## Add Fields to Document
The API allows you to add fields to a document via the `/api/v1/documents/{documentId}/fields` endpoint. This is useful when you want to add fields to a document before sending it to recipients.
To add fields to a document, you need to make a `POST` request with a JSON payload containing the field(s) information.
```json
{
"recipientId": 0,
"type": "SIGNATURE",
"pageNumber": 0,
"pageX": 0,
"pageY": 0,
"pageWidth": 0,
"pageHeight": 0,
"fieldMeta": {
"label": "string",
"placeholder": "string",
"required": true,
"readOnly": true,
"type": "text",
"text": "string",
"characterLimit": 0
}
}
// or
[
{
"recipientId": 0,
"type": "SIGNATURE",
"pageNumber": 0,
"pageX": 0,
"pageY": 0,
"pageWidth": 0,
"pageHeight": 0
},
{
"recipientId": 0,
"type": "TEXT",
"pageNumber": 0,
"pageX": 0,
"pageY": 0,
"pageWidth": 0,
"pageHeight": 0,
"fieldMeta": {
"label": "string",
"placeholder": "string",
"required": true,
"readOnly": true,
"type": "text",
"text": "string",
"characterLimit": 0
}
}
]
```
<Callout type="info">This endpoint accepts either one field or an array of fields.</Callout>
Before adding fields to a document, you need each recipient's ID. If the document already has recipients, you can query the document to retrieve the recipient's details. If the document has no recipients, you need to add a recipient via the UI or API before adding a field.
<Steps>
### Retrieve the Recipient(s) ID(s)
Perform a `GET` request to the `/api/v1/documents/{id}` to retrieve the details of a specific document, including the recipient's information.
An example response would look like this:
```json
{
"id": 137,
"externalId": null,
"userId": 3,
"teamId": null,
"title": "documenso.pdf",
"status": "DRAFT",
"documentDataId": "<document-data-id>",
"createdAt": "2024-10-11T12:29:12.725Z",
"updatedAt": "2024-10-11T12:29:12.725Z",
"completedAt": null,
"recipients": [
{
"id": 55,
"documentId": 137,
"email": "ashdrew@email.com",
"name": "Ash Drew",
"role": "SIGNER",
"signingOrder": null,
"token": "<signing-token>",
"signedAt": null,
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "NOT_SENT",
"signingUrl": "https://app.documenso.com/sign/<signing-token>"
}
]
}
```
From this response, you'll only need the recipient ID, which is `55` in this case.
### (OR) Add a Recipient
If the document doesn't already have recipient(s), you can add recipient(s) via the API. Make a `POST` request to the `/api/v1/documents/{documentId}/recipients` endpoint with the recipient information. This endpoint takes the following JSON payload:
```json
{
"name": "string",
"email": "user@example.com",
"role": "SIGNER",
"signingOrder": 0,
"authOptions": {
"actionAuth": "ACCOUNT"
}
}
```
<Callout type="info">The `authOptions` property is only available for Enterprise accounts.</Callout>
Here's an example of the JSON payload for adding a recipient:
```json
{
"name": "Ash Drew",
"email": "ashdrew@email.com",
"role": "SIGNER",
"signingOrder": 0
}
```
A successful request will return a JSON response with the newly added recipient. You can now use the recipient ID to add fields to the document.
### Add Field(s)
Now you can make a `POST` request to the `/api/v1/documents/{documentId}/fields` endpoint with the field(s) information. Here's an example:
```json
[
{
"recipientId": 55,
"type": "SIGNATURE",
"pageNumber": 1,
"pageX": 50,
"pageY": 20,
"pageWidth": 25,
"pageHeight": 5
},
{
"recipientId": 55,
"type": "TEXT",
"pageNumber": 1,
"pageX": 20,
"pageY": 50,
"pageWidth": 30,
"pageHeight": 7.5,
"fieldMeta": {
"label": "Address",
"placeholder": "32 New York Street, 41241",
"required": true,
"readOnly": false,
"type": "text",
"text": "32 New York Street, 41241",
"characterLimit": 40
}
}
]
```
<Callout type="info">
The `text` field represents the default value of the field. If the user doesn't provide any other
value, this is the value that will be used to sign the field.
</Callout>
<Callout type="warning">
It's important to pass the `type` in the `fieldMeta` property for the advanced fields. [Read more
here](#a-note-on-advanced-fields)
</Callout>
A successful request will return a JSON response with the newly added fields. The image below illustrates the fields added to the document via the API.
![A screenshot of the document in the Documenso editor](/api-reference/fields-added-via-api.webp)
</Steps>
#### A Note on Advanced Fields
The advanced fields are: text, checkbox, radio, number, and select. Whenever you append any of these advanced fields to a document, you need to pass the `type` in the `fieldMeta` property:
```json
...
"fieldMeta": {
"type": "text",
}
...
```
Replace the `text` value with the corresponding field type:
- For the `TEXT` field it should be `text`.
- For the `CHECKBOX` field it should be `checkbox`.
- For the `RADIO` field it should be `radio`.
- For the `NUMBER` field it should be `number`.
- For the `SELECT` field it should be `select`. (check this before merge)
You must pass this property at all times, even if you don't need to set any other properties. If you don't, the endpoint will throw an error.
## Pre-fill Fields On Document Creation
The API allows you to pre-fill fields on document creation. This is useful when you want to create a document from an existing template and pre-fill the fields with specific values.
To pre-fill a field, you need to make a `POST` request to the `/api/v1/templates/{templateId}/generate-document` endpoint with the field information. Here's an example:
```json
{
"title": "my-document.pdf",
"recipients": [
{
"id": 3,
"name": "Example User",
"email": "example@documenso.com",
"signingOrder": 1,
"role": "SIGNER"
}
],
"prefillFields": [ "prefillFields": [
{ {
"id": 21, "id": 21,
@ -270,96 +574,51 @@ The API allows you to pre-fill fields on document creation. This is useful when
"value": ["option-1", "option-2"] "value": ["option-1", "option-2"]
} }
] ]
// Other payload properties...
} }
``` ```
</Steps> Check out the endpoint in the [API V1 documentation](https://app.documenso.com/api/v1/openapi#:~:text=/%7BtemplateId%7D/-,generate,-%2Ddocument).
## Add Recipients ### API V2
The API allows you to add recipients to an envelope via the [`/api/v2/envelope/recipient/create-many`](https://openapi.documenso.com/reference#tag/envelope-recipients/POST/envelope/recipient/create-many) endpoint. For API V2, you need to make a `POST` request to the `/api/v2-beta/template/use` endpoint with the field(s) information. Here's an example:
The following is an example of a request which creates 2 new recipients on the envelope. ```json
{
```sh "templateId": 111,
curl https://app.documenso.com/api/v2/envelope/recipient/create-many \ "recipients": [
--request POST \ {
--header 'Authorization: api_xxxxxxxxxxxxxx' \ "id": 3,
--header 'Content-Type: application/json' \ "name": "Example User",
--data '{ "email": "example@documenso.com",
"envelopeId": "envelope_brxkyaxywuxkyeuv", "signingOrder": 1,
"data": [ "role": "SIGNER"
{ }
"name": "Recipient Name", ],
"email": "example@documenso.com", "prefillFields": [
"role": "SIGNER" {
}, "id": 21,
{ "type": "text",
"name": "Recipient Two", "label": "my-label",
"email": "example+2@documenso.com", "placeholder": "my-placeholder",
"role": "APPROVER" "value": "my-value"
} },
] {
}' "id": 22,
"type": "number",
"label": "my-label",
"placeholder": "my-placeholder",
"value": "123"
},
{
"id": 23,
"type": "checkbox",
"label": "my-label",
"placeholder": "my-placeholder",
"value": ["option-1", "option-2"]
}
]
}
``` ```
## Add Fields Check out the endpoint in the [API V2 documentation](https://openapi.documenso.com/reference#tag/template/POST/template/use).
The API allows you to add fields to an envelope via the [`/api/v2/envelope/field/create-many`](https://openapi.documenso.com/reference#tag/envelope-fields/POST/envelope/field/create-many) endpoint.
Before adding fields to an envelope, you will need the following details:
- **Envelope ID** - Which envelope the field will be added to
- **Recipient ID** - Which recipient the field will be added to
- **Envelope Item ID** - Which file the field will be added to. If blank, the field will be added to the first file.
See the [Get Envelope](#get-envelope) section for more details on how to retrieve these details.
The following is an example of a request which creates 2 new fields on the first page of the envelope.
Note that width, height, positionX and positionY are percentage numbers between 0 and 100, which scale the field relative to the size of the PDF.
```sh
curl https://app.documenso.com/api/v2/envelope/field/create-many \
--request POST \
--header 'Authorization: api_xxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"envelopeId": "envelope_xxxxxxxxxx",
"data": [
{
"recipientId": recipient_id_here,
"envelopeItemId": "envelope_item_id_here",
"type": "TEXT",
"page": 1,
"positionX": 0,
"positionY": 0,
"width": 50,
"height": 50,
"fieldMeta": {
"type": "text",
"label": "First test field"
}
},
{
"recipientId": recipient_id_here,
"envelopeItemId": "envelope_item_id_here",
"type": "TEXT",
"page": 1,
"positionX": 50,
"positionY": 50,
"width": 50,
"height": 50,
"fieldMeta": {
"type": "text",
"label": "Second test field"
}
}
]
}'
```
Field meta allows you to further configure fields, for example it will allow you to add multiple items for checkboxes or radios.
A successful request will return a JSON response with the newly added fields.

View File

@ -9,9 +9,9 @@ import { Callout } from 'nextra/components';
Documenso uses API versioning to manage changes to the public API. This allows us to introduce new features, fix bugs, and make other changes without breaking existing integrations. Documenso uses API versioning to manage changes to the public API. This allows us to introduce new features, fix bugs, and make other changes without breaking existing integrations.
<Callout type="info">The current version of the API is `v2`.</Callout> <Callout type="info">The current version of the API is `v1`.</Callout>
The API version is specified in the URL. For example, the base URL for the `v2` API is `https://app.documenso.com/api/v2`. The API version is specified in the URL. For example, the base URL for the `v1` API is `https://app.documenso.com/api/v1`.
We may make changes to the API without incrementing the version number. We will always try to avoid breaking changes, but in some cases, it may be necessary to make changes that are not backward compatible. In these cases, we will increment the version number and provide information about the changes in the release notes. We may make changes to the API without incrementing the version number. We will always try to avoid breaking changes, but in some cases, it may be necessary to make changes that are not backward compatible. In these cases, we will increment the version number and provide information about the changes in the release notes.

View File

@ -54,7 +54,7 @@ Install the project dependencies as follows:
```bash ```bash
npm i npm i
npm run build npm run build:web
npm run prisma:migrate-deploy npm run prisma:migrate-deploy
``` ```
@ -69,7 +69,7 @@ npm run start
This will start the server on `localhost:3000`. Any reverse proxy can handle the front end and SSL termination. This will start the server on `localhost:3000`. Any reverse proxy can handle the front end and SSL termination.
<Callout type="info"> <Callout type="info">
If you want to run with another port than `3000`, you can start the application with `next -p <ANY PORT>` from the `apps/remix` folder. If you want to run with another port than `3000`, you can start the application with `next -p <ANY PORT>` from the `apps/web` folder.
</Callout> </Callout>
</Steps> </Steps>
@ -119,89 +119,16 @@ NEXT_PRIVATE_SMTP_USERNAME="<your-username>"
NEXT_PRIVATE_SMTP_PASSWORD="<your-password>" NEXT_PRIVATE_SMTP_PASSWORD="<your-password>"
``` ```
### Set Up Your Signing Certificate ### Update the Volume Binding
<Callout type="warning"> The `cert.p12` file is required to sign and encrypt documents, so you must provide your key file. Update the volume binding in the `compose.yml` file to point to your key file:
This is the most common source of issues for self-hosters. Please follow these steps carefully.
</Callout>
The `cert.p12` file is required to sign and encrypt documents. You have three options: ```yaml
volumes:
- /path/to/your/keyfile.p12:/opt/documenso/cert.p12
```
#### Option A: Generate Certificate Inside Container (Recommended) After updating the volume binding, save the `compose.yml` file and run the following command to start the containers:
This method avoids file permission issues by creating the certificate directly inside the Docker container:
1. Start your containers:
```bash
docker-compose up -d
```
2. Set certificate password securely and generate certificate inside the container:
```bash
# Set certificate password securely (won't appear in command history)
read -s -p "Enter certificate password: " CERT_PASS
echo
# Generate certificate inside container using environment variable
docker exec -e CERT_PASS="$CERT_PASS" -it documenso-production-documenso-1 bash -c "
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /tmp/private.key \
-out /tmp/certificate.crt \
-subj '/C=US/ST=State/L=City/O=Organization/CN=localhost' && \
openssl pkcs12 -export -out /app/certs/cert.p12 \
-inkey /tmp/private.key -in /tmp/certificate.crt \
-passout env:CERT_PASS && \
rm /tmp/private.key /tmp/certificate.crt
"
```
3. Add the certificate passphrase to your `.env` file:
```bash
NEXT_PRIVATE_SIGNING_PASSPHRASE="your_password_here"
```
4. Restart the container to apply changes:
```bash
docker-compose restart documenso
```
#### Option B: Use an Existing Certificate File
If you have an existing `.p12` certificate file:
1. **Place your certificate file** in an accessible location on your host system
2. **Set proper permissions:**
```bash
# Make sure the certificate is readable
chmod 644 /path/to/your/cert.p12
# For Docker, ensure proper ownership
chown 1001:1001 /path/to/your/cert.p12
```
3. **Update the volume binding** in the `compose.yml` file:
```yaml
volumes:
- /path/to/your/cert.p12:/opt/documenso/cert.p12:ro
```
4. **Add certificate configuration** to your `.env` file:
```bash
NEXT_PRIVATE_SIGNING_LOCAL_FILE_PATH=/opt/documenso/cert.p12
NEXT_PRIVATE_SIGNING_PASSPHRASE=your_certificate_password
```
<Callout type="warning">
Your certificate MUST have a password. Certificates without passwords will cause "Failed to get
private key bags" errors.
</Callout>
After setting up your certificate, save the `compose.yml` file and run the following command to start the containers:
```bash ```bash
docker-compose --env-file ./.env up -d docker-compose --env-file ./.env up -d
@ -322,7 +249,7 @@ After=network.target
Environment=PATH=/path/to/your/node/binaries Environment=PATH=/path/to/your/node/binaries
Type=simple Type=simple
User=www-data User=www-data
WorkingDirectory=/var/www/documenso/apps/remix WorkingDirectory=/var/www/documenso/apps/web
ExecStart=/usr/bin/next start -p 3500 ExecStart=/usr/bin/next start -p 3500
TimeoutSec=15 TimeoutSec=15
Restart=always Restart=always

View File

@ -27,33 +27,3 @@ NEXT_PRIVATE_GOOGLE_CLIENT_SECRET=<your-client-secret>
``` ```
Finally verify the signing in with Google works by signing in with your Google account and checking the email address in your profile. Finally verify the signing in with Google works by signing in with your Google account and checking the email address in your profile.
## Microsoft OAuth (Azure AD)
To use Microsoft OAuth, you will need to create an Azure AD application registration in the Microsoft Azure portal. This will allow users to sign in with their Microsoft accounts.
### Create and configure a new Azure AD application
1. Go to the [Azure Portal](https://portal.azure.com/)
2. Navigate to **Azure Active Directory** (or **Microsoft Entra ID** in newer Azure portals)
3. In the left sidebar, click **App registrations**
4. Click **New registration**
5. Enter a name for your application (e.g., "Documenso")
6. Under **Supported account types**, select **Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)** to allow any Microsoft account to sign in
7. Under **Redirect URI**, select **Web** and enter: `https://<documenso-domain>/api/auth/callback/microsoft`
8. Click **Register**
### Configure the application
1. After registration, you'll be taken to the app's overview page
2. Copy the **Application (client) ID** - this will be your `NEXT_PRIVATE_MICROSOFT_CLIENT_ID`
3. In the left sidebar, click **Certificates & secrets**
4. Under **Client secrets**, click **New client secret**
5. Add a description and select an expiration period
6. Click **Add** and copy the **Value** (not the Secret ID) - this will be your `NEXT_PRIVATE_MICROSOFT_CLIENT_SECRET`
7. In the Documenso environment variables, set the following:
```
NEXT_PRIVATE_MICROSOFT_CLIENT_ID=<your-application-client-id>
NEXT_PRIVATE_MICROSOFT_CLIENT_SECRET=<your-client-secret-value>
```

View File

@ -619,18 +619,6 @@ Example payload for the `document.rejected` event:
} }
``` ```
## Webhook Events Testing
You can trigger test webhook events to test the webhook functionality. To trigger a test webhook, navigate to the [Webhooks page](/developers/webhooks) and click on the "Test Webhook" button.
![Documenso's Webhooks Page](/webhook-images/test-webhooks-page.webp)
This opens a dialog where you can select the event type to test.
![Documenso's individual webhook page](/webhook-images/test-webhook-dialog.webp)
Choose the appropriate event and click "Send Test Webhook." Youll shortly receive a test payload from Documenso with sample data.
## Availability ## Availability
Webhooks are available to individual users and teams. Webhooks are available to individual users and teams.

View File

@ -6,13 +6,11 @@
"title": "How To Use" "title": "How To Use"
}, },
"get-started": "Get Started", "get-started": "Get Started",
"profile": "Public Profile", "profile": "User Profile",
"organisations": "Organisations", "signing-documents": "Signing Documents",
"documents": "Documents",
"templates": "Templates", "templates": "Templates",
"branding": "Branding",
"email-domains": "Email Domains",
"direct-links": "Direct Signing Links", "direct-links": "Direct Signing Links",
"teams": "Teams",
"-- Legal Overview": { "-- Legal Overview": {
"type": "separator", "type": "separator",
"title": "Legal Overview" "title": "Legal Overview"

View File

@ -1,28 +0,0 @@
---
title: Branding Preferences
description: Learn how to set the branding preferences for your team account.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Branding Preferences
Branding preferences allow you to set the default settings when emailing documents to your recipients.
## Preferences
Branding preferences can be set on either the organisation or team level.
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
To access the preferences, navigate to either the organisation or teams settings page and click the **Branding** tab under the **Preferences** section.
![A screenshot of the organisation's document preferences page](/organisations/organisation-branding.webp)
On this page, you can:
- **Upload a Logo** - Upload your team's logo to be displayed instead of the default Documenso logo.
- **Set the Brand Website** - Enter the URL of your team's website to be displayed in the email communications sent by the team.
- **Add Additional Brand Details** - You can add additional information to display at the bottom of the emails sent by the team. This can include contact information, social media links, and other relevant details.

View File

@ -19,13 +19,13 @@ device, and other FDA-regulated industries.
- [x] User Access Management - [x] User Access Management
- [x] Quality Assurance Documentation - [x] Quality Assurance Documentation
## SOC 2 ## SOC/ SOC II
<Callout type="info" emoji=""> <Callout type="warning" emoji="">
Status: [Compliant](https://documen.so/trust) Status: [Planned](https://github.com/documenso/backlog/issues/24)
</Callout> </Callout>
SOC 2 is a framework for managing and auditing the security, availability, processing integrity, confidentiality, SOC II is a framework for managing and auditing the security, availability, processing integrity, confidentiality,
and data privacy in cloud and IT service organizations, established by the American Institute of Certified and data privacy in cloud and IT service organizations, established by the American Institute of Certified
Public Accountants (AICPA). Public Accountants (AICPA).
@ -34,9 +34,9 @@ Public Accountants (AICPA).
<Callout type="warning" emoji="⏳"> <Callout type="warning" emoji="⏳">
Status: [Planned](https://github.com/documenso/backlog/issues/26) Status: [Planned](https://github.com/documenso/backlog/issues/26)
</Callout> </Callout>
ISO 27001 is an international standard for managing information security, specifying requirements ISO 27001 is an international standard for managing information security, specifying requirements for
for establishing, implementing, maintaining, and continually improving an information security establishing, implementing, maintaining, and continually improving an information security management
management system (ISMS). system (ISMS).
### HIPAA ### HIPAA

View File

@ -1,7 +0,0 @@
{
"sending-documents": "Sending Documents",
"document-preferences": "Document Preferences",
"document-visibility": "Document Visibility",
"fields": "Document Fields",
"email-preferences": "Email Preferences"
}

View File

@ -1,44 +0,0 @@
---
title: Preferences
description: Learn how to manage your team's global preferences.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Document Preferences
Document preferences allow you to set the default settings when creating new documents and templates.
For example, you can set the default language for documents sent by the team, or set the allowed signatures types.
## Preferences
Document preferences can be set on either the organisation or team level.
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
To access the preferences, navigate to either the organisation or teams settings page and click the **Document** tab under the **Preferences** section.
![A screenshot of the organisation's document preferences page](/organisations/organisation-document-preferences.webp)
- **Document Visibility** - Set the default visibility of the documents created by team members. Learn more about [document visibility](/users/documents/document-visibility).
- **Default Document Language** - This setting allows you to set the default language for the documents uploaded in the organisation. The default language is used as the default language in the email communications with the document recipients.
- **Default Time Zone** - The timezone to use for date fields and signing the document.
- **Default Date Format** - The date format to use for date fields and signing the document.
- **Signature Settings** - Controls what signatures are allowed to be used when signing the documents.
- **Sender Details** - Set whether the sender's name should be included in the emails sent by the team. See more below [sender details](/users/documents/document-preferences#sender-details).
- **Include the Signing Certificate** - This setting controls whether the signing certificate should be included in the signed documents. If enabled, the signing certificate is included in the signed documents. If disabled, the signing certificate is not included in the signed documents. Regardless of this setting, the signing certificate is always available in the document's audit log page.
Document visibility, language and signature settings can be overriden on a per document basis.
### Sender Details
If the **Sender Details** setting is enabled, the emails sent by the team will include the sender's name. The email will say:
> "Example User" on behalf of "Example Team" has invited you to sign "document.pdf"
If the **Sender Details** setting is disabled, the emails sent by the team will not include the sender's name. The email will say:
> "Example Team" has invited you to sign "document.pdf"

View File

@ -1,26 +0,0 @@
---
title: Email Preferences
description: Learn how to set the email preferences for your team account.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Email Preferences
Email preferences allow you to set the default settings when emailing documents to your recipients.
## Preferences
Email preferences can be set on either the organisation or team level.
By default, teams inherit the preferences from the organisation. You can override these preferences on the team level at any time.
To access the preferences, navigate to either the organisation or teams settings page and click the **Email** tab under the **Preferences** section.
![A screenshot of the organisation's email preferences page](/organisations/organisation-email-preferences.webp)
- **Default Email** - Use a custom email address when sending documents to your recipients. See [email domains](/users/email-domains) for more information.
- **Reply To** - The email address that will be used in the "Reply To" field in emails
- **Email Settings** - Which emails to send to recipients during document signing

View File

@ -1,199 +0,0 @@
---
title: Document Fields
description: Learn about the different fields you can add to your documents in Documenso.
---
# Document Fields
Learn about the different fields you can add to your documents in Documenso and how to make the most of them.
## Signature Field
The signature field collects the signer's signature. It's required for each recipient with the "Signer" role.
![The signature field in the Documenso document editor](/document-signing/signature-field-document-editor-view.webp)
The signature field settings include:
- **Font size** - The typed signature font size. You can disable typed signatures in the document settings.
## Email Field
The email field is used to collect the signer's email address. This will be the email address you entered when you created the recipients.
![The email field in the Documenso document editor](/document-signing/email-field-document-editor-view.webp)
The email field settings include:
- **Font Size** - The font size of the email address.
- **Text Align** - The horizontal text alignment of the email address.
## Name Field
The name field is used to collect the signer's name.
![The name field in the Documenso document editor](/document-signing/name-field-document-editor-view.webp)
The name field settings include:
- **Font Size** - The font size of the name.
- **Text Align** - The horizontal text alignment of the name.
## Initials Field
The initials field is used to collect the signer's initials. This is generally the first and last name initials.
![The initials field in the Documenso document editor](/document-signing/initials-field-document-editor-view.webp)
The initials field settings include:
- **Font Size** - The font size of the initials.
- **Text Align** - The horizontal text alignment of the initials.
## Date Field
The date field is used to collect the date of the signature. You can change the date format in the document settings.
![The date field in the Documenso document editor](/document-signing/date-field-document-editor-view.webp)
The date field settings include:
- **Font Size** - The font size of the date.
- **Text Align** - The horizontal text alignment of the date.
## Text Field
The text field is used to collect text input from the signer.
Place the text field on the document where you want the signer to enter text. The text field comes with additional settings that can be configured.
![The text field in the Documenso document editor](/document-signing/text-field-document-editor-view.webp)
The text field settings include:
- **Label** - The label displayed in the field when the user opens the document to sign
- **Placeholder** - The placeholder text displayed in the field. The signer will see this prior to signing.
- **Text** - The text which will be prefilled into the field. The signer can change this text unless the field is read-only.
- **Character limit** - The maximum number of characters allowed in the field.
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Text Align** - The horizontal text alignment of the text in the field.
- **Vertical Align** - The vertical text alignment of the text in the field.
- **Line height** - The line height of the text in the field. Useful for multi-line text fields.
- **Letter spacing** - The spacing between each character in the text in the field.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty text field. It must have a default text value.
- The signer must fill out a required field.
- The text field characters count can't exceed the character limit.
- The signer can't modify a read-only field.
- The field will be inserted automatically into the document if there is a default text value.
## Number Field
The number field is used for collecting a number input from the signer.
![The number field in the Documenso document editor](/document-signing/number-field-document-editor-view.webp)
The number field settings include:
- **Label** - The label displayed is the field.
- **Placeholder** - The placeholder text displayed in the field.
- **Value** - The value which will be prefilled into the field. The signer can change this value unless the field is read-only.
- **Number format** - The format of the number.
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Text Align** - The horizontal text alignment of the number in the field.
- **Vertical Align** - The vertical text alignment of the number in the field.
- **Line height** - The line height of the number in the field. Useful for multi-line number fields.
- **Letter spacing** - The spacing between each character in the number in the field.
- **Validation** - The validation rules for the field.
It also comes with a couple of rules:
- The value must be a number.
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty number field. It must have a default number value.
- The signer must fill out a required field.
- If the default number and a max value are set, the default number must be less than the max value.
- If the default number and a min value are set, the default number must be greater than the min value.
- The value must match the number format if a number format is set.
## Radio Field
The radio field is used to collect a single choice from the signer.
![The radio field in the Documenso document editor](/document-signing/radio-field-document-editor-view.webp)
The radio field settings include:
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Values** - The list of choices for the field.
- **Direction** - The direction of the radio field. Can be "Vertical" or "Horizontal".
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty radio field. It must have at least one option.
- The signer must fill out a required field.
- The field auto-signs if there is a default value.
- The signer can't sign with a value not in the options list.
- The signer can't modify the field if it's read-only.
- It should contain at least one option.
- The field can't have more than one option selected.
## Checkbox Field
The checkbox field is used to collect multiple choices from the signer.
Place the checkbox field on the document where you want the signer to select choices. The checkbox field comes with additional settings that can be configured.
![The checkbox field in the Documenso document editor](/document-signing/checkbox-field-document-editor-view.webp)
The checkbox field settings include the following:
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Options** - The list of choices for the field.
- **Direction** - The direction of the checkbox field. Can be "Vertical" or "Horizontal".
- **Validation Rule** - The rule specifies "At least", "At most", and "Exactly".
- **Validation Number** - The number of choices that must be selected.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty checkbox field. It must have at least one checked option.
- The signer must fill out a required field.
- The field auto-signs if there is a default value.
- The signer can't sign with a value not in the options list.
- The signer can't modify the field if it's read-only.
- It should contain at least one option.
## Dropdown/Select Field
The dropdown/select field collects a single choice from a list of options.
Place the dropdown/select field on the document where you want the signer to select a choice. The dropdown/select field comes with additional settings that can be configured.
![The dropdown/select field in the Documenso document editor](/document-signing/dropdown-field-document-editor-view.webp)
The dropdown/select field settings include:
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Options** - The list of choices for the field.
- **Default Value** - The default value selected in the field.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty select field. It must have a default value.
- The signer must fill out a required field.
- The default value must be one of the options.
- The field auto-signs if there is a default value.
- The field can't be signed with a value not in the options list.
- The signer can't modify the field if it's read-only.
- It should contain at least one option.

View File

@ -1,209 +0,0 @@
---
title: Send a document for signing
description: The guide gives a detailed description of all options available when sending out a document for signing.
---
import { Callout, Steps } from 'nextra/components';
# Send Documents for Signing
This guide will walk you through the process of sending a document out for signing. You will learn how to upload a document, add recipients, place signature fields, and send the document for signing.
## Uploading a Document
<Steps>
### Log In to Your Account
The guide assumes you have a Documenso account. If you don't, you can create a free account [here](https://documen.so/free-docs).
### Upload Document
Navigate to the [Documenso dashboard](https://app.documenso.com/documents) and click on the "Upload Document" button located at the top right of the page. Select the documents you want to upload and wait for the upload to complete.
<Callout type="info">
The maximum file size for uploaded documents is 150MB in production. You can upload up to 5
documents at a time on standard plans. In staging, the limit is 50MB.
</Callout>
![Documenso dashboard](/document-signing/documenso-documents-dashboard.webp)
After the upload is complete, you will be redirected to the editor. You can configure the document's settings and add recipients and fields here.
</Steps>
## Configuring and Sending Document
The Documenso editor allows you to create and configure documents or templates. The editor consists of three sections that guide you through the process of preparing your document.
1. **Document & Recipients** - Upload files and add recipients
2. **Add Fields** - Add fields to the document
3. **Preview** - Preview the document before sending
You can click each section to navigate to it, and the current section will be highlighted in the sidebar.
![Editor page in the Documenso dashboard](/document-signing/editor-overview.webp)
There is also a quick actions section on the left-hand side which allows you to:
- **Document Settings** - Configure general settings, emails, or security settings for the document
- **Send Document** - Send the document to the recipients
- **Duplicate** - Duplicate the document
- **Download** - Download the document PDF
- **Delete** - Delete the document
The header contains some notable items:
- **Title** - You can edit the title in the top-left corner of the header by clicking on the text
- **Status** - You can see the current status of the document next to the title
- **Attachments** - You can configure the attachments on the right-hand side of the header
<Steps>
### Upload Documents and Add Recipients
The first step in the editor is to upload your document and add recipients.
![Upload and add recipients page in the Documenso editor](/document-signing/editor-upload-recipients.webp)
#### Upload Document
You can upload documents by either clicking the "Add a document" dropzone, or dragging and dropping files into the dropzone.
<Callout type="info">
The maximum file size for uploaded documents is 150MB in production. You can upload up to 5
documents at a time on standard plans. In staging, the limit is 50MB.
</Callout>
#### Add Recipients
Click the "+ Add Signer" button to add a new recipient. For each recipient you can configure the following:
- **Email address** - The recipient's email address
- **Name** - The recipient's name
- **Order** - The sequence in which the recipient should sign the document. Only available if the "Enable Signing Order" checkbox is enabled
- **Role** - As seen below
Documenso has 5 roles for recipients with different permissions and actions.
| Role | Function | Action required | Signature |
| :-------: | :-----------------------------------------------------------------------------: | :-------------: | :-------: |
| Signer | Needs to sign signature fields assigned to them. | Yes | Yes |
| Approver | Needs to approve the document as a whole. Signature optional. | Yes | Optional |
| Viewer | Needs to confirm they viewed the document. | Yes | No |
| Assistant | Can help prepare the document by filling in fields on behalf of other signers. | Yes | No |
| CC | Receives a copy of the signed document after completion. No action is required. | No | No |
### Fields
Documenso supports 10 different field types that can be added to the document. Each field type collects various information from the recipients when they sign the document.
To create a field, you can either click and drag to draw a field on the document or drag and drop the field type from the sidebar.
![The available field types in the Documenso dashboard](/document-signing/documenso-document-fields.webp)
The field created will be assigned to the currently selected recipient. You can change the recipient by clicking on the recipient's name in the right sidebar.
The available field types are:
- **Signature** - Collects the signer's signature
- **Email** - Collects the signer's email address
- **Name** - Collects the signer's name
- **Initials** - Collects the signer's initials
- **Date** - Collects the date of the signature
- **Text** - Collects text input from the signer
- **Number** - Collects a number input from the signer
- **Radio** - Collects a single choice from the signer
- **Checkbox** - Collects multiple choices from the signer
- **Dropdown/Select** - Collects a single choice from a list of choices
All fields can be placed anywhere on the document and resized as needed.
<Callout type="info">
Learn more about the available field types and how to use them on the [Fields
page](/users/documents/fields).
</Callout>
### Preview
In this section, you can preview what the document will look like once it is fully signed. This uses placeholder data for the fields.
![Preview section in the Documenso editor](/document-signing/documenso-editor-preview.webp)
### Email Settings
Before sending the document, you can configure the email settings and customize the subject line, message, and sender name.
![Email settings in the Documenso dashboard](/document-signing/documenso-document-email-settings.webp)
If you leave the email subject and message empty, Documenso will use the default email template.
### Sending the Document
After configuring the document, click the "Send" button to send the document to the recipients. The recipients will receive an email with a link to sign the document.
![The email sent to the recipients with the signing link](/document-signing/documenso-sign-email.webp)
#### Signing Link
If you need to copy the signing link for each recipient, you can do so by clicking on the recipient whose link you want to copy. The signing link is copied automatically to your clipboard.
![How to copy the signing link for each recipient from the Documenso dashboard](/document-signing/documenso-signing-links.webp)
The signing link has the following format:
```bash
https://app.documenso.com/sign/12ACP777zxQLO52hjj_vCB
```
</Steps>
## Document Settings
To access the document settings, click the "Document Settings" button in the quick actions section.
### General Settings
![General Documenso editor settings](/document-signing/documenso-editor-general-settings.webp)
- **Language** - The language that the emails will be sent in
- **Allowed Signature Types** - The signature types that the recipient will be allowed to use
- **Date Format** - The date format that will be used for date fields
- **Time Zone** - The time zone that will be used for date fields
- **External ID** - A custom ID for the document that can be used to identify the document in your external system(s)
- **Redirect URL** - The URL where the signer will be redirected after signing the document
- **Document Distribution Method** - Whether to use emails to send the document, or none (which we will generate signing links for manual distribution)
### Email Settings
![Email Documenso editor settings](/document-signing/documenso-editor-email-settings.webp)
- **Reply To** - The email address that will be used as the reply to email address
- **Subject** - The subject of the email
- **Message** - The message of the email
- **Checkboxes** - You can select which emails should be sent during the document signing process
### Security Settings
Documenso enables you to set up access control for your documents. You can require authentication for viewing the document.
The available options are:
- **Require account** - The recipient must be signed in to view the document.
- **Require 2FA** - The recipient must use 2FA to sign the document.
- **None** - The document can be accessed directly by the URL sent to the recipient.
![Security Documenso editor settings](/document-signing/documenso-editor-security-settings.webp)
The "Recipient Authentication" feature allows you to specify the authentication method required for recipients to sign the signature field.
The available options are:
- **Require passkey** - The recipient must have an account and passkey configured via their settings.
- **Require 2FA** - The recipient must have an account and 2FA enabled via their settings.
- **None** - No authentication required.
This can be overridden by setting the authentication requirements directly for each recipient in the next step.
<Callout type="info">
The "Recipient Authentication" feature is only available for Enterprise accounts.
</Callout>

View File

@ -1,111 +0,0 @@
import { Callout, Steps } from 'nextra/components';
# Email Domains
Email Domains allow you to send emails to recipients from your own domain instead of the default Documenso email address.
<Callout type="info">
**Enterprise Only**: Email Domains is only available to Enterprise customers and custom plans
</Callout>
## Creating Email Domains
Before setting up email domains, ensure you have:
- An Enterprise subscription
- Access to your domain's DNS settings
- Access to your Documenso organisation as an admin or manager
<Steps>
### Access Email Domains Settings
Navigate to your Organisation email domains settings page and click the "Add Email Domain" button.
![Email Domains settings page](/email-domains/email-domains-settings-page.webp)
### Configure DNS Records
After adding your domain, Documenso will provide you with the following required DNS records that need to be configured on your domain:
- **SPF Record**: Specifies which servers are authorized to send emails from your domain
- **DKIM Record**: Provides email authentication and prevents tampering
![DNS configuration instructions](/email-domains/email-domains-record.webp)
<Callout type="info">
If you already have an SPF record configured, you will need to update it to include Amazon SES as
an authorized server instead of creating a new record.
</Callout>
Configure these records in your domain's DNS settings according to their specific instructions.
### Verify Domain Configuration
Once you've added the DNS records, return to the Documenso email domains settings page and click the "Verify" button.
This will trigger a verification process which will check if the DNS records are properly configured. If successful, the domain will be marked as "Active".
![Domain verification process](/email-domains/email-domain-sync.webp)
<Callout type="info">
Please note that it may take up to 48 hours for the DNS records to propagate.
</Callout>
</Steps>
## Creating Emails
Once your email domain has been configured, you can create multiple email addresses which your members can use when sending documents to recipients.
<Steps>
### Select the Email Domain You Want to Use
Navigate to the email domains settings page and click "Manage" on the domain you want to use.
![Email Domains settings page](/email-domains/email-domains-manage.webp)
### Add a New Email
Click on the "Add Email" button to begin the setup process.
![Create email](/email-domains/email-domains-manage-create-email.webp)
### Use Email
Once you have added an email, you can configure it to be the default email on either the:
- Organisation email preferences page
- Team email preferences page
When a draft document is created, it will inherit the email configured on the team if set, otherwise it will inherit the email configured in the organisation.
You can also configure the email address directly on the document to override the default email if required.
</Steps>
## Notes
- If you change the default email, it will not retroactively update any existing documents with the old default email.
- If the email domain becomes invalid, all emails using that domain will fail to send.
## Troubleshooting
### Common Issues
**DNS Verification Fails**
- Double-check all DNS record values
- Ensure records are added to the correct domain
- Wait for DNS propagation (up to 48 hours)
**Emails Not Delivering**
- Check domain reputation and blacklist status
- Verify SPF, DKIM, and DMARC records
- Review bounce and spam reports
<Callout type="info">
For additional support with Email Domains configuration, contact our support team at
support@documenso.com.
</Callout>

View File

@ -10,7 +10,7 @@ import { Callout, Steps } from 'nextra/components';
<Steps> <Steps>
### Pick a Plan ### Pick a Plan
The first step to start using Documenso is to pick a plan and create an account. At the moment of writing this guide, we have 3 plans available: Free, Individual, Teams and Platform. The first step to start using Documenso is to pick a plan and create an account. At the moment of writing this guide, we have 3 plans available: Free, Individual, and Teams.
Explore each plan's features and choose the one that best suits your needs. The [pricing page](https://documen.so/pricing) has more information about the plans. Explore each plan's features and choose the one that best suits your needs. The [pricing page](https://documen.so/pricing) has more information about the plans.
@ -28,6 +28,6 @@ You can claim a premium username by upgrading to a paid plan. After upgrading to
### Optional: Create a Team ### Optional: Create a Team
If you are working with others, you can create a team and invite your team members to collaborate on your documents. More information about teams is available in the [Teams section](/users/organisations/teams). If you are working with others, you can create a team and invite your team members to collaborate on your documents. More information about teams is available in the [Teams section](/users/get-started/teams).
</Steps> </Steps>

View File

@ -0,0 +1,99 @@
---
title: Teams
description: Learn how to create and manage teams in Documenso.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Teams
Documenso allows you to create teams to collaborate with others on creating and signing documents.
<Steps>
### Create a New Team
Anyone can create a team from their account by clicking on the "+" (plus) button in the "Teams" section from the account dropdown.
![Documenso account dropdown menu](/get-started-images/add-team.webp)
Each team is a separate entity with its members, documents, and templates. You can create as many teams as you like but remember that each team is billed separately.
<Callout type="info">You can transfer the ownership of the team at any time.</Callout>
### Name and URL
Clicking the "+" button will open a modal where you must pick your team's name and URL. The URL is the team's identifier and will link to the team's page and settings. An example URL would be:
```bash
https://app.documenso.com/t/<your-team-name>
```
![Documenso create team modal](/get-started-images/add-team-2.webp)
You can select a different name and URL for your team, but we recommend using the same or similar name.
### Invite Team Members
After creating the team, you can invite team members by navigating to the "Members" tab in the team settings and clicking the "Invite member" button.
To access the team settings, click on the team's name in the account dropdown and select the appropriate team. Lastly, click again on the avatar and then "Team Settings".
Or you can copy this URL:
```bash
https://app.documenso.com/t/<your-team-name>/settings/members
```
Once you click on the "Invite member" button, you will be prompted to enter the email address of the person you want to invite. You can also select the role of the person you are inviting.
![Invite team members in Documenso dashboard](/get-started-images/add-team-members-documenso.webp)
You can also bulk-invite members by uploading a CSV file with the email addresses and roles of the people you want to invite.
The table below shows how the CSV file should be structured:
| Email address | Role |
| -------------------------- | ------- |
| team-admin@documenso.com | Admin |
| team-manager@documenso.com | Manager |
| team-member@documenso.com | Member |
<Callout type="info">
The basic team plan includes 5 members. You can invite as many members as you like by upgrading
your team's seats on the team's billing page.
</Callout>
#### Roles
You can assign different permissions to team members based on their roles. The roles available are:
| Role | Create, Edit, Send Documents | Manage Users | Manage Admins | Settings | Billing | Delete/ Transfer |
| :-----: | :--------------------------: | :----------: | :-----------: | :------: | :-----: | :--------------: |
| Member | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Manager | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Admin | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Owner | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
### Set a Team Email
You can add a team email to make signing and sending documents easier. Adding a team email allows you to:
- See a signing request sent to this email (Team Inbox)
- See all documents sent on behalf of the team
### (Optional) Transfer Team Ownership
You can transfer the team's ownership at any time. To do this, navigate to the "General" tab in the team settings and click the "Transfer team" button.
Use this URL to get to the team settings:
```bash
https://app.documenso.com/t/<your-team-name>/settings
```
### [Send your First Document](https://app.documenso.com/)
</Steps>

View File

@ -1,8 +0,0 @@
{
"index": "Introduction",
"members": "Members",
"groups": "Groups",
"teams": "Teams",
"sso": "SSO",
"billing": "Billing"
}

View File

@ -1,19 +0,0 @@
---
title: Billing
description: Learn how to manage your organisation's billing and subscription.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
### Billing and Subscription Management
Organisations handle billing centrally, making it easier to manage:
- **Unified Billing**: One subscription covers all teams in the organisation
- **Seat Management**: Add or remove seats across all teams automatically (Teams plan)
You can change plans, view invoices and manage your subscription from the billing page which is accessible from the organisation settings.
![A screenshot of the organisation's billing page](/organisations/organisations-billing.webp)

View File

@ -1,75 +0,0 @@
---
title: Preferences
description: Learn how to manage your team's global preferences.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Organisation Groups
Organisation groups are a powerful administrative tool that streamlines user management across your entire organisation. Instead of manually assigning individual users to multiple teams, groups allow you to manage access at scale.
This automated approach ensures consistent permissions while reducing administrative overhead for tasks like onboarding employees or managing contractor access.
## Understanding groups
### Key Benefits
- **Instant Access Management**: New hires get immediate, appropriate access across all relevant teams
- **Bulk Operations**: Remove an entire group (like a departing contractor team) and all members lose access simultaneously
- **Role Consistency**: Ensure the same role is applied consistently across teams—no more accidentally giving admin access when member access was intended
- **Audit Trail**: Easily track which groups have access to which teams
### Example use case: Legal Compliance Team
Imagine you have a legal compliance team that needs access to review documents across all departments. Instead of manually adding each legal team member to every departmental team (Sales, Marketing, HR, Operations), you can:
1. Create a "Legal Compliance" group with the "Member" Organisation Role
2. Add legal team members to this group
3. Assign the "Legal Compliance" group to the required teams
Now, when Sarah from Legal joins the company, you can simply add her to the "Legal Compliance" group. Once added, she automatically gains access to all teams the "Legal Compliance" group is assigned to.
When John from Legal leaves the company, you remove him from the group and his access is instantly revoked across all teams.
## Getting started with groups
Navigate to the "Groups" section in your organisation settings to create and manage groups.
There are two types of roles when using groups:
- **Organisation Role**: A global organisation role given to all members of the group
- **Team Role**: A team role you select when assigning the group to a team
You should generally have the "Organisation Role" set to "Organisation Member", otherwise these members would by default have access to all teams anyway due to the high organisation role.
### Creating Custom Groups
When creating a custom group, you can:
1. **Name the Group**: Give it a descriptive name that reflects its purpose
2. **Set Organisation Role**: Define the default **organisation role** for group members
3. **Add Members**: Include organisation members in the group
![Organisation group creation](/organisations/organisation-group-create.webp)
### Manage Custom Groups
By clicking the "Manage" button on a custom group, you can view all teams it is assigned to and modify the group's settings.
![Organisation group management](/organisations/organisation-group-manage.webp)
### Assigning a group to a team
To assign a group to a team, you need to navigate to the team settings and click the "Groups" tab.
![Organisation group assignment](/organisations/organisation-group-assignment.webp)
From here, click the "Add groups" button to begin the process of assigning a group to a team. Once you have added the group you can see that the members have been automatically added to the team in the members tab.
## What's next?
- [Create Your First Team](/users/organisations/teams)
- [Manage Default Settings](/users/documents/document-preferences)

View File

@ -1,65 +0,0 @@
---
title: Organisations
description: Learn how to create and manage organisations in Documenso.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Organisations
Organisations allow you to manage multiple teams and users under a single managed entity. This powerful feature enables enterprise-level collaboration and streamlined management across your entire organisation.
## What are Organisations?
Organisations are the top-level entity in Documenso's hierarchy structure:
![Organisations diagram](/organisations/organisations-basic-diagram.webp)
Each organisation can contain multiple teams, and each team can have multiple members. This structure provides:
- **Centralized Management**: Control multiple teams from a single organisational dashboard
- **Unified Billing**: Manage billing and subscriptions at the organisation level
- **Access Control**: Define roles and groups across the entire organisation
- **Group Management**: Create custom groups to organise members and control team access
- **Global Settings**: Apply consistent settings across all teams in your organisation
## Create a new organisation
You can create multiple organisations, but each organisation will be billed separately.
<Steps>
### Creating Organisations
To create a new organisation, navigate to the organisation section in your account settings and click the "Create Organisation" button.
![Create organisation in Documenso dashboard](/organisations/organisations-create.webp)
### Select your plan
Choose from our range of plans for your new organisation. If you want to instead upgrade your current organisation, you can do so by going into your settings billing page and upgrade it there.
### Name setup
When creating an organisation, you'll need to provide:
- **Organisation Name**: The display name for your organisation
</Steps>
Once your organisation is established, you can create teams to organise your work and collaborate effectively. Each team operates independently but inherits organisation-level settings and branding.
## Best Practices for Organisation Management
1. **Use groups effectively**: Leverage groups to simplify permission management
2. **Set default settings**: Configure organisation-wide settings for consistency
## What's next?
- [Create Your First Team](/users/organisations/teams)
- [Invite Organisation Members](/users/organisations/members)
- [Create Organisation Groups](/users/organisations/groups)
- [Manage Default Settings](/users/documents/document-preferences)
- [Manage Default Branding](/users/branding)

View File

@ -1,65 +0,0 @@
---
title: Members
description: Learn how to invite and manage your organisation's members.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Organisation Members
Organisation members are the core users of your organisation. They are the ones who can access the team resources and collaborate with other members.
## Organisation Roles
You can assign different permissions to organisation members by using roles. The roles available are:
| Role | Manage Settings/Teams/Members | Billing | Delete Organisation |
| :------------------: | :---------------------------: | :-----: | ------------------- |
| Organisation Owner | ✅ | ✅ | ✅ |
| Organisation Admin | ✅ | ✅ | ✅ |
| Organisation Manager | ✅ | ❌ | ❌ |
| Organisation Member | ❌ | ❌ | ❌ |
<Callout type="info">
Organisation admins and managers will automatically have access to all teams as the "Team Admin"
role. When creating a team you can also decide whether to automatically allow normal members to
access it by default as well.
</Callout>
## Invite Organisation Members
To invite organisation members, you need to be an organisation owner, admin or manager.
1. Open the menu switcher top right
2. Hover over your new organisation and click the settings icon
3. Navigate to the "Members" tab
4. Click "Invite Member"
Once you click on the "Invite member" button, you will be prompted to enter the email address of the person you want to invite. You can also select the role of the person you are inviting.
![Invite organisation members](/organisations/organisations-member-invite.webp)
You can also bulk-invite members by uploading a CSV file with the email addresses and roles of the people you want to invite.
The table below shows how the CSV file should be structured:
| Email address | Role |
| ------------------------- | ------- |
| org-admin@documenso.com | Admin |
| org-manager@documenso.com | Manager |
| org-member@documenso.com | Member |
<Callout type="info">
The basic team plan includes 5 organisation members. Going over the 5 members will charge your
organisation according to the seat plan pricing.
</Callout>
## Manage Organisation Members
On the same page, you can change the organisation member's roles or remove them from the organisation.
## What's next?
- [Use groups to organise your members](/users/organisations/groups)

View File

@ -1,4 +0,0 @@
{
"index": "Configuration",
"microsoft-entra-id": "Microsoft Entra ID"
}

View File

@ -1,149 +0,0 @@
---
title: SSO Portal
description: Learn how to set up a custom SSO login portal for your organisation.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Organisation SSO Portal
The SSO Portal provides a dedicated login URL for your organisation that integrates with any OIDC compliant identity provider. This feature provides:
- **Single Sign-On**: Access Documenso using your own authentication system
- **Automatic onboarding**: New users will be automatically added to your organisation when they sign in through the portal
- **Delegated account management**: Your organisation has full control over the users who sign in through the portal
<Callout type="warning">
Anyone who signs in through your portal will be added to your organisation as a member.
</Callout>
## Getting Started
To set up the SSO Portal, you need to be an organisation owner, admin, or manager.
<Callout type="info">
**Enterprise Only**: This feature is only available to Enterprise customers.
</Callout>
<Steps>
### Access Organisation SSO Settings
![Organisation SSO Portal settings](/organisations/organisations-sso-settings.webp)
### Configure SSO Portal
See the [Microsoft Entra ID](/users/organisations/sso/microsoft-entra-id) guide to find the values for the following fields.
#### Issuer URL
Enter the OpenID discovery endpoint URL for your provider. Here are some common examples:
- **Google Workspace**: `https://accounts.google.com/.well-known/openid-configuration`
- **Microsoft Entra ID**: `https://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration`
- **Okta**: `https://{your-domain}.okta.com/.well-known/openid-configuration`
- **Auth0**: `https://{your-domain}.auth0.com/.well-known/openid-configuration`
#### Client Credentials
Enter the client ID and client secret provided by your identity provider:
- **Client ID**: The unique identifier for your application
- **Client Secret**: The secret key for authenticating your application
#### Default Organisation Role
Select the default Organisation role that new users will receive when they first sign in through the portal.
#### Allowed Email Domains
Specify which email domains are allowed to sign in through your SSO portal. Separate domains with spaces:
```
your-domain.com another-domain.com
```
Leave this field empty to allow all domains.
### Configure Your Identity Provider
You'll need to configure your identity provider with the following information:
- Redirect URI
- Scopes
These values are found at the top of the page.
### Save Configuration
Toggle the "Enable SSO portal" switch to activate the feature for your organisation.
Click "Update" to save your SSO portal configuration. The portal will be activated once all required fields are completed.
</Steps>
## Testing Your SSO Portal
Once configured, you can test your SSO portal by:
1. Navigating to your portal URL found at the top of the organisation SSO portal settings page
2. Sign in with a test account from your configured domain
3. Verifying that the user is properly provisioned with the correct organisation role
## Best Practices
### Reduce Friction
Create a custom subdomain for your organisation's SSO portal. For example, you can create a subdomain like `documenso.your-organisation.com` which redirects to the portal link.
### Security Considerations
Please note that anyone who signs in through your portal will be added to your organisation as a member.
- **Domain Restrictions**: Use allowed domains to prevent unauthorized access
- **Role Assignment**: Carefully consider the default organisation role for new users
## Troubleshooting
### Common Issues
**"Invalid issuer URL"**
- Verify the issuer URL is correct and accessible
- Ensure the URL follows the OpenID Connect discovery format
**"Client authentication failed"**
- Check that your client ID and client secret are correct
- Verify that your application is properly registered with your identity provider
**"User not provisioned"**
- Check that the user's email domain is in the allowed domains list
- Verify the default organisation role is set correctly
**"Redirect URI mismatch"**
- Ensure the redirect URI in Documenso matches exactly what's configured in your identity provider
- Check for any trailing slashes or protocol mismatches
### Getting Help
If you encounter issues with your SSO portal configuration:
1. Review your identity provider's documentation for OpenID Connect setup
2. Check the Documenso logs for detailed error messages
3. Contact your identity provider's support for provider-specific issues
<Callout type="info">
For additional support for SSO Portal configuration, contact our support team at
support@documenso.com.
</Callout>
## Identity Provider Guides
For detailed setup instructions for specific identity providers:
- [Microsoft Entra ID](/users/organisations/sso/microsoft-entra-id) - Complete guide for Azure AD configuration

View File

@ -1,76 +0,0 @@
---
title: Microsoft Entra ID
description: Learn how to configure Microsoft Entra ID (Azure AD) for your organisation's SSO portal.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Microsoft Entra ID Configuration
Microsoft Entra ID (formerly Azure Active Directory) is a popular identity provider for enterprise SSO. This guide will walk you through creating an app registration and configuring it for use with your Documenso SSO portal.
## Prerequisites
- Access to Microsoft Entra ID (Azure AD) admin center
- Access to your Documenso organisation as an administrator or manager
<Callout type="warning">Each user in your Azure AD will need an email associated with it.</Callout>
## Creating an App Registration
<Steps>
### Access Azure Portal
1. Navigate to the Azure Portal
2. Sign in with your Microsoft Entra ID administrator account
3. Search for "Azure Active Directory" or "Microsoft Entra ID" in the search bar
4. Click on "Microsoft Entra ID" from the results
### Create App Registration
1. In the left sidebar, click on "App registrations"
2. Click the "New registration" button
### Configure App Registration
Fill in the registration form with the following details:
- **Name**: Your preferred name (e.g. `Documenso SSO Portal`)
- **Supported account types**: Choose based on your needs
- **Redirect URI (Web)**: Found in the Documenso SSO portal settings page
Click "Register" to create the app registration.
### Get Client ID
After registration, you'll be taken to the app's overview page. The **Application (client) ID** is displayed prominently - this is your Client ID for Documenso.
### Create Client Secret
1. In the left sidebar, click on "Certificates & secrets"
2. Click "New client secret"
3. Add a description (e.g., "Documenso SSO Secret")
4. Choose an expiration period (recommended 12-24 months)
5. Click "Add"
Make sure you copy the "Secret value", not the "Secret ID", you won't be able to access it again after you leave the page.
</Steps>
## Getting Your OpenID Configuration URL
1. In the Azure portal, go to "Microsoft Entra ID"
2. Click on "Overview" in the left sidebar
3. Click the "Endpoints" in the horizontal tab
4. Copy the "OpenID Connect metadata document" value
## Configure Documenso SSO Portal
Now you have all the information needed to configure your Documenso SSO portal:
- **Issuer URL**: The "OpenID Connect metadata document" value from the previous step
- **Client ID**: The Application (client) ID from your app registration
- **Client Secret**: The secret value you copied during creation

View File

@ -1,121 +0,0 @@
---
title: Teams
description: Learn how to create and manage teams in Documenso.
---
import Image from 'next/image';
import { Callout, Steps } from 'nextra/components';
# Teams
Documenso teams allow you to collaborate with others on creating, sending and receiving documents within your organisation. Teams operate within the organisational structure and inherit settings and branding from their parent organisation.
## Team Structure
Teams provide focused collaboration spaces while benefiting from organisation-level management and settings.
Each team within an organisation has its own:
- Team members and roles
- Documents and templates
- Team-specific settings (that can override organisation defaults)
- Team email and branding (if enabled)
## Creating a Team
Only members with the "Organisation Admin" or "Organisation Manager" role can create teams.
<Steps>
### Create Team
To create a team, navigate to the organisation settings page and click the "Teams" tab. Then you can click the "Create Team" button.
![Create Team Dialog](/teams/team-create.webp)
### Name and URL
When creating a team, you'll need to provide:
- **Team Name**: The display name for your team
- **Team URL**: A unique identifier for your team
The team URL will follow this format:
```bash
https://app.documenso.com/t/<team-url>
```
You can select different names and URLs for your team, but we recommend using the same or similar names for consistency.
![Documenso create team modal](/teams/team-create-dialog.webp)
You can also decide whether to automatically inherit members from the organisation into the team. This means that all members of the organisation will have access to this team.
Members with the "Organisation Admin" or "Organisation Manager" role will be assigned as "Team Admin" regardless of this setting. This will only affect members with the "Organisation Member" role, who will be added to the team as a "Team Member".
Disabling this setting will remove all these members automatically. This can always be turned on or off later in the teams member settings page.
</Steps>
## Team Members
After creating the team, you can add organisation members into your team using two methods:
- Directly adding members to the team
- Add members using groups
### Directly adding members
1. Navigate to the team settings member page
2. Click the "Add Members" button
3. Choose which members you want to add
4. Assign the team roles for each team member
If you want to add people outside of the organisation, you will need to invite them to the organisation first.
See the [organisation members](/users/organisations/members#invite-organisation-members) page for more information.
### Adding members using groups
1. Navigate to the teams settings groups page
2. Click the "Add groups" button
3. Choose which groups you want to add
4. Assign the team roles for each group
See the [organisation groups](/users/organisations/groups) page for more information.
### Team Member Roles
You can assign different permissions to team members based on their roles. The roles available are:
| Role | Manage Documents | Manage Team | Delete Team |
| :----------: | :--------------: | :---------: | :---------: |
| Team Admin | ✅ | ✅ | ✅ |
| Team Manager | ✅ | ✅ | ❌ |
| Team Member | ✅ | ❌ | ❌ |
These roles can be used for document visibility and management as well.
## Set a Team Email
You can add a team email which allows you to:
- See signing requests sent to this email (Team Inbox)
- See documents sent from this email
- Send documents on behalf of the team
- Maintain consistent team branding in communications
## Team Settings and Branding
You can override preferences and settings from the Organisation on the Team level. See the following pages for more information:
- [Document preferences](/users/documents/document-preferences)
- [Branding preferences](/users/branding/branding-preferences)
## What's next?
- [Send your first document](/users/documents/sending-documents)
- [Setup your default document preferences](/users/documents/document-preferences)
- [Setup your default branding preferences](/users/branding)

View File

@ -1,5 +1,5 @@
--- ---
title: Public Profile title: User Profile
description: Learn how to set up your public profile on Documenso. description: Learn how to set up your public profile on Documenso.
--- ---
@ -15,7 +15,7 @@ Documenso allows you to create a public profile to share your templates for anyo
### Navigate to Your Profile Settings ### Navigate to Your Profile Settings
Click on your profile picture in the top right corner and select "Settings" or "Team Settings". Then, navigate to the "Public Profile" tab to configure your profile. Click on your profile picture in the top right corner and select "User settings". Then, navigate to the "Public Profile" tab to configure your profile.
![The profile settings page](/public-profile/documenso-public-profile-settings.webp) ![The profile settings page](/public-profile/documenso-public-profile-settings.webp)
@ -45,8 +45,6 @@ You can choose to make your profile public or private. Only you can access it if
To make your profile public, toggle the switch to the right ("Show") at the top right-hand side of the page. To make your profile public, toggle the switch to the right ("Show") at the top right-hand side of the page.
![An example of a enabling a public profile on Documenso](/public-profile/documenso-enable-public-profile-settings.webp)
### (Optional) Link Templates ### (Optional) Link Templates
Linking templates to your profile is optional, but it's what makes your profile helpful. Linking templates allow people to sign documents directly from your profile. As a result, we recommend linking at least one template you want to share with others. Linking templates to your profile is optional, but it's what makes your profile helpful. Linking templates allow people to sign documents directly from your profile. As a result, we recommend linking at least one template you want to share with others.

View File

@ -0,0 +1,4 @@
{
"index": "Send Documents",
"fields": "Document Fields"
}

View File

@ -0,0 +1,446 @@
---
title: Document Fields
description: Learn about the different fields you can add to your documents in Documenso.
---
# Document Fields
Learn about the different fields you can add to your documents in Documenso and how to make the most of them.
## Signature Field
The signature field collects the signer's signature. It's required for each recipient with the "Signer" role.
### Document Editor View
The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign.
![The signature field in the Documenso document editor](/document-signing/signature-field-document-editor-view.webp)
### Document Signing View
The recipient will see the signature field when they open the document to sign.
The recipient must click on the signature field to open the signing view, where they can sign using their mouse, touchpad, or touchscreen.
![The signature field in the Documenso document signing view](/document-signing/signature-field-document-signing-view.webp)
The image below shows the signature field signed by the recipient.
![The signature field signed by the user in the Documenso document signing view](/document-signing/signed-signature-field.webp)
After signing, the recipient can click the "Complete" button to complete the signing process.
## Email Field
The email field is used to collect the signer's email address.
### Document Editor View
The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign.
![The email field in the Documenso document editor](/document-signing/email-field-document-editor-view.webp)
### Document Signing View
When the recipient opens the document to sign, they will see the email field.
The recipient must click on the email field to automatically sign the field with the email associated with their account.
![The email field in the Documenso document signing view](/document-signing/email-field-document-signing-view.webp)
The image below shows the email field signed by the recipient.
![The email field signed by the user in the Documenso document signing view](/document-signing/signed-email-field.webp)
After entering their email address, the recipient can click the "Complete" button to complete the signing process.
## Name Field
The name field is used to collect the signer's name.
### Document Editor View
The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign.
![The name field in the Documenso document editor](/document-signing/name-field-document-editor-view.webp)
### Document Signing View
When the recipient opens the document to sign, they will see the name field.
The recipient must click on the name field, which will automatically sign the field with the name associated with their account.
![The name field in the Documenso document signing view](/document-signing/name-field-document-signing-view.webp)
The image below shows the name field signed by the recipient.
![The name field signed by the user in the Documenso document signing view](/document-signing/name-field-signed.webp)
After entering their name, the recipient can click the "Complete" button to complete the signing process.
## Date Field
The date field is used to collect the date of the signature.
### Document Editor View
The field doesn't have any additional settings. You just need to place it on the document where you want the signer to sign.
![The date field in the Documenso document editor](/document-signing/date-field-document-editor-view.webp)
### Document Signing View
When the recipient opens the document to sign, they will see the date field.
The recipient must click on the date field to automatically sign the field with the current date and time.
![The date field in the Documenso document signing view](/document-signing/date-field-document-signing-view.webp)
The image below shows the date field signed by the recipient.
![The date field signed by the user in the Documenso document signing view](/document-signing/date-field-signed.webp)
After entering the date, the recipient can click the "Complete" button to complete the signing process.
## Text Field
The text field is used to collect text input from the signer.
### Document Editor View
Place the text field on the document where you want the signer to enter text. The text field comes with additional settings that can be configured.
![The text field in the Documenso document editor](/document-signing/text-field-document-editor-view.webp)
To open the settings, click on the text field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen.
![The text field settings in the Documenso document editor](/document-signing/text-field-advanced-settings-document-editor-view.webp)
The text field settings include:
- **Label** - The label displayed in the field.
- **Placeholder** - The placeholder text displayed in the field.
- **Text** - The default text displayed in the field.
- **Character limit** - The maximum number of characters allowed in the field.
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty text field. It must have a default text value.
- The signer must fill out a required field.
- The text field characters count can't exceed the character limit.
- The signer can't modify a read-only field.
- The field auto-signs if there is a default text value.
Let's look at the following example.
![A text field with the settings configured by the user in the Documenso document editor](/document-signing/text-field-with-filled-advanced-settings.webp)
The field is configured as follows:
- Label: "Address"
- Placeholder: "Your office address"
- Default Text: "Signing Street 1, 241245"
- Character Limit: 35
- Required: False
- Read Only: False
Since the field has a label set, the label is displayed instead of the default text field value - "Add text".
### Document Signing View
What the recipient sees when they open the document to sign depends on the settings configured by the sender.
In this case, the recipient sees the text field signed with the default value.
![Text field with the default value signed by the user in the Documenso document signing view](/document-signing/text-field-autosigned.webp)
The recipient can modify the text field value since the field is not read-only. To change the value, the recipient must click the field to un-sign it.
Once it's unsigned, the field uses the label set by the sender.
![Unsigned text field in the Documenso document signing view](/document-signing/text-field-unsigned.webp)
To sign the field with a different value, the recipient needs to click on the field and enter the new value.
![Text field with the text input in the Documenso document signing view](/document-signing/text-field-input-modal.webp)
Since the text field has a character limit, the recipient must enter a value that doesn't exceed the limit. Otherwise, an error message will appear, and the field will not be signed.
The image below illustrates the text field signed with a new value.
![Text field signed with a new value](/document-signing/text-field-new-value-signed.webp)
After signing the field, the recipient can click the "Complete" button to complete the signing process.
## Number Field
The number field is used for collecting a number input from the signer.
### Document Editor View
Place the number field on the document where you want the signer to enter a number. The number field comes with additional settings that can be configured.
![The number field in the Documenso document editor](/document-signing/number-field-document-editor.webp)
To open the settings, click on the number field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen.
![The number field in the Documenso document editor](/document-signing/number-field-document-editor-view.webp)
The number field settings include:
- **Label** - The label displayed is the field.
- **Placeholder** - The placeholder text displayed in the field.
- **Value** - The default number displayed in the field.
- **Number format** - The format of the number.
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Validation** - The validation rules for the field.
It also comes with a couple of rules:
- The value must be a number.
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty number field. It must have a default number value.
- The signer must fill out a required field.
- If the default number and a max value are set, the default number must be less than the max value.
- If the default number and a min value are set, the default number must be greater than the min value.
- The value must match the number format if a number format is set.
In this example, the number field is configured as follows:
- Label: "Quantity"
- Placeholder: "Enter the preferred quantity"
- Default Value: 12
- Number Format: "123,456,789.00"
- Required: False
- Read Only: False
- Validation:
- Min value: 5, Max value: 50
![A number field with the label configured by the user in the Documenso document editor](/document-signing/number-field-label.webp)
Since the field has a label set, the label is displayed instead of the default number field value - "Add number".
### Document Signing View
What the recipient sees when they open the document to sign depends on the settings configured by the sender.
The recipient sees the number field signed with the default value in this case.
![Number field with the default value signed by the user in the Documenso document signing view](/document-signing/number-field-autosigned.webp)
Since the number field is not read-only, the recipient can modify its value. To change the value, the recipient must click the field to un-sign it.
Once it's unsigned, the field uses the label set by the sender.
![Unsigned number field in the Documenso document signing view](/document-signing/number-field-unsigned.webp)
To sign the field with a different value, the recipient needs to click on the field and enter the new value.
![Number field with the number input in the Documenso document signing view](/document-signing/number-field-input-modal.webp)
Since the number field has a validation rule set, the recipient must enter a value that meets the rules. In this example, the value needs to be between 5 and 50. Otherwise, an error message will appear, and the field will not be signed.
The image below illustrates the text field signed with a new value.
![Number field signed with a new value](/document-signing/number-field-signed-with-another-value.webp)
After signing the field, the recipient can click the "Complete" button to complete the signing process.
## Radio Field
The radio field is used to collect a single choice from the signer.
### Document Editor View
Place the radio field on the document where you want the signer to select a choice. The radio field comes with additional settings that can be configured.
![The radio field in the Documenso document editor](/document-signing/radio-field-document-editor-view.webp)
To open the settings, click on the radio field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen.
![The radio field advanced settings in the Documenso document editor](/document-signing/radio-field-advanced-settings-document-editor-view.webp)
The radio field settings include:
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Values** - The list of choices for the field.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty radio field. It must have at least one option.
- The signer must fill out a required field.
- The field auto-signs if there is a default value.
- The signer can't sign with a value not in the options list.
- The signer can't modify the field if it's read-only.
- It should contain at least one option.
- The field can't have more than one option selected.
In this example, the radio field is configured as follows:
- Required: False
- Read Only: False
- Options:
- Option 1
- Option 2
- Empty value
- Empty value
- Option 3
![The radio field with the settings configured by the user in the Documenso document editor](/document-signing/radio-field-options-document-editor-view.webp)
Since the field contains radio options, it displays them instead of the default radio field value, "Radio".
### Document Signing View
What the recipient sees when they open the document to sign depends on the settings configured by the sender.
In this case, the recipient sees the radio field unsigned because the sender didn't select a value.
![Radio field with no value selected in the Documenso document signing view](/document-signing/radio-field-unsigned.webp)
The recipient can select one of the options by clicking on the radio button next to the option.
![Radio field with the value selected by the user in the Documenso document signing view](/document-signing/radio-field-signed.webp)
After signing the field, the recipient can click the "Complete" button to complete the signing process.
## Checkbox Field
The checkbox field is used to collect multiple choices from the signer.
### Document Editor View
Place the checkbox field on the document where you want the signer to select choices. The checkbox field comes with additional settings that can be configured.
![The checkbox field in the Documenso document editor](/document-signing/checkbox-document-editor-view.webp)
To open the settings, click on the checkbox field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen.
![The checkbox field settings in the Documenso document editor](/document-signing/checkbox-advanced-settings.webp)
The checkbox field settings include the following:
- **Validation** - The validation rules for the field.
- **Rule** - The rule specifies "At least", "At most", and "Exactly".
- **Number** - The number of choices that must be selected.
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Options** - The list of choices for the field.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty checkbox field. It must have at least one checked option.
- The signer must fill out a required field.
- The field auto-signs if there is a default value.
- The signer can't sign with a value not in the options list.
- The signer can't modify the field if it's read-only.
- It should contain at least one option.
In this example, the checkbox field is configured as follows:
- No validation rules
- Required: True
- Read Only: False
- Options:
- Option 1
- Empty value (checked)
- Option 2
- Option 3 (checked)
- Empty value
![The checkbox field with the settings configured by the user in the Documenso document editor](/document-signing/checkbox-advanced-settings-document-editor-view.webp)
Since the field contains checkbox options, it displays them instead of the default checkbox field value, "Checkbox".
### Document Signing View
What the recipient sees when they open the document to sign depends on the settings configured by the sender.
In this case, the recipient sees the checkbox field signed with the values selected by the sender.
![Checkbox field with the values selected by the user in the Documenso document signing view](/document-signing/checkbox-field-document-signing-view.webp)
Since the field is required, the recipient can either sign with the values selected by the sender or modify the values.
The values can be modified in 2 ways:
- Click on the options you want to select or deselect.
- Hover over the field and click the "X" button to clear all the selected values.
The image below illustrates the checkbox field with the values cleared by the recipient. Since the field is required, it has a red border instead of the yellow one (non-required fields).
![Checkbox field the values cleared by the user in the Documenso document signing view](/document-signing/checkbox-field-unsigned.webp)
Then, the recipient can select values other than the ones chosen by the sender.
![Checkbox field with the values selected by the user in the Documenso document signing view](/document-signing/checkbox-field-custom-sign.webp)
After signing the field, the recipient can click the "Complete" button to complete the signing process.
## Dropdown/Select Field
The dropdown/select field collects a single choice from a list of options.
### Document Editor View
Place the dropdown/select field on the document where you want the signer to select a choice. The dropdown/select field comes with additional settings that can be configured.
![The dropdown/select field in the Documenso document editor](/document-signing/select-field-sliders.webp)
To open the settings, click on the dropdown/select field and then on the "Sliders" icon. That opens the settings panel on the right side of the screen.
![The dropdown/select field settings in the Documenso document editor](/document-signing/select-field-advanced-settings-panel.webp)
The dropdown/select field settings include:
- **Required** - Whether the field is required or not.
- **Read only** - Whether the field is read-only or not.
- **Options** - The list of choices for the field.
- **Default** value - The default value selected in the field.
It also comes with a couple of rules:
- The field can't be required and read-only at the same time.
- A read-only field can't have an empty select field. It must have a default value.
- The signer must fill out a required field.
- The default value must be one of the options.
- The field auto-signs if there is a default value.
- The field can't be signed with a value not in the options list.
- The signer can't modify the field if it's read-only.
- It should contain at least one option.
In this example, the dropdown/select field is configured as follows:
- Required: False
- Read Only: False
- Default Value: None
- Options:
- Document
- Template
- Other
### Document Signing View
What the recipient sees when they open the document to sign depends on the settings configured by the sender.
In this case, the recipient sees the dropdown/select field with the default label, "-- Select ---" since the sender has not set a default value.
![Dropdown/select field in the Documenso document signing view](/document-signing/select-field-unsigned.webp)
The recipient can modify the dropdown/select field value since the field is not read-only. To change the value, the recipient must click on the field for the dropdown list to appear.
![Dropdown/select field with the dropdown list in the Documenso document signing view](/document-signing/select-field-unsigned-dropdown.webp)
The recipient can select one of the options from the list. The image below illustrates the dropdown/select field signed with a new value.
![Dropdown/select field signed with a value](/document-signing/select-field-signed.webp)
After signing the field, the recipient can click the "Complete" button to complete the signing process.

View File

@ -0,0 +1,153 @@
---
title: Send a document for signing
description: The guide gives a detailed description of all options available when sending out a document for signing.
---
import { Callout, Steps } from 'nextra/components';
# Send Documents for Signing
This guide will walk you through the process of sending a document out for signing. You will learn how to upload a document, add recipients, place signature fields, and send the document for signing.
<Steps>
### Login Into Your Account
The guide assumes you have a Documenso account. If you don't, you can create a free account [here](https://documen.so/free-docs).
### Upload Document
Navigate to the [Documenso dashboard](https://app.documenso.com/documents) and click on the "Add a document" button. Select the document you want to upload and wait for the upload to complete.
![Documenso dashboard](/document-signing/documenso-documents-dashboard.webp)
After the upload is complete, you will be redirected to the document's page. You can configure the document's settings and add recipients and fields here.
![Documenso document overview](/document-signing/documenso-uploaded-document.webp)
### (Optional) Advanced Options
Click on the "Advanced options" button to access additional settings for the document. You can set an external ID, date format, time zone, and the redirect URL.
![Advanced settings for a document uploaded in the Documenso dashboard](/document-signing/documenso-uploaded-document-advanced-options.webp)
The external ID allows you to set a custom ID for the document that can be used to identify the document in your external system(s).
The date format and time zone settings allow you to customize how the date and time are displayed in the document.
The redirect URL allows you to specify a URL where the signer will be redirected after signing the document.
### (Optional) Document Access
Documenso enables you to set up access control for your documents. You can require authentication for viewing the document.
The available options are:
- **Require account** - The recipient must be signed in to view the document.
- **None** - The document can be accessed directly by the URL sent to the recipient.
![Document access settings in the Documenso dashboard](/document-signing/documenso-enterprise-document-access.webp)
<Callout type="info">
The "Document Access" feature is only available for Enterprise accounts.
</Callout>
### (Optional) Recipient Authentication
The "Recipient Authentication" feature allows you to specify the authentication method required for recipients to sign the signature field.
The available options are:
- **Require passkey** - The recipient must have an account and passkey configured via their settings.
- **Require 2FA** - The recipient must have an account and 2FA enabled via their settings.
- **None** - No authentication required.
![Document recipient action authentication in the Documenso dashboard](/document-signing/document-enterprise-recipient-action-authentication.webp)
This can be overridden by setting the authentication requirements directly for each recipient in the next step.
<Callout type="info">
The "Recipient Authentication" feature is only available for Enterprise accounts.
</Callout>
### Recipients
Click the "+ Add Signer" button to add a new recipient. You can configure the recipient's email address, name, role, and authentication method on this page.
You can choose any option from the ["Recipient Authentication"](#optional-recipient-authentication) section, or you can set it to "Inherit authentication method" to use the global action signing authentication method configured in the "General Settings" step.
![The required authentication method for a recipient](/document-signing/documenso-document-recipient-authentication-method.webp)
You can also set the recipient's role, which determines their actions and permissions in the document.
![The recipient role](/document-signing/documenso-document-recipient-role.webp)
#### Roles
Documenso has 4 roles for recipients with different permissions and actions.
| Role | Function | Action required | Signature |
| :-------: | :-----------------------------------------------------------------------------: | :-------------: | :-------: |
| Signer | Needs to sign signatures fields assigned to them. | Yes | Yes |
| Approver | Needs to approve the document as a whole. Signature optional. | Yes | Optional |
| Viewer | Needs to confirm they viewed the document. | Yes | No |
| Assistant | Can help prepare the document by filling in fields on behalf of other signers. | Yes | No |
| CC | Receives a copy of the signed document after completion. No action is required. | No | No |
### Fields
Documenso supports 9 different field types that can be added to the document. Each field type collects various information from the recipients when they sign the document.
![The available field types in the Documenso dashboard](/document-signing/documenso-document-fields.webp)
The available field types are:
- **Signature** - Collects the signer's signature
- **Email** - Collects the signer's email address
- **Name** - Collects the signer's name
- **Date** - Collects the date of the signature
- **Text** - Collects text input from the signer
- **Number** - Collects a number input from the signer
- **Radio** - Collects a single choice from the signer
- **Checkbox** - Collects multiple choices from the signer
- **Dropdown/Select** - Collects a single choice from a list of choices
All fields can be placed anywhere on the document and resized as needed.
<Callout type="info">
Learn more about the available field types and how to use them on the [Fields
page](signing-documents/fields).
</Callout>
#### Signature Required
Signer Roles require at least 1 signature field. You will get an error message if you try to send a document without a signature field.
![Error message when trying to send a document without a signature field](/document-signing/documenso-no-signature-field-found.webp)
### Email Settings
Before sending the document, you can configure the email settings and customize the subject line, message, and sender name.
![Email settings in the Documenso dashboard](/document-signing/documenso-document-email-settings.webp)
If you leave the email subject and message empty, Documenso will use the default email template.
### Sending the Document
After configuring the document, click the "Send" button to send the document to the recipients. The recipients will receive an email with a link to sign the document.
![The email sent to the recipients with the signing link](/document-signing/documenso-sign-email.webp)
#### Signing Link
If you need to copy the signing link for each recipient, you can do so by clicking on the recipient whose link you want to copy. The signing link is copied automatically to your clipboard.
![How to copy the signing link for each recipient from the Documenso dashboard](/document-signing/documenso-signing-links.webp)
The signing link has the following format:
```bash
https://app.documenso.com/sign/12ACP777zxQLO52hjj_vCB
```
</Steps>

View File

@ -0,0 +1,6 @@
{
"preferences": "Preferences",
"document-visibility": "Document Visibility",
"sender-details": "Email Sender Details",
"branding-preferences": "Branding Preferences"
}

View File

@ -0,0 +1,16 @@
---
title: Branding Preferences
description: Learn how to set the branding preferences for your team account.
---
# Branding Preferences
You can set the branding preferences for your team account by going to the **Branding Preferences** tab in the team's settings dashboard.
![A screenshot of the team's branding preferences page](/teams/team-branding-preferences.webp)
On this page, you can:
- **Upload a Logo** - Upload your team's logo to be displayed instead of the default Documenso logo.
- **Set the Brand Website** - Enter the URL of your team's website to be displayed in the email communications sent by the team.
- **Add Additional Brand Details** - You can add additional information to display at the bottom of the emails sent by the team. This can include contact information, social media links, and other relevant details.

View File

@ -5,25 +5,19 @@ description: Learn how to control the visibility of your team documents.
import { Callout } from 'nextra/components'; import { Callout } from 'nextra/components';
# Document Visibility # Team's Document Visibility
The default document visibility option allows you to control who can view and access the documents uploaded within a team. The default document visibility option allows you to control who can view and access the documents uploaded to your team account. The document visibility can be set to one of the following options:
This value can either be set in the [document preferences](/users/documents/document-preferences), or when you [create the document](/users/documents/send-document)
## Document Visibility Options
The document visibility can be set to one of the following options:
- **Everyone** - The document is visible to all team members. - **Everyone** - The document is visible to all team members.
- **Managers and above** - The document is visible to team members with the role of _Manager or above_ and _Admin_. - **Managers and above** - The document is visible to team members with the role of _Manager or above_ and _Admin_.
- **Admin only** - The document is only visible to the team's admins. - **Admin only** - The document is only visible to the team's admins.
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [document preferences page](/users/documents/document-preferences) and selecting a different visibility option. ![A screenshot of the document visibility selector from the team's global preferences page](/teams/team-preferences-document-visibility.webp)
![Document visibility preference](/organisations/organisation-document-visibility.webp) The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general preferences page](/users/teams/preferences) and selecting a different visibility option.
## How it works Here's how it works:
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Everyone_", the document's visibility is set to "_EVERYONE_". - If a user with the "_Member_" role creates a document and the default document visibility is set to "_Everyone_", the document's visibility is set to "_EVERYONE_".
- The user can't change the visibility of the document in the document editor. - The user can't change the visibility of the document in the document editor.

View File

@ -0,0 +1,19 @@
---
title: Preferences
description: Learn how to manage your team's global preferences.
---
# Preferences
You can manage your team's global preferences by clicking on the **Preferences** tab in the team's settings dashboard.
![A screenshot of the team's global preferences page](/teams/team-preferences.webp)
The preferences page allows you to update the following settings:
- **Document Visibility** - Set the default visibility of the documents created by team members. Learn more about [document visibility](/users/teams/document-visibility).
- **Default Document Language** - This setting allows you to set the default language for the documents uploaded in the team account. The default language is used as the default language in the email communications with the document recipients. You can change the language for individual documents when uploading them.
- **Sender Details** - Set whether the sender's name should be included in the emails sent by the team. Learn more about [sender details](/users/teams/sender-details).
- **Typed Signature** - It controls whether the document recipients can sign the documents with a typed signature or not. If enabled, the recipients can sign the document using either a drawn or a typed signature. If disabled, the recipients can only sign the documents usign a drawn signature. This setting can also be changed for individual documents when uploading them.
- **Include the Signing Certificate** - This setting controls whether the signing certificate should be included in the signed documents. If enabled, the signing certificate is included in the signed documents. If disabled, the signing certificate is not included in the signed documents. Regardless of this setting, the signing certificate is always available in the document's audit log page.
- **Branding Preferences** - Set the branding preferences and defaults for the team account. Learn more about [branding preferences](/users/teams/branding-preferences).

View File

@ -0,0 +1,14 @@
---
title: Email Sender Details
description: Learn how to update the sender details for your team's email notifications.
---
## Sender Details
If the **Sender Details** setting is enabled, the emails sent by the team will include the sender's name. The email will say:
> "Example User" on behalf of "Example Team" has invited you to sign "document.pdf"
If the **Sender Details** setting is disabled, the emails sent by the team will not include the sender's name. The email will say:
> "Example Team" has invited you to sign "document.pdf"

View File

@ -8,43 +8,82 @@ Documenso allows you to create templates, which are reusable documents. Template
### Create New Template ### Create New Template
To create a new template, navigate to the "Templates" page and click on the "Upload Template" button. To create a new template, navigate to the ["Templates" page](https://app.documenso.com/templates) and click on the "New Template" button.
![Documenso template page](/templates/documenso-template-page.webp) ![Documenso template page](/templates/documenso-template-page.webp)
You can select multiple files at once to upload into the template. Once the upload is complete you will be redirected to the editor. Clicking on the "New Template" button opens a new modal to upload the document you want to use as a template. Select the document and wait for Documenso to upload it to your account.
![A successfully uploaded document in the Documenso dashboard](/templates/documenso-template-page-uploaded-document.webp) ![Upload a new template document in the Documenso dashboard](/templates/documenso-template-page-upload-document.webp)
See the [documents](/users/documents/sending-documents) page for more information on how to use the editor. Once the upload is complete, Documenso opens the template configuration page.
![A successfuly uploaded document in the Documenso dashboard](/templates/documenso-template-page-uploaded-document.webp)
You can then configure the template by adding recipients, fields, and other options. You can then configure the template by adding recipients, fields, and other options.
### (Optional) Email options
When you send a document for signing, Documenso emails the recipients with a link to the document. The email contains a subject, message, and the document.
Documenso uses a generic subject and message but also allows you to customize them for each document and template.
![Configuring the email options for the Documenso template](/templates/documenso-template-page-uploaded-document-email-options.webp)
To configure the email options, click the "Email Options" tab and fill in the subject and message fields. Every time you use this template for signing, Documenso will use the custom subject and message you provided. They can also be overridden before sending the document.
### (Optional) Advanced Options
The template also has advanced options that you can configure. These options include settings such as the external ID, date format, time zone and the redirect URL.
![Configuring the advanced options for the Documenso template](/templates/documenso-template-page-uploaded-document-advanced-options.webp)
The external ID allows you to set a custom ID for the document that can be used to identify the document in your external system(s).
The date format and time zone settings allow you to customize how the date and time are displayed in the document.
The redirect URL allows you to specify a URL where the signer will be redirected after signing the document.
### Add Placeholders or Recipients ### Add Placeholders or Recipients
When adding recipients, you can use dummy recipients which can be replaced with actual recipients when you use a template, which we will explain in the next section. You can add placeholders for the template recipients. Placeholders specify where the recipient's name, email, and other information should be in the document.
For example, the following has two recipients: You can also add recipients directly to the template. Recipients are the people who will receive the document for signing.
- placeholder@documenso.com
- me@documenso.com
![Adding placeholder recipients for the Documenso template](/templates/documenso-template-recipients.webp) ![Adding placeholder recipients for the Documenso template](/templates/documenso-template-recipients.webp)
You can then place fields for each recipient. If you add placeholders to the template, you must replace them with actual recipients when creating a document from it. See the modal from the ["Use a Template"](#use-a-template) section.
### Add Fields
The last step involves adding fields to the document. These fields collect information from the recipients when they sign the document.
Documenso provides the following field types:
- **Signature** - Collects the signer's signature
- **Email** - Collects the signer's email address
- **Name** - Collects the signer's name
- **Date** - Collects the date of the signature
- **Text** - Collects text input from the signer
- **Number** - Collects a number input from the signer
- **Radio** - Collects a single choice from the signer
- **Checkbox** - Collects multiple choices from the signer
- **Dropdown/Select** - Collects a single choice from a list of choices
![Adding fields for the Documenso template](/templates/documenso-template-page-fields.webp)
After adding the fields, press the "Save Template" button to save the template.
<Callout type="info"> <Callout type="info">
Learn more about the available field types and how to use them on the [Fields Learn more about the available field types and how to use them on the [Fields
page](/users/documents/fields). page](signing-documents/fields).
</Callout> </Callout>
### Use a Template ### Use a Template
Once you're ready to use the template, you can click the "Use Template" button in the top right corner. Click on the "Use Template" button to create a new document from the template. Before creating the document, you are asked to fill in the recipients for the placeholders you added to the template.
Here you can choose to use the template as is, or you can replace the emails or names with different recipients as you require. After filling in the recipients, click the "Create Document" button to create the document in your account.
You can now decide whether to create the document as a draft, or immediately send it to the recipients for signing.
![Use an available Documenso template](/templates/documenso-use-template.webp) ![Use an available Documenso template](/templates/documenso-use-template.webp)
@ -52,7 +91,7 @@ You can also send the document straight to the recipients for signing by checkin
### (Optional) Create A Direct Signing Link ### (Optional) Create A Direct Signing Link
A direct signing link allows you to create a shareable link for document signing, where recipients can fill in their information and sign the document. A direct signing link allows you to create a shareable link for document signing, where recipients can fill in their information and sign the document. See the "Create Direct Link" button in the image from [step 4](#add-placeholders-or-recipients).
<Callout type="info"> <Callout type="info">
Check out the [Direct Signing Links](/users/direct-links) section for more information. Check out the [Direct Signing Links](/users/direct-links) section for more information.

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Some files were not shown because too many files have changed in this diff Show More