Compare commits

...

339 Commits

Author SHA1 Message Date
9917def0ca v1.12.2-rc.0 2025-07-03 10:31:22 +10:00
cdb9b9ee03 chore: add certificate error logs (#1875)
Add certificate logs
2025-07-03 10:13:12 +10:00
8d1d098e3a v1.12.1 2025-07-03 10:07:54 +10:00
b682d2785f chore: add translations (#1835)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-07-03 10:07:11 +10:00
1a1a30791e v1.12.0 2025-07-03 10:01:03 +10:00
ea1cf481eb chore: extract translations 2025-07-01 21:27:35 +10:00
eda0d5eeb6 fix: open advanced settings when fields are added to templates (#1855) 2025-07-01 21:21:13 +10:00
8da4ab533f fix(add-subject): remove superfluous word (#1866) 2025-07-01 12:34:14 +10:00
8695ef766e v1.12.0-rc.8 2025-06-30 19:47:37 +10:00
7487399123 feat: add more api logs (#1870)
Adds more detailed API logging using Pino
2025-06-30 19:46:32 +10:00
0cc729e9bd feat: add sequential document view logs (#1871)
## Description

Add a new document audit log to detect when the document is viewed. This
should only be visible in the document audit log page

Notes:
1. I wanted to reuse the `DOCUMENT_OPENED` event and add an additional
paramter to track sequential views, but it's not query-able
2. This will log "DOCUMENT_VIEWED" before "DOCUMENT_OPENED" but i don't
think it matters
2025-06-30 19:11:16 +10:00
58d97518c8 v1.12.0-rc.7 2025-06-27 22:17:45 +10:00
20c8969272 fix: get real ip for rate limit key 2025-06-27 22:17:02 +10:00
85ac65e405 v1.12.0-rc.6 2025-06-27 21:46:16 +10:00
e07a497b69 feat: api logging by pino (#1865)
experiemental
2025-06-27 21:44:51 +10:00
21dc4eee62 v1.12.0-rc.5 2025-06-27 18:53:45 +10:00
dc2042a1ee fix: rate limit api endpoints (#1863)
Rate limit API endpoint
2025-06-27 18:50:22 +10:00
bb9ba80edb fix: duplicate fields and recipients when you duplicate a document (#1852) 2025-06-23 16:43:07 +10:00
bfe8c674f2 fix: globalAccessAuth error (#1851) 2025-06-23 10:10:57 +10:00
ebe1baf0a0 chore: extract translations 2025-06-19 15:16:44 +10:00
2345de679b feat: admin monthly active users metric (#1724) 2025-06-19 15:12:17 +10:00
1be0e2842c fix: refactor folders UI/UX (#1770)
- Add folder search
- Used correct HTML elements
- Added missing translations
- Removed automatic folder redirects
- Removed duplicate code
- Added folder loading skeletons and empty states
2025-06-19 14:57:32 +10:00
29a03d4ec7 feat: add inbox counter (#1849) 2025-06-18 13:30:01 +10:00
039cd7d449 fix: remove preconnect font links (#1798) 2025-06-18 12:42:54 +10:00
484f6c8b85 fix: admin metrics broken (#1845) 2025-06-17 21:15:11 +10:00
4fd8a767b2 chore: Update README.md (#1840) 2025-06-13 22:42:38 +10:00
b8e08e88ac fix: api keys not showing (#1839) 2025-06-13 17:20:03 +10:00
031a7b9e36 fix: visibility 2025-06-13 01:02:40 +10:00
12fe045195 fix: visiblity 2025-06-13 00:05:08 +10:00
614106a5e4 fix: rework documents limits logic (#1836) 2025-06-12 13:42:31 +10:00
8be7137b59 v1.12.0-rc.4 2025-06-12 10:27:41 +10:00
31e2a6443e fix: legacy authOptions support for api v1 2025-06-12 10:21:41 +10:00
400d2a2b1a feat: sign out of all sessions (#1797) 2025-06-11 17:57:38 +10:00
e3ce7f94e6 chore: update build 2025-06-11 14:52:23 +10:00
cad04f26e7 feat: sitemap auto-generation for docs (#1822) 2025-06-11 14:09:45 +10:00
d27f0ee0ef fix: duplicate field bugs (#1685) 2025-06-11 13:26:19 +10:00
fd2b413ed9 chore: increase wait times for tests (#1778) 2025-06-11 13:25:21 +10:00
d11ec8fa2a feat: show field coordinates in devmode (#1802)
Show the fields coordinates when the `devmode` search param is present.
It's meant to help API users understand where to position the fields.
2025-06-11 12:28:39 +10:00
b1127b4f0d chore: update readme 2025-06-11 10:42:32 +10:00
be4244fb62 chore: add translations (#1832)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-06-11 10:39:33 +10:00
504a0893ab chore: add organisation docs (#1831) 2025-06-10 20:54:36 +10:00
22a37409c1 v1.12.0-rc.3 2025-06-10 12:49:37 +10:00
50605d5912 chore: add translations (#1830)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-06-10 12:30:36 +10:00
4609fc852d chore: extract translations 2025-06-10 11:52:59 +10:00
e6dc237ad2 feat: add organisations (#1820) 2025-06-10 11:49:52 +10:00
0b37f19641 chore: add translations (#1774) 2025-06-09 16:00:03 +10:00
64c6a51e04 v1.12.0-rc.2 2025-06-07 02:25:14 +10:00
d1eddb02c4 fix: add missing awaits for font normalization 2025-06-07 02:24:59 +10:00
60a623fafd v1.12.0-rc.1 2025-06-07 00:56:40 +10:00
6059b79a8e fix: type error 2025-06-07 00:56:33 +10:00
c73d61955b v1.12.0-rc.0 2025-06-07 00:47:49 +10:00
7c3ca72359 fix: track uninserted fields for multisign 2025-06-07 00:44:41 +10:00
55c8632620 feat: password reauthentication for documents and recipients (#1827)
Adds password reauthentication to our existing reauth providers,
additionally swaps from an exclusive provider to an inclusive type where
multiple methods can be selected to offer a this or that experience.
2025-06-07 00:27:19 +10:00
ce66da0055 feat: multisign embedding (#1823)
Adds the ability to use a multisign embedding for cases where multiple
documents need to be signed in a convenient manner.
2025-06-05 12:58:52 +10:00
695ed418e2 fix: documents failing to seal (#1821)
During our field rework that makes fields appear
more accurately between signing and the completed pdf we swapped to
using text fields. Unfortunately as part of that we dropped using the
Noto font for the text field causing ANSI encoding issues when
encountering certain characters.

This change restores the font and handles a nasty issue we had with our
form flattening reverting our selected font.
2025-06-04 23:29:36 +10:00
93aece9644 chore: dependency updates (#1808) 2025-05-22 14:30:22 +10:00
abd4fddf31 chore: test reo integration (#1806)
---
name: Pull Request
about: Submit changes to the project for review and inclusion
---

## Description

Experimental Short-Term Reo Integration
2025-05-21 15:24:46 +02:00
44bc769e60 v1.11.1 2025-05-20 22:37:46 +10:00
c8f80f7be0 fix: reverse original document logic for api endpoint 2025-05-20 22:37:17 +10:00
8540f24de0 v1.11.0 2025-05-19 15:44:10 +10:00
67203d4bd7 fix: show powered by logic (#1801)
Previous powered by display logic was incorrect, likely due to a merge
conflict.
2025-05-19 14:31:24 +10:00
9d1e638f0f fix: pending tooltip click triggers field (#1800)
Makes it so clicking on the pending field tooltip will trigger the
underlying field it refers to on click if the field can be found within
the DOM.
2025-05-19 10:27:13 +10:00
bd64ad9fef fix: improve multiselect for webhook triggers (#1795)
Replaces https://github.com/documenso/documenso/pull/1660 with the same
code but targeting our main branch.

## Demo

![CleanShot 2025-02-18 at 18 01
05](https://github.com/user-attachments/assets/5afeab95-1a80-4d54-b845-b32cb2e33266)
2025-05-15 13:01:45 +10:00
99b0ad574e feat: bulk add fields (#1683)
## Demo

![CleanShot 2025-03-04 at 02 17
47](https://github.com/user-attachments/assets/2cffaee3-9933-49e9-bdab-eadfd4c35030)

---------

Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2025-05-14 19:35:32 +00:00
9594e1fee8 chore: minor ui fixes (#1793) 2025-05-14 20:08:03 +10:00
5e3a2b8f76 fix: allow prefilling date field (#1794)
Allows the prefilling of date fields when creating a document from a
template.

Current implementation is super dirty and should be replaced asap.
2025-05-14 20:06:53 +10:00
f928503a33 chore: update dropdown icons (#1790)
### Before

![CleanShot 2025-05-12 at 11 11
05@2x](https://github.com/user-attachments/assets/af2a60bf-9676-405d-8c3d-e6b2256b53ae)

### After

![CleanShot 2025-05-12 at 11 10
25@2x](https://github.com/user-attachments/assets/aec67e9c-f0f2-4b0d-9baa-7aa327680cf1)
2025-05-14 16:44:13 +10:00
c389670785 fix: trigger webhook for duplicated documents (#1789) 2025-05-14 16:43:31 +10:00
99ad2eb645 fix: allow download of original document via api (#1788) 2025-05-14 08:22:11 +10:00
2f48679b0b fix: make lang cookie httpOnly (#1783) 2025-05-08 15:59:43 +10:00
e40c5d9d24 v1.10.3 2025-05-03 09:23:25 +10:00
ab323f149f fix: resolve issue with uploading templates 2025-05-03 09:23:17 +10:00
bf1c1ff9dc v1.10.2 2025-05-03 08:11:27 +10:00
516e237966 fix: resolve issue with uploading templates 2025-05-03 08:09:44 +10:00
ac7d24eb12 v1.10.1 2025-05-03 07:39:19 +10:00
0931c472a7 fix: resolve issue with uploading templates 2025-05-03 07:38:48 +10:00
8c9dd5e372 v1.10.0 2025-05-02 12:03:08 +10:00
e108da546d fix: incorrect data for postMessage 2025-05-02 10:50:13 +10:00
17370749b4 feat: add folders (#1711) 2025-05-02 02:46:59 +10:00
12ada567f5 feat: embed authoring part two (#1768) 2025-05-01 23:32:56 +10:00
bdb0b0ea88 feat: certificate qrcode (#1755)
Adds document access tokens and QR code functionality to enable secure
document sharing via URLs. It includes a new document access page that
allows viewing and downloading documents through tokenized links.
2025-04-28 11:30:09 +10:00
6a41a37bd4 feat: download original documents (#1742)
## Preview
![CleanShot 2025-04-10 at 14 26
11@2x](https://github.com/user-attachments/assets/d4984d85-ab40-4d38-8d5c-a1085bde21a2)
2025-04-25 22:44:03 +10:00
d78cfec00e fix: branding logos (#1759) 2025-04-24 16:15:06 +10:00
f0dcf7e9bf fix: signing volume query (#1753)
This pull request updates the implementation of the admin leaderboard,
enhancing data handling and improving type safety. It introduces clearer
differentiation between users and teams, adds additional fields to track
more relevant information, and refactors the querying logic to optimize
performance and maintainability.
2025-04-24 16:14:38 +10:00
6540291055 feat: migrate webhook execution to background jobs (#1694) 2025-04-24 06:00:53 +00:00
193325717d fix: rework fields (#1697)
Rework:
- Field styling to improve visibility
- Field insertions, better alignment, centering and overflows

## Changes

General changes:

- Set default text alignment to left if no meta found
- Reduce borders and rings around fields to allow smaller fields
- Removed lots of redundant duplicated code surrounding field rendering
- Make fields more consistent across viewing, editing and signing
- Add more transparency to fields to allow users to see under fields
- No more optional/required/etc colors when signing, required fields
will be highlighted as orange when form is "validating"

Highlighted internal changes:

- Utilize native PDF fields to insert text, instead of drawing text 
- Change font auto scaling to only apply to when the height overflows
AND no custom font is set

⚠️ Multiline changes:

Multi line is enabled for a field under these conditions

1. Field content exceeds field width
2. Field includes a new line
3. Field type is TEXT

## [BEFORE] Field UI Signing 


![image](https://github.com/user-attachments/assets/ea002743-faeb-477c-a239-3ed240b54f55)

## [AFTER] Field UI Signing 


![image](https://github.com/user-attachments/assets/0f8eb252-4cf3-4d96-8d4f-cd085881b78c)

## [BEFORE] Signing a checkbox


![image](https://github.com/user-attachments/assets/4567d745-e1da-4202-a758-5d3c178c930e)

![image](https://github.com/user-attachments/assets/c25068e7-fe80-40f5-b63a-e8a0d4b38b6c)

## [AFTER] Signing a checkbox


![image](https://github.com/user-attachments/assets/effa5e3d-385a-4c35-bc8a-405386dd27d6)

![image](https://github.com/user-attachments/assets/64be34a9-0b32-424d-9264-15361c03eca5)

## [BEFORE] What a 2nd recipient sees once someone else signed a
document


![image](https://github.com/user-attachments/assets/21c21ae2-fc62-4ccc-880a-46aab012aa70)

## [AFTER] What a 2nd recipient sees once someone else signed a document


![image](https://github.com/user-attachments/assets/ae51677b-f1d5-4008-a7fd-756533166542)

## **[BEFORE]** Inserting fields


![image](https://github.com/user-attachments/assets/1a8bb8da-9a15-4deb-bc28-eb349414465c)

## **[AFTER]** Inserting fields


![image](https://github.com/user-attachments/assets/c52c5238-9836-45aa-b8a4-bc24a3462f40)

## Overflows, multilines and field alignments testing

Debugging borders:
- Red border = The original field placement without any modifications
- Blue border = The available space to overflow

### Single line overflows and field alignments 

This is left aligned fields, overflow will always go to the end of the
page and will not wrap


![image](https://github.com/user-attachments/assets/47003658-783e-4f9c-adbf-c4686804d98f)

This is center aligned fields, the max width is the closest edge to the
page * 2


![image](https://github.com/user-attachments/assets/05a38093-75d6-4600-bae2-21ecff63e115)

This is right aligned text, the width will extend all the way to the
left hand side of the page


![image](https://github.com/user-attachments/assets/6a9d84a8-4166-4626-9fb3-1577fac2571e)

### Multiline line overflows and field alignments 

These are text fields that can be overflowed


![image](https://github.com/user-attachments/assets/f7b5456e-2c49-48b2-8d4c-ab1dc3401644)

Another example of left aligned text overflows with more text


![image](https://github.com/user-attachments/assets/3db6b35e-4c8d-4ffe-8036-0da760d9c167)
2025-04-23 21:40:42 +10:00
b94645a451 fix: optional fields being required in direct links (#1752) 2025-04-21 16:34:29 +10:00
7e6704faae chore: update tests 2025-04-21 16:23:50 +10:00
cf17fc61bc chore: update tests 2025-04-21 16:07:19 +10:00
6df8b3aac8 chore: update ci 2025-04-21 14:29:40 +10:00
fdb31772db chore: update tests 2025-04-21 14:13:12 +10:00
a3dfd81870 chore: update playwright config 2025-04-21 13:27:19 +10:00
755ef697ba chore: update playwright config 2025-04-21 13:03:29 +10:00
37cc41d713 fix: skip immediate expiration presign test 2025-04-21 12:41:38 +10:00
dd2ef3a657 v1.10.0-rc.5 2025-04-17 23:01:43 +10:00
435b3ca4f8 chore: remove legacy document update route (#1751)
Remove deprecated route
2025-04-17 16:36:10 +10:00
278cd8a9de fix: always show ip and useragent in certificate 2025-04-17 12:55:03 +10:00
f1526315f5 feat: limit free teams platform plan (#1673)
This pull request removes the `id` field from
`IsDocumentPlatformOptions` in `is-document-platform.ts` and updates the
billing logic in `create-team.ts`: platform plan users create their
first team free, but pay for subsequent teams; non-platform users need
an active team subscription if billing is enabled.
2025-04-15 21:32:15 +10:00
353a7e8e0d fix: dynamic route for team transfer (#1730)
fix: dynamic route handling for /team/verify/transfer/:token
2025-04-15 21:30:44 +10:00
34b2504268 chore: husky (#1706) 2025-04-15 21:29:03 +10:00
566abda36b chore: update render build command (#1748) 2025-04-15 19:06:06 +10:00
9121a062b3 chore: add docs for authoring 2025-04-14 11:31:54 +10:00
e613e0e347 feat: support embedded authoring for creation (#1741)
Adds support for creating documents and templates
using our embed components.

Support is super primitive at the moment and is being polished.
2025-04-11 00:20:39 +10:00
95aae52fa4 chore: add translations (#1715)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2025-04-10 12:24:07 +10:00
5958f38719 chore: set the default value on the top (#1734) 2025-04-08 23:35:32 +10:00
419bc02171 docs: prefill fields (#1688) 2025-04-04 00:03:37 +11:00
5e4956f3a2 fix: zero month addition (#1733)
- Add zero month at the begining of each metric on the open page
2025-04-01 11:12:41 +00:00
da71613c9f v1.10.0-rc.4 2025-03-31 20:02:22 +11:00
4d6efe091e fix: pass document meta to readonly field component (#1737)
## Description

Previously we weren't passing the DocumentMeta to our readonly field
component which is used for displaying completed fields by other
recipients.

Due to this dates that were not using the default format were displaying
as invalid date adding confusion to the signing process.

## Related Issue

Reported via support email.

## Changes Made

- Pass the document meta to the readonly field component.
- Support showing completed fields within the embedding UI.

## Testing Performed

- Manual testing
2025-03-31 17:14:56 +11:00
7e6ac4db40 fix: direct template redirects (#1727) 2025-03-28 14:45:54 +11:00
a87af910c7 v1.10.0-rc.2 2025-03-28 01:50:59 +11:00
e37b005d7f chore: update dockerfile 2025-03-28 01:28:49 +11:00
73f8518b47 chore: update tests 2025-03-28 01:21:48 +11:00
ac3deb113e chore: update ci 2025-03-27 22:49:59 +11:00
c82388c40a fix: remove console.log embed document completed (#1723) 2025-03-25 16:36:52 +02:00
31be548939 fix: duplicate webhook calls on document complete (#1721)
Fix webhooks being sent twice due to duplicate frontend calls

Updated the assistant confirmation dialog so the next signer is always
visible (if dictate is enabled). Because if the form is invalid (due to
no name) there is no visual queue that the form is invalid (since it's
hidden)

## Notes

Didn't bother to remove the weird assistants form since it currently
works for now


![image](https://github.com/user-attachments/assets/47910fec-e05e-486a-a61d-16078d948893)

## Tests

- Currently running locally
- Tested webhooks via network tab and via webhook.site
2025-03-25 21:59:13 +11:00
063fd32f18 feat: add signature configurations (#1710)
Add ability to enable or disable allowed signature types:
- Drawn
- Typed
- Uploaded

**Tabbed style signature dialog**

![image](https://github.com/user-attachments/assets/a816fab6-b071-42a5-bb5c-6d4a2572431e)

**Document settings**

![image](https://github.com/user-attachments/assets/f0c1bff1-6be1-4c87-b384-1666fa25d7a6)

**Team preferences**

![image](https://github.com/user-attachments/assets/8767b05e-1463-4087-8672-f3f43d8b0f2c)

- Add multiselect to select allowed signatures in document and templates
settings tab
- Add multiselect to select allowed signatures in teams preferences
- Removed "Enable typed signatures" from document/template edit page
- Refactored signature pad to use tabs instead of an all in one
signature pad

Added E2E tests to check settings are applied correctly for documents
and templates
2025-03-24 17:13:11 +11:00
231f51bd1f v1.10.0-rc.1 2025-03-22 17:34:33 +11:00
a8de8368a2 fix: hide powered by on certificate for platform documents 2025-03-22 12:04:08 +11:00
7dd331addf fix: allow blank rejection reasons 2025-03-22 12:01:18 +11:00
c6743a7cec v1.10.0-rc.0 2025-03-22 03:23:23 +11:00
efbc097191 fix: unblock last signer when using dictation 2025-03-22 02:34:12 +11:00
f1525991dc feat: dictate next signer (#1719)
Adds next recipient dictation functionality to document signing flow,
allowing assistants and signers to update the next recipient's
information during the signing process.

## Related Issue

N/A

## Changes Made

- Added form handling for next recipient dictation in signing dialogs
- Implemented UI for updating next recipient information
- Added e2e tests covering dictation scenarios:
  - Regular signing with dictation enabled
  - Assistant role with dictation
  - Parallel signing flow
  - Disabled dictation state

## Testing Performed

- Added comprehensive e2e tests covering:
  - Sequential signing with dictation
  - Assistant role dictation
  - Parallel signing without dictation
  - Form validation and state management
- Tested on Chrome and Firefox
- Verified recipient state updates in database
2025-03-21 13:27:04 +11:00
fb173e4d0e chore: update docker build scripts 2025-03-20 10:52:33 +11:00
d422ffa873 chore: add terms and privacy policy link (#1707) 2025-03-19 19:29:09 +11:00
55b7697316 chore: update d script in package.json (#1703)
Add the `translate:compile` command to the `d` script.
2025-03-14 16:15:57 +11:00
67bbb6c6f4 fix: autosigning fields with direct links (#1696)
## Description

The changes in `sign-direct-template.tsx` automatically fill in field
values for text, number, and dropdown fields when default values are
present or if the fields are read-only. In `checkbox-field.tsx`, the
changes fix the checkbox signing by checking if the validation is met
and improving how it saves or removes checkbox choices.

## Testing Performed

I tested the code locally with a variety of documents/fields.

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [x] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.
2025-03-13 11:18:01 +02:00
63a4bab0fe feat: better document rejection (#1702)
Improves the existing document rejection process by actually marking a
document as completed cancelling further actions.

## Related Issue

N/A

## Changes Made

- Added a new rejection status for documents
- Updated a million areas that check for document completion
- Updated email sending, so rejection is confirmed for the rejecting
recipient while other recipients are notified that the document is now
cancelled.

## Testing Performed

- Ran the testing suite to ensure there are no regressions.
- Performed manual testing of current core flows.
2025-03-13 15:08:57 +11:00
9f17c1e48e fix: adjust desktop nav search button width and spacing (#1699) 2025-03-13 10:52:01 +11:00
91ae818213 fix: missing prefillfields property from the api v2 documentation (#1700) 2025-03-12 22:54:58 +11:00
a0ace803cf fix: admin signing page crash 2025-03-12 16:53:09 +11:00
b3db3be8e9 fix: signing field disabled when pointer is out of canvas (#1652) 2025-03-12 16:44:21 +11:00
44cdbeecb4 fix: improve layout and truncate document information in logs page (#1656) 2025-03-12 16:31:03 +11:00
Tom
7214965c0c chore: update French translations (#1679) 2025-03-12 16:22:06 +11:00
8d6bf91d12 fix: persist theme cookie for a much longer time (#1693) 2025-03-12 16:09:37 +11:00
fec078081b fix: correct signer deletion (#1596) 2025-03-12 16:05:45 +11:00
c646afcd97 fix: tests 2025-03-09 15:10:19 +11:00
63d990ce8d fix: optional fields in embeds (#1691) 2025-03-09 14:41:17 +11:00
aa7d6b28a4 docs: Update documentation to match reality. colorPrimary, colorBackground,… (#1666)
Update documentation to match reality. colorPrimary, colorBackground,
and borderRadius do not exist according to the schema:
280251cfdd/packages/react/src/css-vars.ts
2025-03-09 14:38:51 +11:00
b990532633 fix: remove refresh on focus 2025-03-08 15:30:13 +11:00
65be37514f fix: prefill fields (#1689)
Users can now selectively choose which properties to pre-fill for each
field - from just a label to all available properties.
2025-03-07 09:09:15 +11:00
0df29fce36 fix: invalid request body (#1686)
Fix the invalid request body so the webhooks work again.
2025-03-06 19:47:24 +11:00
ba5b7ce480 feat: hide signature ui when theres no signature field (#1676) 2025-03-06 19:47:02 +11:00
422770a8c7 feat: allow fields prefill when generating a document from a template (#1615)
This change allows API users to pre-fill fields with values by
passing the data in the request body. Example body for V2 API endpoint
`/api/v2-beta/template/use`:

```json
{
    "templateId": 1,
    "recipients": [
        {
            "id": 1,
            "email": "signer1@mail.com",
            "name": "Signer 1"
        },
        {
            "id": 2,
            "email": "signer2@mail.com",
            "name": "Signer 2"
        }
    ],
    "prefillValues": [
        {
            "id": 14,
            "fieldMeta": {
                "type": "text",
                "label": "my label",
                "placeholder": "text placeholder test",
                "text": "auto-sign value",
                "characterLimit": 25,
                "textAlign": "right",
                "fontSize": 94,
                "required": true
            }
        },
        {
            "id": 15,
            "fieldMeta": {
                "type": "radio",
                "label": "radio label",
                "placeholder": "new radio placeholder",
                "required": false,
                "readOnly": true,
                "values": [
                    {
                        "id": 2,
                        "checked": true,
                        "value": "radio val 1"
                    },
                    {
                        "id": 3,
                        "checked": false,
                        "value": "radio val 2"
                    }
                ]
            }
        },
        {
            "id": 16,
            "fieldMeta": {
                "type": "dropdown",
                "label": "dropdown label",
                "placeholder": "DD placeholder",
                "required": false,
                "readOnly": false,
                "values": [
                    {
                        "value": "option 1"
                    },
                    {
                        "value": "option 2"
                    },
                    {
                        "value": "option 3"
                    }
                ],
                "defaultValue": "option 2"
            }
        }
    ],
    "distributeDocument": false,
    "customDocumentDataId": ""
}
```
2025-03-06 19:45:33 +11:00
083a706373 fix: duplex and 2fa refresh 2025-03-04 11:41:38 +11:00
db326cb4a9 fix: posthog reverse proxy 2025-03-04 10:48:19 +11:00
d664f571d6 fix: posthog reverse proxy 2025-03-04 10:46:59 +11:00
7c38970ee8 fix: update error logging 2025-03-04 01:41:39 +11:00
e08d62c844 fix: remove invalid prisma zod schemas 2025-03-04 01:20:13 +11:00
25bb6ffe77 fix: imports 2025-03-03 14:49:28 +11:00
e79d762710 chore: add label for checkbox and radio fields (#1607) 2025-03-03 13:46:29 +11:00
d970976299 fix: remove auto-expand in embeddding 2025-02-28 14:46:15 +11:00
3dce814ab2 fix: stripe price fetch (#1677)
Currently Stripe prices search is omitting a price for an unknown
reason.

Changed our fetch logic to use `list` instead of `search` allows us to
work around the issue.

It's unknown on the performance impact of using `list` vs `search`
2025-02-28 14:44:06 +11:00
ad520bb032 fix: remove oauth from embeds 2025-02-27 14:08:59 +11:00
596d30e2e5 fix: remove lazy pdf loader 2025-02-26 21:48:06 +11:00
6474b4a524 fix: add preferred team middleware 2025-02-26 19:42:42 +11:00
5b4db51051 fix: react-pdf canvas build 2025-02-26 18:39:21 +11:00
cf58c80e31 fix: handle empty field meta for checkboxes 2025-02-26 15:30:51 +11:00
11dbb8873e docs: add the v2 api staging base url (#1671) 2025-02-26 15:30:32 +11:00
bc7907271b fix: unbreak build for docker 2025-02-25 21:46:51 +11:00
9b376d34cf feat: add stripe dev cli 2025-02-25 21:22:28 +11:00
deea99d865 feat: search by externalId 2025-02-25 20:07:47 +11:00
3328074f51 fix: early adopters can use platform features 2025-02-25 20:07:40 +11:00
5e69665e00 fix: rr7 github build 2025-02-25 16:52:10 +11:00
c1c7cfaf8b chore: cleanup 2025-02-25 16:37:36 +11:00
7e8955b89c fix: add posthog error monitor 2025-02-25 15:14:45 +11:00
cedd5e87b1 chore: update API documentation 2025-02-25 02:36:08 +11:00
5255e8671f chore: refactor pdf worker loader 2025-02-24 21:47:06 +11:00
d4c1bad407 fix: add default oauth user url 2025-02-23 18:49:22 +11:00
01dccb7916 chore: flattern routes 2025-02-21 15:53:23 +11:00
483d7caef7 feat: allow document rejection in embeds (#1662) 2025-02-21 01:27:03 +11:00
139bc265c7 fix: migrate billing to RR7 2025-02-21 01:16:23 +11:00
991ce5ff46 fix: update teams API tokens logic 2025-02-21 00:34:50 +11:00
7728c8641c fix: share opengraph 2025-02-20 15:38:06 +11:00
50a41d0799 fix: pdf viewer and embeds 2025-02-20 15:06:36 +11:00
250381fec8 fix: billing 2025-02-20 12:17:55 +11:00
d2f3d24542 chore: update docs 2025-02-19 22:36:17 +11:00
ec07092bf6 fix: session refresh 2025-02-19 22:29:30 +11:00
63e2ef0abf fix: static caching 2025-02-19 21:35:35 +11:00
90ce52164c chore: add password tests 2025-02-19 18:41:53 +11:00
ac30654913 fix: add auth session lifetime 2025-02-19 18:04:36 +11:00
24f3ecd94f fix: remove marketing url 2025-02-19 16:45:54 +11:00
a319ea0f5e fix: add public profiles tests 2025-02-19 16:07:04 +11:00
5ce2bae39d fix: resolve internal pdf translations 2025-02-19 14:43:35 +11:00
5d86e84217 fix: prepare auth migration (#1648)
Add schema session migration in preparation for auth migration.
2025-02-18 15:19:42 +11:00
79e26a9a46 fix: remove session migration 2025-02-18 15:19:39 +11:00
dd602a7e1c fix: themes 2025-02-18 15:17:13 +11:00
fb16214dc5 chore: add asssitant role to the docs (#1638) 2025-02-17 23:28:00 +11:00
5fc724b247 fix: rework sessions 2025-02-17 22:46:36 +11:00
1ed1cb0773 chore: refactor sessions 2025-02-16 00:44:01 +11:00
8d5fafec27 feat: add static cache 2025-02-15 00:08:36 +11:00
0f6f236e0c fix: firefox fouc 2025-02-14 23:02:45 +11:00
e518985833 fix: migrate 2fa to custom auth 2025-02-14 22:00:55 +11:00
595e901bc2 fix: make auth migration more flexible 2025-02-14 19:22:11 +11:00
df8ea09021 fix: add oidc env variables 2025-02-14 18:11:54 +11:00
180656978b feat: add themes 2025-02-14 17:50:23 +11:00
28f5177064 fix: dialogs with search params 2025-02-14 16:14:02 +11:00
31de86e425 feat: add oidc 2025-02-14 16:01:16 +11:00
113ab293bb chore: make all the docker stuff work 2025-02-14 14:53:01 +11:00
1c4878e526 fix: documentation build 2025-02-13 21:21:51 +11:00
92db4d68db fix: cleanup env variables 2025-02-13 20:56:44 +11:00
7379391f92 fix: migrate translations 2025-02-13 20:24:27 +11:00
ebc2b00067 fix: add sign up hook 2025-02-13 20:21:23 +11:00
87dcdd44cd chore: update local seed data (#1622)
Add multiple example documents, pending documents, and templates for
both admin and example users
2025-02-13 19:50:05 +11:00
b205f7e5f3 fix: typed signature not working (#1635)
The `typedSignatureEnabled` prop was removed from the `SignatureField`
component, which broke the typed signature meaning that nobody could
sign documents by typing their signature.
2025-02-13 19:47:38 +11:00
c5d5355cf7 fix: assistant mode breaks for number fields 2025-02-13 19:46:14 +11:00
5fac29a07f fix: add css targets for embeds 2025-02-13 19:45:54 +11:00
1aaacab6ca fix: temp field label/text truncation (#1565)
TEMP: Fix the truncation of the field label/text.
2025-02-13 19:43:35 +11:00
06076c1809 fix: unable to check on the checkbox field (#1593)
This change prevents race conditions between state updates and API
operations by updating local state immediately before making async
calls.
2025-02-13 19:42:08 +11:00
c0ae68c28b feat: assistant role (#1588)
Introduces the ability for users with the **Assistant** role to prefill
fields on behalf of other signers. Assistants can fill in various field
types such as text, checkboxes, dates, and more, streamlining the
document preparation process before it reaches the final signers.
2025-02-13 19:37:34 +11:00
3e106c1a2d chore: api v2 docs (#1620)
chore update docs for api v2 announce
2025-02-13 18:49:37 +11:00
741639ee78 fix: improve move to team display logic 2025-02-13 18:49:03 +11:00
0b3638c42c feat: add Polish and Italian (#1618) 2025-02-13 18:48:37 +11:00
0f50110853 fix: create global settings on team creation (#1601)
The global team settings weren't created when creating a new team.

## Changes Made

The global team settings are now created when a new team is created.
2025-02-13 18:47:59 +11:00
b0f8c83134 chore: add cancelled webhook event (#1608) 2025-02-13 18:47:43 +11:00
c9e8a32471 feat: bulk send templates via csv (#1578)
Implements a bulk send feature allowing users to upload a CSV file to
create multiple documents from a template. Includes CSV template
generation, background processing, and email notifications.
2025-02-13 18:44:29 +11:00
84b193d99c fix: tidy document invite email render logic (#1597)
Updates one of our confusing ternaries to use `ts-pattern` for rendering
the conditional blocks making it easy to follow the logic occurring.
2025-02-13 18:34:38 +11:00
b03c5ab1a7 fix: admin leaderboard query sorting (#1548) 2025-02-13 18:32:38 +11:00
9db42accf3 feat: add text align option to fields (#1610)
Adds the ability to align text to the left, center or right for relevant
fields.

Previously text was always centered which can be less desirable.

See attached debug document which has left, center and right text
alignments set for fields.

<img width="614" alt="image"
src="https://github.com/user-attachments/assets/361a030e-813d-458b-9c7a-ff4c9fa5e33c"
/>

N/A

- Added text align option
- Update the insert in pdf method to support different alignments
- Added a debug mode to field insertion

- Ran manual tests using the debug mode
2025-02-13 18:28:33 +11:00
383b5f78f0 feat: migrate nextjs to rr7 2025-02-13 14:10:38 +11:00
9183f668d3 chore: bump node version for docker 2025-01-27 12:20:04 +11:00
54ea96391a fix: correct redirect after document duplication (#1595) 2025-01-23 16:34:22 +11:00
42d24fd1a1 feat: copy, paste, duplicate template fields (#1594) 2025-01-23 14:28:26 +11:00
dc36a8182c v1.9.0-rc.11 2025-01-21 09:49:22 +11:00
0ef85b47b1 fix: handle empty object as fieldMeta 2025-01-21 09:46:54 +11:00
058d9dd0ba v1.9.0-rc.10 2025-01-20 19:54:39 +11:00
74bb230247 fix: add empty success responses (#1600) 2025-01-20 19:47:39 +11:00
7c1e0f34e8 v1.9.0-rc.9 2025-01-20 16:08:15 +11:00
7e31323faa fix: add team context to more vanilla client usages 2025-01-20 15:53:28 +11:00
a28cdf437b feat: add get field endpoints (#1599) 2025-01-20 15:53:12 +11:00
80dfbeb16f feat: add angular embedding docs (#1592) 2025-01-20 09:35:47 +11:00
9de3a32ceb fix: pass team id to vanilla trpc client 2025-01-20 09:30:36 +11:00
0d3864548c fix: bump trpc and openapi packages (#1591) 2025-01-19 22:07:02 +11:00
9e03747e43 feat: add create document beta endpoint (#1584) 2025-01-16 13:36:00 +11:00
5750f2b477 feat: add prisma json types (#1583) 2025-01-15 13:46:45 +11:00
901be70f97 feat: add consistent response schemas (#1582) 2025-01-14 00:43:35 +11:00
7d0a9c6439 fix: refactor prisma relations (#1581) 2025-01-13 13:41:53 +11:00
48b55758e3 feat: ignore unrecognized fields from authorization response (#1479)
When authenticating using OIDC some IDPs send additional fields in their
authorization response. 

This leads to an error because these fields can't be persisted to the DB 
through the auth.js prisma adapter. 

This PR solves this by deleting all unrecognized fields from the 
authorization response before persisting. 

This behaviour is also compliant to 
[RFC6749 Section 4.1.2](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2)
2025-01-13 11:05:37 +11:00
dcaccb65f2 v1.9.0-rc.8 2025-01-13 10:21:05 +11:00
723e1b4ea2 fix: include all template meta in findTemplates 2025-01-13 09:34:23 +11:00
08a69c6168 fix: pending document edit (#1580)
Fix issue where you cannot edit a pending document when there is a CCer
recipient.
2025-01-11 22:31:59 +11:00
948d9c24cf fix: broken direct template webhook (#1579) 2025-01-11 21:42:33 +11:00
ebbe922982 feat: add template and field endpoints (#1572) 2025-01-11 15:33:20 +11:00
6520bbd5e3 Update FEATURES
chore: typo
2025-01-10 14:25:39 +01:00
4e197ac24c v1.9.0-rc.7 2025-01-09 15:07:11 +11:00
f707e5fb10 fix: update template field schema (#1575)
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2025-01-09 12:06:17 +11:00
6fc5e565d0 fix: add document visibility to template (#1566)
Adds the visibility property to templates
2025-01-09 10:14:24 +11:00
07c852744b v1.9.0-rc.6 2025-01-08 20:18:09 +11:00
4fab98c633 feat: allow switching document when using templates (#1571)
Adds the ability to upload a custom document when using a template.

This is useful when you have a given fixed template with placeholder
values that you want to decorate with Documenso fields but will then
create a final specialised document when sending it out to a given
recipient.
2025-01-07 16:13:35 +11:00
18ca0cf3d6 chore: add translations (#1564) 2025-01-02 10:36:05 +11:00
b3e044e278 fix: label stable releases as latest (#1567)
adds missing 'v' in regex  #1405
2025-01-02 10:07:25 +11:00
e2a250063f fix: crowdin config 2024-12-31 17:25:33 +11:00
4085151f80 fix: merge common and web po files (#1563) 2024-12-31 17:20:58 +11:00
0d3681e26a fix: remove marketing remains 2024-12-31 15:53:15 +11:00
cfe7b3a51f fix: remove marketing (#1562) 2024-12-31 15:45:22 +11:00
08d3d6a80a fix: improve recipient status display
Improves the display of the recipients status when
distribution method is set to none.

Previously we had a ton of checks for sendStatus = SENT
which will never trigger when distributing manually causing
some confusion.
2024-12-31 14:54:19 +11:00
9d83bda12c fix: standardise checkboxes
Checkboxes were previously styled super wonky due to
the usage of checkboxClassName which styled the checkbox
trigger.

This change reverts all that and leaves it with sensible defaults
across dark and light mode.
2024-12-31 11:55:49 +11:00
22fd1b5be1 fix: default to user timezone (#1559)
Passes the timezone of the user uploading the document/template via the
UI to the server.

If the user uploads a document/template via the API and doesn't set a
timezone, it defaults to `Etc/UTC`.
2024-12-31 10:27:24 +11:00
df33fbf91b feat: admin ui for disabling users (#1547) 2024-12-30 14:45:33 +11:00
ee6efc4cca fix: avoid having a drawn and typed signature at the same time (#1516) 2024-12-27 20:29:12 +11:00
6da15ab12b feat: open the advanced settings automatically (#1508) 2024-12-27 19:57:24 +11:00
Tom
7ef2a8769b chore: update French translations (#1555) 2024-12-27 19:39:57 +11:00
487f52e194 feat: enable optional fields (#1470) 2024-12-27 19:30:44 +11:00
39b1c5bbec feat: additional valid password (#1456) 2024-12-27 16:02:45 +11:00
32857bbfeb fix: make small fields draggable (#1551) 2024-12-27 15:22:56 +11:00
41218e2585 chore: extract translations 2024-12-26 22:08:52 +11:00
a1a2d0801b feat: notify owner when a recipient signs (#1549) 2024-12-26 22:04:13 +11:00
c588c09b26 fix: remove unwanted semicolon (#1545) 2024-12-26 17:28:22 +11:00
74382e21e7 feat: add get recipient route (#1553) 2024-12-26 17:25:14 +11:00
8a7ec7e982 fix: billing page formatting (#1554) 2024-12-26 17:20:08 +11:00
2948a33bf9 fix: tests (#1556) 2024-12-26 17:00:55 +11:00
98b2da5018 v1.9.0-rc.5 2024-12-26 13:41:04 +11:00
fc1f76b543 fix: checkbox logic (#1537)
## Description

<!--- Describe the changes introduced by this pull request. -->
<!--- Explain what problem it solves or what feature/fix it adds. -->

## Related Issue

<!--- If this pull request is related to a specific issue, reference it
here using #issue_number. -->
<!--- For example, "Fixes #123" or "Addresses #456". -->

## Changes Made

<!--- Provide a summary of the changes made in this pull request. -->
<!--- Include any relevant technical details or architecture changes.
-->

- Change 1
- Change 2
- ...

## Testing Performed

<!--- Describe the testing that you have performed to validate these
changes. -->
<!--- Include information about test cases, testing environments, and
results. -->

- Tested feature X in scenario Y.
- Ran unit tests for component Z.
- Tested on browsers A, B, and C.
- ...

## Checklist

<!--- Please check the boxes that apply to this pull request. -->
<!--- You can add or remove items as needed. -->

- [ ] I have tested these changes locally and they work as expected.
- [ ] I have added/updated tests that prove the effectiveness of these
changes.
- [ ] I have updated the documentation to reflect these changes, if
applicable.
- [ ] I have followed the project's coding style guidelines.
- [ ] I have addressed the code review feedback from the previous
submission, if applicable.

## Additional Notes

<!--- Provide any additional context or notes for the reviewers. -->
<!--- This might include details about design decisions, potential
concerns, or anything else relevant. -->
2024-12-23 12:06:47 +02:00
22c9fb777b fix: perf improvements 2024-12-18 15:01:57 +11:00
2da051a7f9 v1.9.0-rc.4 2024-12-18 08:14:50 +11:00
390a317bd3 fix: normalize pdf on the server 2024-12-18 08:14:14 +11:00
c161553d1d feat: add disabled property for user (#1546) 2024-12-17 22:35:59 +11:00
c960a48b4f fix: z-index of field settings (#1469) 2024-12-17 17:09:58 +11:00
9502f4361d fix: fieldtooltip blocking the field click (#1538)
## Before (error)


https://github.com/user-attachments/assets/525e6c04-fc03-41a7-8299-2a753e9e9fa6

## After (fixed)


https://github.com/user-attachments/assets/67f7e592-c5ca-47f4-962c-e4a848522d43
2024-12-17 17:04:20 +11:00
82deab41f4 fix: move permission check outside the document visibility component (#1543)
PR created because of this comment
https://github.com/documenso/documenso/pull/1521#discussion_r1881895305.
2024-12-17 17:03:08 +11:00
2245812f0b fix: document visibility logic (#1521)
Update the logic of document visibility logic and added some tests &
updated some existing ones.
2024-12-16 09:10:40 +02:00
861e9c976b v1.9.0-rc.3 2024-12-16 09:35:33 +11:00
f55808199b feat: make enterprise billing dynamic (#1539) 2024-12-14 13:44:25 +09:00
b4a7f1887d feat: add trpc openapi (#1535) 2024-12-14 01:23:35 +09:00
f73441ee85 chore: prevent user selection within signature pad (#1530)
adds a `select-none` class to the signature pad in order to
prevent iPadOS from becoming too trigger happy with the context menu and
auto corrects. Please ensure this doesn't break anything by accident.
2024-12-13 16:02:26 +11:00
d7de3b08c1 fix: darkmode on radio button and checkbox labels (#1518)
Fixed Radio Button and Checkbox Appearance in Dark Mode
2024-12-13 15:55:40 +11:00
7d201f05d9 fix: admin leaderboard query (#1522)
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
2024-12-13 15:50:52 +11:00
a21ee2cea6 v1.9.0-rc.2 2024-12-13 15:16:26 +11:00
4ad46b81c9 fix: prevent hidden layers from being toggled in pdf viewers (#1528)
https://github.com/user-attachments/assets/e10194ca-212b-40ee-b9a1-85ef54829a40

---------

Co-authored-by: Mythie <me@lucasjamessmith.me>
2024-12-13 14:19:55 +11:00
10b8e785e0 fix: clear invalid drawn signature when switching to typed signature (#1536) 2024-12-13 10:40:22 +11:00
5fbed783fc feat: add controls for sending completion emails to document owners (#1534)
Adds a new `ownerDocumentCompleted` to the email settings that controls
whether a document will be sent to the owner upon completion.

This was previously the only email you couldn't disable and didn't
account for users integrating with just the API and Webhooks.

Also adds a flag to the public `sendDocument` endpoint which will adjust
this setting while sendint the document for users who aren't using
`emailSettings` on the `createDocument` endpoint.
2024-12-12 14:24:07 +11:00
c9fe134852 v1.9.0-rc.1 2024-12-12 10:31:44 +11:00
f2149719e3 fix: resolve issue with embed css injection 2024-12-12 10:14:23 +11:00
161d40cde7 fix: secure passkey cookies (#1533) 2024-12-12 01:16:29 +09:00
76028771b8 fix: add billing leeway (#1532) 2024-12-12 01:10:01 +09:00
5df1a6602e fix: refactor search routes (#1529)
Refactor find endpoints to be consistent in terms of input and output.
2024-12-11 19:39:50 +09:00
3d7b28a92b chore: update tailwind config 2024-12-11 13:52:34 +11:00
ed862413b1 v1.9.0-rc.0 2024-12-11 09:48:01 +11:00
9d02ab4a5e feat: open page api (#1419) 2024-12-10 21:19:05 +11:00
34c0868d77 chore: add openapi description for enterprise field (#1520) 2024-12-10 20:26:28 +11:00
fae9c0ca24 fix: refactor routers (#1523) 2024-12-10 16:11:20 +09:00
dd162205fa fix: prevent accidental signatures (#1515)
![CleanShot 2024-12-06 at 03 30
39](https://github.com/user-attachments/assets/d47dc820-f19d-43b7-a60d-914fc9ab24b8)

![CleanShot 2024-12-06 at 03 32
34](https://github.com/user-attachments/assets/0db98735-8c91-469b-873c-adb19d0fff7b)
2024-12-08 14:17:58 +11:00
a88ae1cc1e chore: extract translations 2024-12-06 16:11:54 +09:00
904948e2bc fix: refactor trpc errors (#1511) 2024-12-06 16:01:24 +09:00
3b6b96f551 chore: remove redundant translations on upload (#1510)
## Description

Clean redundant translations by default.

This should stop the AI from doing strange things to commented out
translations.
2024-12-06 09:04:15 +11:00
67e49c82a3 feat: return fields in GET /documents/:id endpoint (#1317)
To be able to use the PATCH `/api/v1/documents/{id}/fields/{fieldId}`
endpoint, we need to know the fields ID of a particular document. The
issue #1178 suggested to create a new endpoint for this. To be
consistent with the `/templates` endpoint, I propose in this PR to
directly add the `fields` field to the `/documents/:id` endpoint.
2024-12-06 09:03:32 +11:00
9f45fe62e4 fix: refactor teams router (#1500) 2024-12-05 22:14:47 +09:00
9e8094e34c Update README.md (#1509)
🚨 WE ARE LIVE ON PH WITH OUR LATEST LAUNCH 🚀
2024-12-05 13:51:49 +01:00
0e7e9e17c9 v1.8.1 2024-12-05 13:57:05 +11:00
b3ccb3d26f v1.8.1-rc.9 2024-12-05 13:53:35 +11:00
b17370c153 chore: reword some german translations to increase clarity (#1507) 2024-12-05 09:42:10 +11:00
0c53f5b061 v1.8.1-rc.8 2024-12-04 23:29:15 +11:00
ed6157de80 feat: upload signature as img (#1496)
Allow users to upload their signature as an image.

https://github.com/user-attachments/assets/375faad2-f0db-4f44-83d2-d969c5ab4442
2024-12-04 23:22:18 +11:00
5e08d0cffb v1.8.1-rc.7 2024-12-04 22:43:41 +11:00
5565aff7a3 fix: docs content (#1495) 2024-12-04 19:49:44 +09:00
428acf4ac3 fix: dateformat api bug (#1506) 2024-12-04 19:48:44 +09:00
f4b1e5104e feat: add platform plan pricing (#1505)
Add platform plan to the billing page.
2024-12-04 15:42:03 +09:00
a687064a42 v1.8.1-rc.6 2024-12-04 14:58:29 +11:00
8ec69388a5 fix: add document rejection webhook
Adds the document rejection webhook since it was missing.

Additionally, normalises and standardises the webhook body.
2024-12-04 14:35:20 +11:00
f3da11b3e7 fix: e2e tests failing due to same-site cookies 2024-12-04 14:33:21 +11:00
fc84ee8ec2 fix: use default nextauth logic for secure cookies 2024-12-03 21:35:09 +11:00
4282a96ee7 v1.8.1-rc.5 2024-12-03 15:44:10 +11:00
2aae7435f8 fix: auth cookies across iframes (#1501) 2024-12-03 15:28:30 +11:00
bdd33bd335 feat: signing volume (#1358)
adds a signing volume and leaderboard section to the admin panel
2024-12-03 11:27:22 +11:00
9e8d0ac906 v1.8.1-rc.4 2024-12-02 22:07:31 +11:00
f27d0f342c fix: putPdfFile to always include file extension 2024-12-02 22:06:53 +11:00
4326e27a2a v1.8.1-rc.3 2024-12-02 07:48:03 +11:00
62806298cf fix: wrong signing invitation message (#1497) 2024-12-02 07:47:11 +11:00
87186e08b1 v1.8.1-rc.2 2024-11-29 15:09:03 +11:00
b27fd800ed fix: add distribution settings to external api 2024-11-29 14:10:48 +11:00
98d85b086d feat: add initial api logging (#1494)
Improve API logging and error handling between client and server side.
2024-11-28 16:05:37 +07:00
04293968c6 chore: update embedding docs 2024-11-28 15:55:17 +11:00
e6d4005cd1 fix: document title truncation (#1467)
Truncates the document title across various instances where it previously hadn't been truncated.
2024-11-27 10:53:48 +11:00
337bdb3553 v1.8.0-rc.1 2024-11-26 21:26:12 +11:00
ab654a63d8 chore: enable typed signature by default (#1436)
Enable typed signature by default and also add the option to set a typed
signature in the profile page.
2024-11-26 21:03:44 +11:00
dcb7c2436f fix: update prettier and tailwind 2024-11-26 11:47:28 +11:00
fa33f83696 feat: download doc without signing certificate (#1477)
## Description

I added the option of downloading a document without the signing
certificate for teams. They can disable/enable the option in the
preferences tab.

The signing certificate can still be downloaded separately from the
`logs` page.
2024-11-25 15:47:26 +11:00
b15e1d6c47 feat: support whitelabelling in the embedding (#1491)
## Description

Adds support for customising the theme and CSS for the embedding
components which is restricted to platform customers and above.

Additionally adds proper support for the platform plan which will let us
update our stripe products.

<img width="1040" alt="image"
src="https://github.com/user-attachments/assets/f694cd1e-ac93-4dc0-9f78-92fa813f6404">
<img width="1015" alt="image"
src="https://github.com/user-attachments/assets/4209972a-b2bd-40c9-9049-0367382a4de5">
<img width="1065" alt="image"
src="https://github.com/user-attachments/assets/fdbaaaa5-a028-4b1d-a58a-ea6224e21abe">


## Related Issue

N/A

## Changes Made

- Added support for using CSS Vars and CSS within the embedding route
- Added a guard for platform and enterprise plans to activate the custom
css
- Added support for the platform plan

## Testing Performed
Yes
2024-11-25 15:47:00 +11:00
cd5adce7df fix: hardcode delete confirmation text to avoid translation mismatch (#1487) 2024-11-22 14:22:31 +07:00
1820 changed files with 152804 additions and 90124 deletions

View File

@ -1,4 +1,7 @@
You are an expert in TypeScript, Node.js, Remix, React, Shadcn UI and Tailwind.
Code Style and Structure:
- Write concise, technical TypeScript code with accurate examples
- Use functional and declarative programming patterns; avoid classes
- Prefer iteration and modularization over code duplication
@ -6,20 +9,25 @@ Code Style and Structure:
- Structure files: exported component, subcomponents, helpers, static content, types
Naming Conventions:
- Use lowercase with dashes for directories (e.g., components/auth-wizard)
- Favor named exports for components
TypeScript Usage:
- Use TypeScript for all code; prefer interfaces over types
- Avoid enums; use maps instead
- Use TypeScript for all code; prefer types over interfaces
- Use functional components with TypeScript interfaces
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
- Use declarative JSX
- Never use 'use client'
- Never use 1 line if statements
Error Handling and Validation:
- Prioritize error handling: handle errors and edge cases early
- Use early returns and guard clauses
- Implement proper error logging and user-friendly messages
@ -28,21 +36,40 @@ Error Handling and Validation:
- Use error boundaries for unexpected errors
UI and Styling:
- Use Shadcn UI, Radix, and Tailwind Aria for components and styling
- 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
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
React forms
Key Conventions:
- Use 'nuqs' for URL search parameter state management
- 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
- Use zod for form validation react-hook-form for forms
- Look at TeamCreateDialog.tsx as an example of form usage
- 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
Follow Next.js docs for Data Fetching, Rendering, and Routing
TRPC Specifics
- 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

@ -10,13 +10,7 @@
"ghcr.io/devcontainers/features/node:1": {}
},
"onCreateCommand": "./.devcontainer/on-create.sh",
"forwardPorts": [
3000,
54320,
9000,
2500,
1100
],
"forwardPorts": [3000, 54320, 9000, 2500, 1100],
"customizations": {
"vscode": {
"extensions": [
@ -35,4 +29,4 @@
]
}
}
}
}

View File

@ -1,5 +1,4 @@
# [[AUTH]]
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="secret"
# [[CRYPTO]]
@ -19,14 +18,10 @@ NEXT_PRIVATE_OIDC_WELL_KNOWN=""
NEXT_PRIVATE_OIDC_CLIENT_ID=""
NEXT_PRIVATE_OIDC_CLIENT_SECRET=""
NEXT_PRIVATE_OIDC_PROVIDER_LABEL="OIDC"
# This can be used to still allow signups for OIDC connections
# when signup is disabled via `NEXT_PUBLIC_DISABLE_SIGNUP`
NEXT_PRIVATE_OIDC_ALLOW_SIGNUP=""
NEXT_PRIVATE_OIDC_SKIP_VERIFY=""
# [[URLS]]
NEXT_PUBLIC_WEBAPP_URL="http://localhost:3000"
NEXT_PUBLIC_MARKETING_URL="http://localhost:3001"
# URL used by the web app to request itself (e.g. local background jobs)
NEXT_PRIVATE_INTERNAL_WEBAPP_URL="http://localhost:3000"
@ -113,13 +108,9 @@ NEXT_PUBLIC_DOCUMENT_SIZE_UPLOAD_LIMIT=5
# [[STRIPE]]
NEXT_PRIVATE_STRIPE_API_KEY=
NEXT_PRIVATE_STRIPE_WEBHOOK_SECRET=
NEXT_PUBLIC_STRIPE_COMMUNITY_PLAN_MONTHLY_PRICE_ID=
NEXT_PUBLIC_STRIPE_ENTERPRISE_PLAN_MONTHLY_PRICE_ID=
# [[BACKGROUND JOBS]]
NEXT_PRIVATE_JOBS_PROVIDER="local"
NEXT_PRIVATE_TRIGGER_API_KEY=
NEXT_PRIVATE_TRIGGER_API_URL=
NEXT_PRIVATE_INNGEST_EVENT_KEY=
# [[FEATURES]]
@ -135,7 +126,7 @@ E2E_TEST_AUTHENTICATE_USERNAME="Test User"
E2E_TEST_AUTHENTICATE_USER_EMAIL="testuser@mail.com"
E2E_TEST_AUTHENTICATE_USER_PASSWORD="test_Password123"
# This is only required for the marketing site
# [[REDIS]]
NEXT_PRIVATE_REDIS_URL=
NEXT_PRIVATE_REDIS_TOKEN=
# [[LOGGER]]
# OPTIONAL: The file to save the logger output to. Will disable stdout if provided.
NEXT_PRIVATE_LOGGER_FILE_PATH=

View File

@ -5,6 +5,7 @@ module.exports = {
rules: {
'@next/next/no-img-element': 'off',
'no-unreachable': 'error',
'react-hooks/exhaustive-deps': 'off',
},
settings: {
next: {

View File

@ -1,24 +0,0 @@
name: Cache production build binaries
description: 'Cache or restore if necessary'
inputs:
node_version:
required: false
default: v20.x
runs:
using: 'composite'
steps:
- name: Cache production build
uses: actions/cache@v3
id: production-build-cache
with:
path: |
${{ github.workspace }}/apps/web/.next
${{ github.workspace }}/apps/marketing/.next
**/.turbo/**
**/dist/**
key: prod-build-${{ github.run_id }}-${{ hashFiles('package-lock.json') }}
restore-keys: prod-build-
- run: npm run build
shell: bash

View File

@ -2,7 +2,7 @@ name: 'Setup node and cache node_modules'
inputs:
node_version:
required: false
default: v20.x
default: v22.x
runs:
using: 'composite'

View File

@ -11,16 +11,6 @@ updates:
- 'ci'
open-pull-requests-limit: 0
- package-ecosystem: 'npm'
directory: '/apps/marketing'
schedule:
interval: 'weekly'
target-branch: 'main'
labels:
- 'npm dependencies'
- 'frontend'
open-pull-requests-limit: 0
- package-ecosystem: 'npm'
directory: '/apps/web'
schedule:

3
.github/labeler.yml vendored
View File

@ -1,6 +1,3 @@
'apps: marketing':
- apps/marketing/**
'apps: web':
- apps/web/**

View File

@ -26,7 +26,8 @@ jobs:
- name: Copy env
run: cp .env.example .env
- uses: ./.github/actions/cache-build
- name: Build app
run: npm run build
build_docker:
name: Build Docker Image

View File

@ -1,29 +0,0 @@
name: cleanup caches by a branch
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge

View File

@ -30,7 +30,8 @@ jobs:
- uses: ./.github/actions/node-install
- uses: ./.github/actions/cache-build
- name: Build app
run: npm run build
- name: Initialize CodeQL
uses: github/codeql-action/init@v3

View File

@ -1,14 +1,14 @@
name: Playwright Tests
on:
push:
branches: ['main']
branches: ['main', 'feat/rr7']
pull_request:
branches: ['main']
jobs:
e2e_tests:
name: 'E2E Tests'
timeout-minutes: 60
runs-on: ubuntu-latest
runs-on: warp-ubuntu-2204-x64-16x
steps:
- uses: actions/checkout@v4
@ -28,7 +28,11 @@ jobs:
- name: Seed the database
run: npm run prisma:seed
- uses: ./.github/actions/cache-build
- name: Build app
run: npm run build
- name: Install playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npm run ci

View File

@ -90,7 +90,7 @@ jobs:
GIT_SHA="$(git rev-parse HEAD)"
# Check if the version is stable (no rc or beta in the version)
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
docker manifest create \
documenso/documenso:latest \
--amend documenso/documenso-amd64:latest \
@ -99,7 +99,7 @@ jobs:
docker manifest push documenso/documenso:latest
fi
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
docker manifest create \
documenso/documenso:rc \
--amend documenso/documenso-amd64:rc \
@ -127,7 +127,7 @@ jobs:
GIT_SHA="$(git rev-parse HEAD)"
# Check if the version is stable (no rc or beta in the version)
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
docker manifest create \
ghcr.io/documenso/documenso:latest \
--amend ghcr.io/documenso/documenso-amd64:latest \
@ -136,7 +136,7 @@ jobs:
docker manifest push ghcr.io/documenso/documenso:latest
fi
if [[ "$APP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
if [[ "$APP_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
docker manifest create \
ghcr.io/documenso/documenso:rc \
--amend ghcr.io/documenso/documenso-amd64:rc \

3
.gitignore vendored
View File

@ -50,3 +50,6 @@ yarn-error.log*
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# logs
logs.json

View File

@ -4,9 +4,7 @@ tasks:
npm run dx:up &&
cp .env.example .env &&
set -a; source .env &&
export NEXTAUTH_URL="$(gp url 3000)" &&
export NEXT_PUBLIC_WEBAPP_URL="$(gp url 3000)" &&
export NEXT_PUBLIC_MARKETING_URL="$(gp url 3001)"
command: npm run d
ports:

View File

@ -1,4 +1 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run commitlint -- $1

View File

@ -1,16 +1,9 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
SCRIPT_DIR="$(readlink -f "$(dirname "$0")")"
MONOREPO_ROOT="$(readlink -f "$SCRIPT_DIR/../")"
echo "Copying pdf.js"
npm run copy:pdfjs --workspace apps/**
echo "Copying .well-known/ contents"
node "$MONOREPO_ROOT/scripts/copy-wellknown.cjs"
git add "$MONOREPO_ROOT/apps/web/public/"
git add "$MONOREPO_ROOT/apps/marketing/public/"
git add "$MONOREPO_ROOT/apps/remix/public/"
npx lint-staged

2
.npmrc
View File

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

View File

@ -49,8 +49,6 @@ Join us in creating the next generation of open trust infrastructure.
## 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.
- 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.
@ -69,9 +67,9 @@ Contact us if you are interested in our Enterprise plan for large organizations
<a href="https://cal.com/timurercan/enterprise-customers?utm_source=banner&utm_campaign=oss"><img alt="Book us with Cal.com" src="https://cal.com/book-with-cal-dark.svg" /></a>
## Tech Stack
<p align="left">
<a href="https://www.typescriptlang.org"><img src="https://shields.io/badge/TypeScript-3178C6?logo=TypeScript&logoColor=FFF&style=flat-square" alt="TypeScript"></a>
<a href="https://nextjs.org/"><img src="https://img.shields.io/badge/next.js-000000?style=flat-square&logo=nextdotjs&logoColor=white" alt="NextJS"></a>
<a href="https://prisma.io"><img width="122" height="20" src="http://made-with.prisma.io/indigo.svg" alt="Made with Prisma" /></a>
<a href="https://tailwindcss.com/"><img src="https://img.shields.io/badge/tailwindcss-0F172A?&logo=tailwindcss" alt="Tailwind CSS"></a>
<a href=""><img src="" alt=""></a>
@ -81,20 +79,17 @@ Contact us if you are interested in our Enterprise plan for large organizations
<a href=""><img src="" alt=""></a>
</p>
- [Typescript](https://www.typescriptlang.org/) - Language
- [Next.js](https://nextjs.org/) - Framework
- [Prisma](https://www.prisma.io/) - ORM
- [ReactRouter](https://reactrouter.com/) - Framework
- [Prisma](https://www.prisma.io/) - ORM
- [Tailwind](https://tailwindcss.com/) - CSS
- [shadcn/ui](https://ui.shadcn.com/) - Component Library
- [NextAuth.js](https://next-auth.js.org/) - Authentication
- [react-email](https://react.email/) - Email Templates
- [tRPC](https://trpc.io/) - API
- [@documenso/pdf-sign](https://www.npmjs.com/package/@documenso/pdf-sign) - PDF Signatures (launching soon)
- [React-PDF](https://github.com/wojtekmaj/react-pdf) - Viewing PDFs
- [PDF-Lib](https://github.com/Hopding/pdf-lib) - PDF manipulation
- [Stripe](https://stripe.com/) - Payments
- [Vercel](https://vercel.com) - Hosting
<!-- - Support for [opensignpdf (requires Java on server)](https://github.com/open-pdf-sign) is currently planned. -->
@ -104,7 +99,7 @@ Contact us if you are interested in our Enterprise plan for large organizations
To run Documenso locally, you will need
- Node.js (v18 or above)
- Node.js (v22 or above)
- Postgres SQL Database
- Docker (optional)
@ -167,10 +162,8 @@ git clone https://github.com/<your-username>/documenso
4. Set the following environment variables:
- NEXTAUTH_URL
- NEXTAUTH_SECRET
- NEXT_PUBLIC_WEBAPP_URL
- NEXT_PUBLIC_MARKETING_URL
- NEXT_PRIVATE_DATABASE_URL
- NEXT_PRIVATE_DIRECT_DATABASE_URL
- NEXT_PRIVATE_SMTP_FROM_NAME
@ -239,29 +232,27 @@ cp .env.example .env
The following environment variables must be set:
- `NEXTAUTH_URL`
- `NEXTAUTH_SECRET`
- `NEXT_PUBLIC_WEBAPP_URL`
- `NEXT_PUBLIC_MARKETING_URL`
- `NEXT_PRIVATE_DATABASE_URL`
- `NEXT_PRIVATE_DIRECT_DATABASE_URL`
- `NEXT_PRIVATE_SMTP_FROM_NAME`
- `NEXT_PRIVATE_SMTP_FROM_ADDRESS`
> If you are using a reverse proxy in front of Documenso, don't forget to provide the public URL for both `NEXTAUTH_URL` and `NEXT_PUBLIC_WEBAPP_URL` variables!
> If you are using a reverse proxy in front of Documenso, don't forget to provide the public URL for the `NEXT_PUBLIC_WEBAPP_URL` variable!
Now you can install the dependencies and build it:
```
npm i
npm run build:web
npm run build
npm run prisma:migrate-deploy
```
Finally, you can start it with:
```
cd apps/web
cd apps/remix
npm run start
```
@ -282,7 +273,7 @@ After=network.target
Environment=PATH=/path/to/your/node/binaries
Type=simple
User=www-data
WorkingDirectory=/var/www/documenso/apps/web
WorkingDirectory=/var/www/documenso/apps/remix
ExecStart=/usr/bin/next start -p 3500
TimeoutSec=15
Restart=always

View File

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

View File

@ -1,36 +1 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3002](http://localhost:3002) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
# @documenso/documentation

View File

@ -1,7 +1,7 @@
import Link from 'next/link';
import { Button } from '../primitives/button';
import { Card, CardContent } from '../primitives/card';
import { Button } from '@documenso/ui/primitives/button';
import { Card, CardContent } from '@documenso/ui/primitives/card';
type CallToActionProps = {
className?: string;

View File

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

View File

@ -4,11 +4,10 @@
"private": true,
"scripts": {
"dev": "next dev -p 3002",
"build": "next build",
"build": "next build && next-sitemap",
"start": "next start -p 3002",
"lint:fix": "next lint --fix",
"clean": "rimraf .next && rimraf node_modules",
"copy:pdfjs": "node ../../scripts/copy-pdfjs.cjs"
"clean": "rimraf .next && rimraf node_modules"
},
"dependencies": {
"@documenso/assets": "*",
@ -16,7 +15,7 @@
"@documenso/tailwind-config": "*",
"@documenso/trpc": "*",
"@documenso/ui": "*",
"next": "14.2.6",
"next": "14.2.28",
"next-plausible": "^3.12.0",
"nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4",
@ -27,9 +26,7 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5"
"next-sitemap": "^4.2.3",
"typescript": "5.6.2"
}
}
}

View File

@ -4,7 +4,7 @@ import '../styles.css';
export default function App({ Component, pageProps }) {
return (
<PlausibleProvider>
<Component {...pageProps} />;
<Component {...pageProps} />
</PlausibleProvider>
);
}

View File

@ -5,6 +5,7 @@
"title": "Development & Deployment"
},
"local-development": "Local Development",
"developer-mode": "Developer Mode",
"self-hosting": "Self Hosting",
"contributing": "Contributing",
"-- API & Integration Guides": {
@ -14,4 +15,4 @@
"public-api": "Public API",
"embedding": "Embedding",
"webhooks": "Webhooks"
}
}

View File

@ -20,11 +20,7 @@ If you are looking for development notes on translations, you can find them [her
We store our translations in PO files, which are located in our GitHub repository [here](https://github.com/documenso/documenso/tree/main/packages/lib/translations).
The translation files are organized into folders represented by their respective language codes (`en` for English, `de` for German, etc). Each language folder contains three PO files:
1. `web.po`: Translations for the web application
2. `marketing.po`: Translations for the marketing application
3. `common.po`: Shared translations between web and marketing
The translation files are organized into folders represented by their respective language codes (`en` for English, `de` for German, etc).
Each PO file contains translations which look like this:
@ -46,11 +42,10 @@ msgstr "Möchten Sie auffällige Signatur-Links wie diesen senden? <0>Überprüf
### Updating Existing Translations
1. Fork the repository.
2. Navigate to the appropriate language folder.
3. Open the PO file you want to update (web.po, marketing.po, or common.po).
4. Make your changes, ensuring you follow the PO file format.
5. Commit your changes with a message such as `chore: update German translations`
6. Create a Pull Request.
2. Navigate to the appropriate language folder and open the PO file you want to update.
3. Make your changes, ensuring you follow the PO file format.
4. Commit your changes with a message such as `chore: update German translations`
5. Create a Pull Request.
### Adding a New Language

View File

@ -0,0 +1,18 @@
---
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

@ -0,0 +1,11 @@
{
"index": "Get Started",
"react": "React Integration",
"vue": "Vue Integration",
"svelte": "Svelte Integration",
"solid": "Solid Integration",
"preact": "Preact Integration",
"angular": "Angular Integration",
"css-variables": "CSS Variables",
"authoring": "Authoring"
}

View File

@ -0,0 +1,90 @@
---
title: Angular Integration
description: Learn how to use our embedding SDK within your Angular application.
---
# Angular Integration
Our Angular SDK provides a simple way to embed a signing experience within your Angular application. It supports both direct link templates and signing tokens.
## Installation
To install the SDK, run the following command:
```bash
npm install @documenso/embed-angular
```
## Usage
To embed a signing experience, you'll need to provide the token for the document you want to embed. This can be done in a few different ways, depending on your use case.
### Direct Link Template
If you have a direct link template, you can simply provide the token for the template to the `EmbedDirectTemplate` component.
```typescript
import { Component } from '@angular/core';
import { EmbedDirectTemplate } from '@documenso/embed-angular';
@Component({
selector: 'app-embedding',
template: `
<embed-direct-template [token]="token" />
`,
standalone: true,
imports: [EmbedDirectTemplate],
})
export class EmbeddingComponent {
token = 'YOUR_TOKEN_HERE'; // Replace with the actual token
}
```
#### Props
| Prop | Type | Description |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ |
| token | string | The token for the document you want to embed |
| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters |
| name | string (optional) | The name the signer that will be used by default for signing |
| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications |
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
| onFieldSigned | function (optional) | A callback function that will be called when a field is signed |
| onFieldUnsigned | function (optional) | A callback function that will be called when a field is unsigned |
### Signing Token
If you have a signing token, you can provide it to the `EmbedSignDocument` component.
```typescript
import { Component } from '@angular/core';
import { EmbedSignDocument } from '@documenso/embed-angular';
@Component({
selector: 'app-embedding',
template: `
<embed-sign-document [token]="token" />
`,
standalone: true,
imports: [EmbedSignDocument],
})
export class EmbeddingComponent {
token = 'YOUR_TOKEN_HERE'; // Replace with the actual token
}
```
#### Props
| Prop | Type | Description |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------ |
| token | string | The token for the document you want to embed |
| host | string (optional) | The host to be used for the signing experience, relevant for self-hosters |
| name | string (optional) | The name the signer that will be used by default for signing |
| lockName | boolean (optional) | Whether or not the name field should be locked disallowing modifications |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |

View File

@ -0,0 +1,167 @@
---
title: Authoring
description: Learn how to use embedded authoring to create documents and templates in your application
---
# Embedded Authoring
In addition to embedding signing experiences, Documenso now supports embedded authoring, allowing you to integrate document and template creation directly within your application.
## How Embedded Authoring Works
The embedded authoring feature enables your users to create new documents without leaving your application. This process works through secure presign tokens that authenticate the embedding session and manage permissions.
## Creating Documents with Embedded Authoring
To implement document creation in your application, use the `EmbedCreateDocument` component from our SDK:
```jsx
import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/embed-react';
const DocumentCreator = () => {
// You'll need to obtain a presign token using your API key
const presignToken = 'YOUR_PRESIGN_TOKEN';
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateDocument
presignToken={presignToken}
externalId="order-12345"
onDocumentCreated={(data) => {
console.log('Document created with ID:', data.documentId);
console.log('External reference ID:', data.externalId);
}}
/>
</div>
);
};
```
## Obtaining a Presign Token
Before using the `EmbedCreateDocument` component, you'll need to obtain a presign token from your backend. This token authorizes the embedding session.
You can create a presign token by making a request to:
```
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.
You can find more details on this request at our [API Documentation](https://openapi.documenso.com/reference#tag/embedding)
## Configuration Options
The `EmbedCreateDocument` component accepts several configuration options:
| Option | Type | Description |
| ------------------ | ------- | ------------------------------------------------------------------ |
| `presignToken` | string | **Required**. The authentication token for the embedding session. |
| `externalId` | string | Optional reference ID from your system to link with the document. |
| `host` | string | Optional custom host URL. Defaults to `https://app.documenso.com`. |
| `css` | string | Optional custom CSS to style the embedded component. |
| `cssVars` | object | Optional CSS variables for colors, spacing, and more. |
| `darkModeDisabled` | boolean | Optional flag to disable dark mode. |
| `className` | string | Optional CSS class name for the iframe. |
## Feature Toggles
You can customize the authoring experience by enabling or disabling specific features:
```jsx
<EmbedCreateDocument
presignToken="YOUR_PRESIGN_TOKEN"
features={{
allowConfigureSignatureTypes: true,
allowConfigureLanguage: true,
allowConfigureDateFormat: true,
allowConfigureTimezone: true,
allowConfigureRedirectUrl: true,
allowConfigureCommunication: true,
}}
/>
```
## Handling Document Creation Events
The `onDocumentCreated` callback is triggered when a document is successfully created, providing both the document ID and your external reference ID:
```jsx
<EmbedCreateDocument
presignToken="YOUR_PRESIGN_TOKEN"
externalId="order-12345"
onDocumentCreated={(data) => {
// Navigate to a success page
navigate(`/documents/success?id=${data.documentId}`);
// Or update your database with the document ID
updateOrderDocument(data.externalId, data.documentId);
}}
/>
```
## Styling the Embedded Component
You can customize the appearance of the embedded component using standard CSS classes:
```jsx
<EmbedCreateDocument
className="h-screen w-full rounded-lg border-none shadow-md"
presignToken="YOUR_PRESIGN_TOKEN"
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
/>
```
## Complete Integration Example
Here's a complete example of integrating document creation in a React application:
```tsx
import { useState } from 'react';
import { unstable_EmbedCreateDocument as EmbedCreateDocument } from '@documenso/embed-react';
function DocumentCreator() {
// In a real application, you would fetch this token from your backend
// using your API key at /api/v2-beta/embedding/create-presign-token
const presignToken = 'YOUR_PRESIGN_TOKEN';
const [documentId, setDocumentId] = useState<number | null>(null);
if (documentId) {
return (
<div>
<h2>Document Created Successfully!</h2>
<p>Document ID: {documentId}</p>
<button onClick={() => setDocumentId(null)}>Create Another Document</button>
</div>
);
}
return (
<div style={{ height: '800px', width: '100%' }}>
<EmbedCreateDocument
presignToken={presignToken}
externalId="order-12345"
onDocumentCreated={(data) => {
setDocumentId(data.documentId);
}}
/>
</div>
);
}
export default DocumentCreator;
```
With embedded authoring, your users can seamlessly create documents within your application, enhancing the overall user experience and streamlining document workflows.

View File

@ -0,0 +1,197 @@
---
title: CSS Variables
description: Learn about all available CSS variables for customizing your embedded signing experience
---
# CSS Variables
Platform customers have access to a comprehensive set of CSS variables that can be used to customize the appearance of the embedded signing experience. These variables control everything from colors to spacing and can be used to match your application's design system.
## Available Variables
### Colors
| Variable | Description | Default |
| ----------------------- | ---------------------------------- | -------------- |
| `background` | Base background color | System default |
| `foreground` | Base text color | System default |
| `muted` | Muted/subtle background color | System default |
| `mutedForeground` | Muted/subtle text color | System default |
| `popover` | Popover/dropdown background color | System default |
| `popoverForeground` | Popover/dropdown text color | System default |
| `card` | Card background color | System default |
| `cardBorder` | Card border color | System default |
| `cardBorderTint` | Card border tint/highlight color | System default |
| `cardForeground` | Card text color | System default |
| `fieldCard` | Field card background color | System default |
| `fieldCardBorder` | Field card border color | System default |
| `fieldCardForeground` | Field card text color | System default |
| `widget` | Widget background color | System default |
| `widgetForeground` | Widget text color | System default |
| `border` | Default border color | System default |
| `input` | Input field border color | System default |
| `primary` | Primary action/button color | System default |
| `primaryForeground` | Primary action/button text color | System default |
| `secondary` | Secondary action/button color | System default |
| `secondaryForeground` | Secondary action/button text color | System default |
| `accent` | Accent/highlight color | System default |
| `accentForeground` | Accent/highlight text color | System default |
| `destructive` | Destructive/danger action color | System default |
| `destructiveForeground` | Destructive/danger text color | System default |
| `ring` | Focus ring color | System default |
| `warning` | Warning/alert color | System default |
### Spacing and Layout
| Variable | Description | Default |
| -------- | ------------------------------- | -------------- |
| `radius` | Border radius size in REM units | System default |
## Usage Example
Here's how to use these variables in your embedding implementation:
```jsx
const cssVars = {
// Colors
background: '#ffffff',
foreground: '#000000',
primary: '#0000ff',
primaryForeground: '#ffffff',
accent: '#4f46e5',
destructive: '#ef4444',
// Spacing
radius: '0.5rem'
};
// React/Preact
<EmbedDirectTemplate
token={token}
cssVars={cssVars}
/>
// Vue
<EmbedDirectTemplate
:token="token"
:cssVars="cssVars"
/>
// Svelte
<EmbedDirectTemplate
{token}
cssVars={cssVars}
/>
// Solid
<EmbedDirectTemplate
token={token}
cssVars={cssVars}
/>
```
## Color Format
Colors can be specified in any valid CSS color format:
- Hexadecimal: `#ff0000`
- RGB: `rgb(255, 0, 0)`
- HSL: `hsl(0, 100%, 50%)`
- Named colors: `red`
The colors will be automatically converted to the appropriate format internally.
## Best Practices
1. **Maintain Contrast**: When customizing colors, ensure there's sufficient contrast between background and foreground colors for accessibility.
2. **Test Dark Mode**: If you haven't disabled dark mode, test your color variables in both light and dark modes.
3. **Use Your Brand Colors**: Align the primary and accent colors with your brand's color scheme for a cohesive look.
4. **Consistent Radius**: Use a consistent border radius value that matches your application's design system.
## CSS Class Targets
In addition to CSS variables, specific components in the embedded experience can be targeted using CSS classes for more granular styling:
### Component Classes
| Class Name | Description |
| --------------------------------- | ----------------------------------------------------------------------- |
| `.embed--Root` | Main container for the embedded signing experience |
| `.embed--DocumentContainer` | Container for the document and signing widget |
| `.embed--DocumentViewer` | Container for the document viewer |
| `.embed--DocumentWidget` | The signing widget container |
| `.embed--DocumentWidgetContainer` | Outer container for the signing widget, handles positioning |
| `.embed--DocumentWidgetHeader` | Header section of the signing widget |
| `.embed--DocumentWidgetContent` | Main content area of the signing widget |
| `.embed--DocumentWidgetForm` | Form section within the signing widget |
| `.embed--DocumentWidgetFooter` | Footer section of the signing widget |
| `.embed--WaitingForTurn` | Container for the waiting screen when it's not the user's turn to sign |
| `.embed--DocumentCompleted` | Container for the completion screen after signing |
| `.field--FieldRootContainer` | Base container for document fields (signatures, text, checkboxes, etc.) |
Field components also expose several data attributes that can be used for styling different states:
| Data Attribute | Values | Description |
| ------------------- | ---------------------------------------------- | ------------------------------------ |
| `[data-field-type]` | `SIGNATURE`, `TEXT`, `CHECKBOX`, `RADIO`, etc. | The type of field |
| `[data-inserted]` | `true`, `false` | Whether the field has been filled |
| `[data-validate]` | `true`, `false` | Whether the field is being validated |
### Field Styling Example
```css
/* Style all field containers */
.field--FieldRootContainer {
transition: all 200ms ease;
}
/* Style specific field types */
.field--FieldRootContainer[data-field-type='SIGNATURE'] {
background-color: rgba(0, 0, 0, 0.02);
}
/* Style inserted fields */
.field--FieldRootContainer[data-inserted='true'] {
background-color: var(--primary);
opacity: 0.2;
}
/* Style fields being validated */
.field--FieldRootContainer[data-validate='true'] {
border-color: orange;
}
```
### Example Usage
```css
/* Custom styles for the document widget */
.embed--DocumentWidget {
background-color: #ffffff;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
/* Custom styles for the waiting screen */
.embed--WaitingForTurn {
background-color: #f9fafb;
padding: 2rem;
}
/* Responsive adjustments for the document container */
@media (min-width: 768px) {
.embed--DocumentContainer {
gap: 2rem;
}
}
```
## Related
- [React Integration](/developers/embedding/react)
- [Vue Integration](/developers/embedding/vue)
- [Svelte Integration](/developers/embedding/svelte)
- [Solid Integration](/developers/embedding/solid)
- [Preact Integration](/developers/embedding/preact)

View File

@ -5,13 +5,17 @@ description: Learn how to use embedding to bring signing to your own website or
# Embedding
Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, or using generalized web components, this guide will help you get started with embedding Documenso.
Our embedding feature lets you integrate our document signing experience into your own application or website. Whether you're building with React, Preact, Vue, Svelte, Solid, Angular, or using generalized web components, this guide will help you get started with embedding Documenso.
## Availability
Embedding is currently available for all users on a **Teams Plan** and above, as well as **Early Adopter's** within a team (Early Adopters can create a team for free).
In the future, we will roll out a **Platform Plan** that will offer additional enhancements for embedding, including the option to remove Documenso branding for a more customized experience.
Our **Platform Plan** offers enhanced customization features including:
- Custom CSS and styling variables
- Dark mode controls
- The removal of Documenso branding from the embedding experience
## How Embedding Works
@ -22,17 +26,61 @@ Embedding with Documenso allows you to handle document signing in two main ways:
_For most use-cases we recommend using direct templates, however if you have a need for a more advanced integration, we are happy to help you get started._
## Customization Options
### Styling and Theming
Platform customers have access to advanced styling options to customize the embedding experience:
1. **Custom CSS**: You can provide custom CSS to style the embedded component:
```jsx
<EmbedDirectTemplate
token={token}
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
/>
```
2. **CSS Variables**: Fine-tune the appearance using CSS variables for colors, spacing, and more:
```jsx
<EmbedDirectTemplate
token={token}
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
/>
```
For a complete list of available CSS variables and their usage, see our [CSS Variables](/developers/embedding/css-variables) documentation.
3. **Dark Mode Control**: Disable dark mode if it doesn't match your application's theme:
```jsx
<EmbedDirectTemplate token={token} darkModeDisabled={true} />
```
These customization options are available for both Direct Templates and Signing Token embeds.
## Supported Frameworks
We support embedding across a range of popular JavaScript frameworks, including:
| Framework | Package |
| --------- | -------------------------------------------------------------------------------- |
| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) |
| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) |
| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) |
| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) |
| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) |
| Framework | Package |
| --------- | ---------------------------------------------------------------------------------- |
| React | [@documenso/embed-react](https://www.npmjs.com/package/@documenso/embed-react) |
| Preact | [@documenso/embed-preact](https://www.npmjs.com/package/@documenso/embed-preact) |
| Vue | [@documenso/embed-vue](https://www.npmjs.com/package/@documenso/embed-vue) |
| Svelte | [@documenso/embed-svelte](https://www.npmjs.com/package/@documenso/embed-svelte) |
| Solid | [@documenso/embed-solid](https://www.npmjs.com/package/@documenso/embed-solid) |
| Angular | [@documenso/embed-angular](https://www.npmjs.com/package/@documenso/embed-angular) |
Additionally, we provide **web components** for more generalized use. However, please note that web components are still in their early stages and haven't been extensively tested.
@ -80,7 +128,7 @@ This will show a dialog which will ask you to configure which recipient should b
## Embedding with Signing Tokens
To embed the signing process for an ordinary document, youll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely.
To embed the signing process for an ordinary document, you'll need a **document signing token** for the recipient. This token provides the necessary access to load the document and facilitate the signing process securely.
#### Instructions
@ -117,15 +165,30 @@ Once you've obtained the appropriate tokens, you can integrate the signing exper
- [Vue](/developers/embedding/vue)
- [Svelte](/developers/embedding/svelte)
- [Solid](/developers/embedding/solid)
- [Angular](/developers/embedding/angular)
If you're using **web components**, the integration process is slightly different. Keep in mind that web components are currently less tested but can still provide flexibility for general use cases.
## Stay Tuned for the Platform Plan
## Embedded Authoring
While embedding is already a powerful tool, we're working on a **Platform Plan** that will introduce even more functionality. This plan will offer:
In addition to embedding signing experiences, Documenso now supports **embedded authoring**, allowing your users to create documents and templates directly within your application.
- Additional customization options
- The ability to remove Documenso branding
- Additional controls for the signing experience
With embedded authoring, you can:
More details will be shared as we approach the release.
- Create new documents with custom fields
- Configure document properties and settings
- Set up recipients and signing workflows
- Customize the authoring experience
For detailed implementation instructions and code examples, see our [Embedded Authoring](/developers/embedding/authoring) guide.
## Related
- [React Integration](/developers/embedding/react)
- [Vue Integration](/developers/embedding/vue)
- [Svelte Integration](/developers/embedding/svelte)
- [Solid Integration](/developers/embedding/solid)
- [Preact Integration](/developers/embedding/preact)
- [Angular Integration](/developers/embedding/angular)
- [CSS Variables](/developers/embedding/css-variables)
- [Embedded Authoring](/developers/embedding/authoring)

View File

@ -44,6 +44,9 @@ const MyEmbeddingComponent = () => {
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -75,3 +78,30 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-preact';
const MyEmbeddingComponent = () => {
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
return (
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
);
};
```

View File

@ -44,6 +44,9 @@ const MyEmbeddingComponent = () => {
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -75,3 +78,34 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-react';
const MyEmbeddingComponent = () => {
return (
<EmbedDirectTemplate
token="your-token"
// Custom CSS
css={`
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
`}
// CSS Variables
cssVars={{
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
}}
// Dark Mode Control
darkModeDisabled={true}
/>
);
};
```

View File

@ -44,6 +44,9 @@ const MyEmbeddingComponent = () => {
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -75,3 +78,30 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```jsx
import { EmbedDirectTemplate } from '@documenso/embed-solid';
const MyEmbeddingComponent = () => {
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
return (
<EmbedDirectTemplate token={token} css={customCss} cssVars={cssVars} darkModeDisabled={true} />
);
};
```

View File

@ -46,6 +46,9 @@ If you have a direct link template, you can simply provide the token for the tem
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -77,3 +80,28 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```html
<script lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-svelte';
const token = 'your-token';
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
</script>
<EmbedDirectTemplate {token} css="{customCss}" cssVars="{cssVars}" darkModeDisabled="{true}" />
```

View File

@ -46,6 +46,9 @@ If you have a direct link template, you can simply provide the token for the tem
| email | string (optional) | The email the signer that will be used by default for signing |
| lockEmail | boolean (optional) | Whether or not the email field should be locked disallowing modifications |
| externalId | string (optional) | The external ID to be used for the document that will be created upon completion |
| css | string (optional) | Custom CSS to style the embedded component (Platform Plan only) |
| cssVars | object (optional) | CSS variables for customizing colors, spacing, etc. (Platform Plan only) |
| darkModeDisabled | boolean (optional) | Disable dark mode functionality (Platform Plan only) |
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
@ -77,3 +80,35 @@ const MyEmbeddingComponent = () => {
| onDocumentReady | function (optional) | A callback function that will be called when the document is loaded and ready to be signed |
| onDocumentCompleted | function (optional) | A callback function that will be called when the document has been completed |
| onDocumentError | function (optional) | A callback function that will be called when an error occurs with the document |
### Styling and Theming (Platform Plan)
Platform customers have access to advanced styling options:
```html
<script setup lang="ts">
import { EmbedDirectTemplate } from '@documenso/embed-vue';
const token = ref('your-token');
const customCss = `
.documenso-embed {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
`;
const cssVars = {
primary: '#0000FF',
background: '#F5F5F5',
radius: '8px',
};
</script>
<template>
<EmbedDirectTemplate
:token="token"
:css="customCss"
:cssVars="cssVars"
:darkModeDisabled="true"
/>
</template>
```

View File

@ -16,18 +16,16 @@ Pick the one that fits your needs the best.
## Tech Stack
- [Typescript](https://www.typescriptlang.org/) - Language
- [Next.js](https://nextjs.org/) - Framework
- [React Router](https://reactrouter.com/) - Framework
- [Prisma](https://www.prisma.io/) - ORM
- [Tailwind](https://tailwindcss.com/) - CSS
- [shadcn/ui](https://ui.shadcn.com/) - Component Library
- [NextAuth.js](https://next-auth.js.org/) - Authentication
- [react-email](https://react.email/) - Email Templates
- [tRPC](https://trpc.io/) - API
- [@documenso/pdf-sign](https://www.npmjs.com/package/@documenso/pdf-sign) - PDF Signatures
- [React-PDF](https://github.com/wojtekmaj/react-pdf) - Viewing PDFs
- [PDF-Lib](https://github.com/Hopding/pdf-lib) - PDF manipulation
- [Stripe](https://stripe.com/) - Payments
- [Vercel](https://vercel.com) - Hosting
<div className="mt-16 flex items-center justify-center gap-4">
<a href="https://documen.so/discord">

View File

@ -32,10 +32,8 @@ Run `npm i` in the root directory to install the dependencies required for the p
Set up the following environment variables in the `.env` file:
```bash
NEXTAUTH_URL
NEXTAUTH_SECRET
NEXT_PUBLIC_WEBAPP_URL
NEXT_PUBLIC_MARKETING_URL
NEXT_PRIVATE_DATABASE_URL
NEXT_PRIVATE_DIRECT_DATABASE_URL
NEXT_PRIVATE_SMTP_FROM_NAME

View File

@ -13,35 +13,13 @@ Documenso uses the following stack to handle translations:
Additional reading can be found in the [Lingui documentation](https://lingui.dev/introduction).
## Requirements
You **must** insert **`setupI18nSSR()`** when creating any of the following files:
- Server layout.tsx
- Server page.tsx
- Server loading.tsx
Server meaning it does not have `'use client'` in it.
```tsx
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
export default function SomePage() {
setupI18nSSR(); // Required if there are translations within the page, or nested in components.
// Rest of code...
}
```
Additional information can be found [here.](https://lingui.dev/tutorials/react-rsc#pages-layouts-and-lingui)
## Quick guide
If you require more in-depth information, please see the [Lingui documentation](https://lingui.dev/introduction).
### HTML
Wrap all text to translate in **`<Trans></Trans>`** tags exported from **@lingui/macro** (not @lingui/react).
Wrap all text to translate in **`<Trans></Trans>`** tags exported from **@lingui/react/macro**.
```html
<h1>
@ -64,8 +42,9 @@ For text that is broken into elements, but represent a whole sentence, you must
### Constants outside of react components
```tsx
import { Trans, msg } from '@lingui/macro';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react';
import { Trans } from '@lingui/react/macro';
// Wrap text in msg`text to translate` when it's in a constant here, or another file/package.
export const CONSTANT_WITH_MSG = {
@ -98,31 +77,13 @@ Lingui provides a Plural component to make it easy. See full documentation [here
Lingui provides a [DateTime instance](https://lingui.dev/ref/core#i18n.date) with the configured locale.
#### Server components
Note that the i18n instance is coming from **setupI18nSSR**.
```tsx
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
export const SomeComponent = () => {
const { i18n } = setupI18nSSR();
const { i18n } = useLingui();
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
};
```
#### Client components
Note that the i18n instance is coming from the **import**.
```tsx
import { i18n } from '@lingui/core';
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
export const SomeComponent = () => {
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
};
```

View File

@ -3,6 +3,8 @@ title: Public API
description: Learn how to interact with your documents programmatically using the Documenso public API.
---
import { Callout, Steps } from 'nextra/components';
# Public API
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:
@ -13,10 +15,35 @@ Documenso provides a public REST API enabling you to interact with your document
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.
## Swagger Documentation
## API V1 - Stable
The [Swagger documentation](https://app.documenso.com/api/v1/openapi) also provides information about the API endpoints, request parameters, response formats, and authentication methods.
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.
Our new API V2 supports the following typed SDKs:
- [TypeScript](https://github.com/documenso/sdk-typescript)
- [Python](https://github.com/documenso/sdk-python)
- [Go](https://github.com/documenso/sdk-go)
<Callout type="info">
For the staging API, please use the following base URL:
`https://stg-app.documenso.dev/api/v2-beta/`
</Callout>
🚀 [V2 Announcement](https://documen.so/sdk-blog)
📖 [Documentation](https://documen.so/api-v2-docs)
💬 [Leave Feedback](https://documen.so/sdk-feedback)
🔔 [Breaking Changes](https://documen.so/sdk-breaking)
## Availability
The API is available to individual users and teams.
The API is available to individual users, teams and higher plans. [Fair Use](https://documen.so/fair) applies.

View File

@ -500,8 +500,125 @@ Now you can make a `POST` request to the `/api/v1/documents/{documentId}/fields`
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": [
{
"id": 21,
"type": "text",
"label": "my-label",
"placeholder": "my-placeholder",
"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"]
}
]
}
```
Check out the endpoint in the [API V1 documentation](https://app.documenso.com/api/v1/openapi#:~:text=/%7BtemplateId%7D/-,generate,-%2Ddocument).
### API V2
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:
```json
{
"templateId": 111,
"recipients": [
{
"id": 3,
"name": "Example User",
"email": "example@documenso.com",
"signingOrder": 1,
"role": "SIGNER"
}
],
"prefillFields": [
{
"id": 21,
"type": "text",
"label": "my-label",
"placeholder": "my-placeholder",
"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"]
}
]
}
```
Check out the endpoint in the [API V2 documentation](https://openapi.documenso.com/reference#tag/template/POST/template/use).

View File

@ -5,7 +5,7 @@ description: Learn how to self-host Documenso on your server or cloud infrastruc
import { Callout, Steps } from 'nextra/components';
import { CallToAction } from '@documenso/ui/components/call-to-action';
import { CallToAction } from '../../../components/call-to-action';
# Self Hosting
@ -35,10 +35,8 @@ cp .env.example .env
Open the `.env` file and fill in the following variables:
```bash
- NEXTAUTH_URL
- NEXTAUTH_SECRET
- NEXT_PUBLIC_WEBAPP_URL
- NEXT_PUBLIC_MARKETING_URL
- NEXT_PRIVATE_DATABASE_URL
- NEXT_PRIVATE_DIRECT_DATABASE_URL
- NEXT_PRIVATE_SMTP_FROM_NAME
@ -46,8 +44,8 @@ Open the `.env` file and fill in the following variables:
```
<Callout type="info">
If you use a reverse proxy in front of Documenso, don't forget to provide the public URL for both
the `NEXTAUTH_URL` and `NEXT_PUBLIC_WEBAPP_URL` variables!
If you use a reverse proxy in front of Documenso, don't forget to provide the public URL for the
`NEXT_PUBLIC_WEBAPP_URL` variable!
</Callout>
### Install the Dependencies
@ -171,7 +169,6 @@ Run the Docker container with the required environment variables:
```bash
docker run -d \
-p 3000:3000 \
-e NEXTAUTH_URL="<your-nextauth-url>"
-e NEXTAUTH_SECRET="<your-nextauth-secret>"
-e NEXT_PRIVATE_ENCRYPTION_KEY="<your-next-private-encryption-key>"
-e NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY="<your-next-private-encryption-secondary-key>"
@ -200,7 +197,6 @@ The environment variables listed above are a subset of those available for confi
| Variable | Description |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `PORT` | The port on which the Documenso application runs. It defaults to `3000`. |
| `NEXTAUTH_URL` | The URL for the NextAuth.js authentication service. |
| `NEXTAUTH_SECRET` | The secret key used by NextAuth.js for encryption and signing. |
| `NEXT_PRIVATE_ENCRYPTION_KEY` | The primary encryption key for symmetric encryption and decryption (at least 32 characters). |
| `NEXT_PRIVATE_ENCRYPTION_SECONDARY_KEY` | The secondary encryption key for symmetric encryption and decryption (at least 32 characters). |

View File

@ -3,7 +3,7 @@ title: Getting Started with Self-Hosting
description: A step-by-step guide to setting up and hosting your own Documenso instance.
---
import { CallToAction } from '@documenso/ui/components/call-to-action';
import { CallToAction } from '../../../components/call-to-action';
# Getting Started with Self-Hosting

View File

@ -20,6 +20,8 @@ Documenso supports Webhooks and allows you to subscribe to the following events:
- `document.opened`
- `document.signed`
- `document.completed`
- `document.rejected`
- `document.cancelled`
## Create a webhook subscription
@ -36,7 +38,7 @@ Clicking on the "**Create Webhook**" button opens a modal to create a new webhoo
To create a new webhook subscription, you need to provide the following information:
- Enter the webhook URL that will receive the event payload.
- Select the event(s) you want to subscribe to: `document.created`, `document.sent`, `document.opened`, `document.signed`, `document.completed`.
- Select the event(s) you want to subscribe to: `document.created`, `document.sent`, `document.opened`, `document.signed`, `document.completed`, `document.rejected`, `document.cancelled`.
- Optionally, you can provide a secret key that will be used to sign the payload. This key will be included in the `X-Documenso-Secret` header of the request.
![A screenshot of the Create Webhook modal that shows the URL input field and the event checkboxes](/webhook-images/webhooks-page-create-webhook-modal.webp)
@ -53,45 +55,55 @@ You can edit or delete your webhook subscriptions by clicking the "**Edit**" or
The payload sent to the webhook URL contains the following fields:
| Field | Type | Description |
| -------------------------------------------- | --------- | ---------------------------------------------------- |
| `event` | string | The type of event that triggered the webhook. |
| `payload.id` | number | The id of the document. |
| `payload.userId` | number | The id of the user who owns the document. |
| `payload.authOptions` | json? | Authentication options for the document. |
| `payload.formValues` | json? | Form values for the document. |
| `payload.title` | string | The name of the document. |
| `payload.status` | string | The current status of the document. |
| `payload.documentDataId` | string | The identifier for the document data. |
| `payload.createdAt` | datetime | The creation date and time of the document. |
| `payload.updatedAt` | datetime | The last update date and time of the document. |
| `payload.completedAt` | datetime? | The completion date and time of the document. |
| `payload.deletedAt` | datetime? | The deletion date and time of the document. |
| `payload.teamId` | number? | The id of the team. |
| `payload.documentData.id` | string | The id of the document data. |
| `payload.documentData.type` | string | The type of the document data. |
| `payload.documentData.data` | string | The data of the document. |
| `payload.documentData.initialData` | string | The initial data of the document. |
| `payload.Recipient[].id` | number | The id of the recipient. |
| `payload.Recipient[].documentId` | number? | The id the document associated with the recipient. |
| `payload.Recipient[].templateId` | number? | The template identifier for the recipient. |
| `payload.Recipient[].email` | string | The email address of the recipient. |
| `payload.Recipient[].name` | string | The name of the recipient. |
| `payload.Recipient[].token` | string | The token associated with the recipient. |
| `payload.Recipient[].expired` | datetime? | The expiration status of the recipient. |
| `payload.Recipient[].signedAt` | datetime? | The date and time the recipient signed the document. |
| `payload.Recipient[].authOptions.accessAuth` | json? | Access authentication options. |
| `payload.Recipient[].authOptions.actionAuth` | json? | Action authentication options. |
| `payload.Recipient[].role` | string | The role of the recipient. |
| `payload.Recipient[].readStatus` | string | The read status of the document by the recipient. |
| `payload.Recipient[].signingStatus` | string | The signing status of the recipient. |
| `payload.Recipient[].sendStatus` | string | The send status of the document to the recipient. |
| `createdAt` | datetime | The creation date and time of the webhook event. |
| `webhookEndpoint` | string | The endpoint URL where the webhook is sent. |
## Webhook event payload example
When an event that you have subscribed to occurs, Documenso will send a POST request to the specified webhook URL with a payload containing information about the event.
| Field | Type | Description |
| -------------------------------------------- | --------- | ----------------------------------------------------- |
| `event` | string | The type of event that triggered the webhook. |
| `payload.id` | number | The id of the document. |
| `payload.externalId` | string? | External identifier for the document. |
| `payload.userId` | number | The id of the user who owns the document. |
| `payload.authOptions` | json? | Authentication options for the document. |
| `payload.formValues` | json? | Form values for the document. |
| `payload.visibility` | string | Document visibility (e.g., EVERYONE). |
| `payload.title` | string | The title of the document. |
| `payload.status` | string | The current status of the document. |
| `payload.documentDataId` | string | The identifier for the document data. |
| `payload.createdAt` | datetime | The creation date and time of the document. |
| `payload.updatedAt` | datetime | The last update date and time of the document. |
| `payload.completedAt` | datetime? | The completion date and time of the document. |
| `payload.deletedAt` | datetime? | The deletion date and time of the document. |
| `payload.teamId` | number? | The id of the team if document belongs to a team. |
| `payload.templateId` | number? | The id of the template if created from template. |
| `payload.source` | string | The source of the document (e.g., DOCUMENT, TEMPLATE) |
| `payload.documentMeta.id` | string | The id of the document metadata. |
| `payload.documentMeta.subject` | string? | The subject of the document. |
| `payload.documentMeta.message` | string? | The message associated with the document. |
| `payload.documentMeta.timezone` | string | The timezone setting for the document. |
| `payload.documentMeta.password` | string? | The password protection if set. |
| `payload.documentMeta.dateFormat` | string | The date format used in the document. |
| `payload.documentMeta.redirectUrl` | string? | The URL to redirect after signing. |
| `payload.documentMeta.signingOrder` | string | The signing order (e.g., PARALLEL, SEQUENTIAL). |
| `payload.documentMeta.typedSignatureEnabled` | boolean | Whether typed signatures are enabled. |
| `payload.documentMeta.language` | string | The language of the document. |
| `payload.documentMeta.distributionMethod` | string | The method of distributing the document. |
| `payload.documentMeta.emailSettings` | json? | Email notification settings. |
| `payload.Recipient[].id` | number | The id of the recipient. |
| `payload.Recipient[].documentId` | number? | The id of the document for this recipient. |
| `payload.Recipient[].templateId` | number? | The template id if from a template. |
| `payload.Recipient[].email` | string | The email address of the recipient. |
| `payload.Recipient[].name` | string | The name of the recipient. |
| `payload.Recipient[].token` | string | The unique token for this recipient. |
| `payload.Recipient[].documentDeletedAt` | datetime? | When the document was deleted for this recipient. |
| `payload.Recipient[].expired` | datetime? | When the recipient's access expired. |
| `payload.Recipient[].signedAt` | datetime? | When the recipient signed the document. |
| `payload.Recipient[].authOptions` | json? | Authentication options for this recipient. |
| `payload.Recipient[].signingOrder` | number? | The order in which this recipient should sign. |
| `payload.Recipient[].rejectionReason` | string? | The reason if the recipient rejected the document. |
| `payload.Recipient[].role` | string | The role of the recipient (e.g., SIGNER, VIEWER). |
| `payload.Recipient[].readStatus` | string | Whether the recipient has read the document. |
| `payload.Recipient[].signingStatus` | string | The signing status of this recipient. |
| `payload.Recipient[].sendStatus` | string | The sending status for this recipient. |
| `createdAt` | datetime | The creation date and time of the webhook event. |
| `webhookEndpoint` | string | The endpoint URL where the webhook is sent. |
## Example payloads
@ -104,9 +116,11 @@ Example payload for the `document.created` event:
"event": "DOCUMENT_CREATED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "DRAFT",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -114,7 +128,43 @@ Example payload for the `document.created` event:
"updatedAt": "2024-04-22T11:44:43.341Z",
"completedAt": null,
"deletedAt": null,
"teamId": null
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
"documentId": 10,
"templateId": null,
"email": "signer@documenso.com",
"name": "John Doe",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": null,
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "NOT_SENT"
}
]
},
"createdAt": "2024-04-22T11:44:44.779Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
@ -128,9 +178,11 @@ Example payload for the `document.sent` event:
"event": "DOCUMENT_SENT",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -139,6 +191,22 @@ Example payload for the `document.sent` event:
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
@ -147,12 +215,12 @@ Example payload for the `document.sent` event:
"email": "signer2@documenso.com",
"name": "Signer 2",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"authOptions": null,
"signingOrder": 1,
"rejectionReason": null,
"role": "VIEWER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
@ -165,12 +233,12 @@ Example payload for the `document.sent` event:
"email": "signer1@documenso.com",
"name": "Signer 1",
"token": "HkrptwS42ZBXdRKj1TyUo",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"authOptions": null,
"signingOrder": 2,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
@ -190,9 +258,11 @@ Example payload for the `document.opened` event:
"event": "DOCUMENT_OPENED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -201,6 +271,22 @@ Example payload for the `document.opened` event:
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
@ -209,24 +295,18 @@ Example payload for the `document.opened` event:
"email": "signer2@documenso.com",
"name": "Signer 2",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"authOptions": null,
"signingOrder": 1,
"rejectionReason": null,
"role": "VIEWER",
"readStatus": "OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT"
}
],
"documentData": {
"id": "hs8qz1ktr9204jn7mg6c5dxy0",
"type": "S3_PATH",
"data": "9753/xzqrshtlpokm/documenso.pdf",
"initialData": "9753/xzqrshtlpokm/documenso.pdf"
}
]
},
"createdAt": "2024-04-22T11:50:26.174Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
@ -240,9 +320,11 @@ Example payload for the `document.signed` event:
"event": "DOCUMENT_SIGNED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "COMPLETED",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -251,6 +333,22 @@ Example payload for the `document.signed` event:
"completedAt": "2024-04-22T11:52:05.707Z",
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 51,
@ -259,12 +357,15 @@ Example payload for the `document.signed` event:
"email": "signer1@documenso.com",
"name": "Signer 1",
"token": "HkrptwS42ZBXdRKj1TyUo",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:52:05.688Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "OPENED",
"signingStatus": "SIGNED",
@ -284,9 +385,11 @@ Example payload for the `document.completed` event:
"event": "DOCUMENT_COMPLETED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "COMPLETED",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
@ -295,11 +398,21 @@ Example payload for the `document.completed` event:
"completedAt": "2024-04-22T11:52:05.707Z",
"deletedAt": null,
"teamId": null,
"documentData": {
"id": "hs8qz1ktr9204jn7mg6c5dxy0",
"type": "S3_PATH",
"data": "bk9p1h7x0s3m/documenso-signed.pdf",
"initialData": "9753/xzqrshtlpokm/documenso.pdf"
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
@ -309,12 +422,15 @@ Example payload for the `document.completed` event:
"email": "signer2@documenso.com",
"name": "Signer 2",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:51:10.055Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 1,
"rejectionReason": null,
"role": "VIEWER",
"readStatus": "OPENED",
"signingStatus": "SIGNED",
@ -327,12 +443,15 @@ Example payload for the `document.completed` event:
"email": "signer1@documenso.com",
"name": "Signer 1",
"token": "HkrptwS42ZBXdRKj1TyUo",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:52:05.688Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 2,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "OPENED",
"signingStatus": "SIGNED",
@ -345,6 +464,161 @@ Example payload for the `document.completed` event:
}
```
Example payload for the `document.rejected` event:
```json
{
"event": "DOCUMENT_REJECTED",
"payload": {
"id": 10,
"externalId": null,
"userId": 1,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "hs8qz1ktr9204jn7mg6c5dxy0",
"createdAt": "2024-04-22T11:44:43.341Z",
"updatedAt": "2024-04-22T11:48:07.569Z",
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "doc_meta_123",
"subject": "Please sign this document",
"message": "Hello, please review and sign this document.",
"timezone": "UTC",
"password": null,
"dateFormat": "MM/DD/YYYY",
"redirectUrl": null,
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": null
},
"Recipient": [
{
"id": 52,
"documentId": 10,
"templateId": null,
"email": "signer@documenso.com",
"name": "Signer",
"token": "vbT8hi3jKQmrFP_LN1WcS",
"documentDeletedAt": null,
"expired": null,
"signedAt": "2024-04-22T11:48:07.569Z",
"authOptions": {
"accessAuth": null,
"actionAuth": null
},
"signingOrder": 1,
"rejectionReason": "I do not agree with the terms",
"role": "SIGNER",
"readStatus": "OPENED",
"signingStatus": "REJECTED",
"sendStatus": "SENT"
}
]
},
"createdAt": "2024-04-22T11:48:07.945Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
}
```
Example payload for the `document.rejected` event:
```json
{
"event": "DOCUMENT_CANCELLED",
"payload": {
"id": 7,
"externalId": null,
"userId": 3,
"authOptions": null,
"formValues": null,
"visibility": "EVERYONE",
"title": "documenso.pdf",
"status": "PENDING",
"documentDataId": "cm6exvn93006hi02ru90a265a",
"createdAt": "2025-01-27T11:02:14.393Z",
"updatedAt": "2025-01-27T11:03:16.387Z",
"completedAt": null,
"deletedAt": null,
"teamId": null,
"templateId": null,
"source": "DOCUMENT",
"documentMeta": {
"id": "cm6exvn96006ji02rqvzjvwoy",
"subject": "",
"message": "",
"timezone": "Etc/UTC",
"password": null,
"dateFormat": "yyyy-MM-dd hh:mm a",
"redirectUrl": "",
"signingOrder": "PARALLEL",
"typedSignatureEnabled": true,
"language": "en",
"distributionMethod": "EMAIL",
"emailSettings": {
"documentDeleted": true,
"documentPending": true,
"recipientSigned": true,
"recipientRemoved": true,
"documentCompleted": true,
"ownerDocumentCompleted": true,
"recipientSigningRequest": true
}
},
"recipients": [
{
"id": 7,
"documentId": 7,
"templateId": null,
"email": "mybirihix@mailinator.com",
"name": "Zorita Baird",
"token": "XkKx1HCs6Znm2UBJA2j6o",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": { "accessAuth": null, "actionAuth": null },
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT"
}
],
"Recipient": [
{
"id": 7,
"documentId": 7,
"templateId": null,
"email": "signer@documenso.com",
"name": "Signer",
"token": "XkKx1HCs6Znm2UBJA2j6o",
"documentDeletedAt": null,
"expired": null,
"signedAt": null,
"authOptions": { "accessAuth": null, "actionAuth": null },
"signingOrder": 1,
"rejectionReason": null,
"role": "SIGNER",
"readStatus": "NOT_OPENED",
"signingStatus": "NOT_SIGNED",
"sendStatus": "SENT"
}
]
},
"createdAt": "2025-01-27T11:03:27.730Z",
"webhookEndpoint": "https://mywebhooksite.com/mywebhook"
}
```
## Availability
Webhooks are available to individual users and teams.

View File

@ -6,12 +6,12 @@
"title": "How To Use"
},
"get-started": "Get Started",
"profile": "User Profile",
"signing-documents": "Signing Documents",
"profile": "Public Profile",
"organisations": "Organisations",
"documents": "Documents",
"templates": "Templates",
"branding": "Branding",
"direct-links": "Direct Signing Links",
"document-visibility": "Document Visibility",
"teams": "Teams",
"-- Legal Overview": {
"type": "separator",
"title": "Legal Overview"
@ -19,4 +19,4 @@
"fair-use": "Fair Use Policy",
"licenses": "Licenses",
"compliance": "Compliance"
}
}

View File

@ -0,0 +1,28 @@
---
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 **Preferences** tab. This page contains both the preferences for documents and branding, the branding section is located at the bottom of the page.
![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

@ -0,0 +1,5 @@
{
"sending-documents": "Sending Documents",
"document-preferences": "Document Preferences",
"document-visibility": "Document Visibility"
}

View File

@ -0,0 +1,42 @@
---
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 **Preferences** tab.
![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.
- **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

@ -0,0 +1,53 @@
---
title: Document Visibility
description: Learn how to control the visibility of your team documents.
---
import { Callout } from 'nextra/components';
# Document Visibility
The default document visibility option allows you to control who can view and access the documents uploaded within a team.
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.
- **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.
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.
![Document visibility preference](/organisations/organisation-document-visibility.webp)
## 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_".
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Admin_" or "_Managers and above_" in this case).
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Everyone_" or "_Managers and above_", the document's visibility is set to the default document visibility ("_Everyone_" or "_Managers and above_" in this case).
- The user can change the visibility of the document to any of these options, except "_Admin_", in the document editor.
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Admin_".
- The user can't change the visibility of the document in the document editor.
- If a user with the "_Admin_" role creates a document, and the default document visibility is set to "_Everyone_", "_Managers and above_", or "_Admin_", the document's visibility is set to the default document visibility.
- The user can change the visibility of the document to any of these options in the document editor.
You can change the visibility of a document at any time by editing the document and selecting a different visibility option.
![A screenshot of the Documenso's document editor page where you can update the document visibility](/teams/document-visibility-settings.webp)
<Callout type="warning">
Updating the default document visibility in the team's general preferences will not affect the
visibility of existing documents. You will need to update the visibility of each document
individually.
</Callout>
## A Note on Document Access
The `document owner` (the user who created the document) always has access to the document, regardless of the document's visibility settings. This means that even if a document is set to "Admins only", the document owner can still view and edit the document.
The `recipient` (the user who receives the document for signature, approval, etc.) also has access to the document, regardless of the document's visibility settings. This means that even if a document is set to "Admins only", the recipient can still view and sign the document.

View File

@ -85,12 +85,13 @@ You can also set the recipient's role, which determines their actions and permis
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 |
| BCC | Receives a copy of the signed document after completion. No action is required. | No | No |
| 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
@ -114,7 +115,7 @@ 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).
page](/users/documents/fields).
</Callout>
#### Signature Required

View File

@ -10,7 +10,7 @@ import { Callout, Steps } from 'nextra/components';
<Steps>
### 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, and Teams.
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.
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
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).
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).
</Steps>

View File

@ -1,99 +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 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

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

View File

@ -0,0 +1,19 @@
---
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

@ -0,0 +1,75 @@
---
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

@ -0,0 +1,65 @@
---
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

@ -0,0 +1,65 @@
---
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

@ -0,0 +1,121 @@
---
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: User Profile
title: Public Profile
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
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.
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.
![The profile settings page](/public-profile/documenso-public-profile-settings.webp)
@ -45,6 +45,8 @@ 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.
![An example of a enabling a public profile on Documenso](/public-profile/documenso-enable-public-profile-settings.webp)
### (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.

View File

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

View File

@ -1,5 +0,0 @@
{
"general-settings": "General Settings",
"document-visibility": "Document Visibility",
"sender-details": "Email Sender Details"
}

View File

@ -1,45 +0,0 @@
---
title: Document Visibility
description: Learn how to control the visibility of your team documents.
---
import { Callout } from 'nextra/components';
# Team's Document Visibility
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:
- **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_.
- **Admin only** - The document is only visible to the team's admins.
![A screenshot of the document visibility selector from the team's general settings page](/teams/team-general-settings-document-visibility-select.webp)
The default document visibility is set to "_EVERYONE_" by default. You can change this setting by going to the [team's general settings page](/users/teams/general-settings) and selecting a different visibility option.
<Callout type="warning">
If the team member uploading the document has a role lower than the default document visibility,
the document visibility will be set to a lower visibility level matching the team member's role.
</Callout>
Here's how it works:
- If a user with the "_Member_" role creates a document and the default document visibility is set to "_Admin_" or "_Managers and above_", the document's visibility is set to "_Everyone_".
- If a user with the "_Manager_" role creates a document and the default document visibility is set to "_Admin_", the document's visibility is set to "_Managers and above_".
- Otherwise, the document's visibility is set to the default document visibility.
You can change the visibility of a document at any time by editing the document and selecting a different visibility option.
![A screenshot of the Documenso's document editor page where you can update the document visibility](/teams/document-visibility-settings.webp)
<Callout type="warning">
Updating the default document visibility in the team's general settings will not affect the
visibility of existing documents. You will need to update the visibility of each document
individually.
</Callout>
## A Note on Document Access
The `document owner` (the user who created the document) always has access to the document, regardless of the document's visibility settings. This means that even if a document is set to "Admins only", the document owner can still view and edit the document.
The `recipient` (the user who receives the document for signature, approval, etc.) also has access to the document, regardless of the document's visibility settings. This means that even if a document is set to "Admins only", the recipient can still view and sign the document.

View File

@ -1,15 +0,0 @@
---
title: General Settings
description: Learn how to manage your team's General settings.
---
# General Settings
You can manage your team's general settings by clicking on the **General Settings** tab in the team's settings dashboard.
![A screenshot of team's General settings page](/teams/team-general-settings.webp)
The general settings 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).
- **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).

View File

@ -1,14 +0,0 @@
---
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

@ -1,5 +1,3 @@
'use client';
import React from 'react';
import NextPlausibleProvider from 'next-plausible';

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

View File

@ -19,6 +19,22 @@ const themeConfig: DocsThemeConfig = {
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<script
dangerouslySetInnerHTML={{
__html: `
!function(){
if (location.hostname === 'localhost') return;
var e="6c236490c9a68c1",
t=function(){Reo.init({ clientID: e })},
n=document.createElement("script");
n.src="https://static.reo.dev/"+e+"/reo.js";
n.defer=true;
n.onload=t;
document.head.appendChild(n);
}();
`,
}}
/>
</>
);
},

View File

@ -1 +0,0 @@
# @documenso/marketing

View File

@ -1 +0,0 @@
declare module '@documenso/tailwind-config';

View File

@ -1,63 +0,0 @@
---
title: Launching Direct Links
description: Today, we are launching direct links to templates, a new and async way to get documents signed.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-06-17
tags:
- Announcement
- Direct Links
- Profiles
---
<figure>
<MdxNextImage
src="/blog/direct-links.png"
width="1400"
height="884"
alt="Direct Links in Templats List View"
/>
<figcaption className="text-center">Direct Template Links - Async signing, anytime.</figcaption>
</figure>
> TLDR; We are launching direct links to templates. With direct links, a document is created from a template every time anyone signs the link. Links can be public.
## Sync or Async?
> Quick refresher on Sync vs. Async: Sync means everyone has to wait for me until they can continue their work. Async means everyone can and does their work at the time that fits best.
Digital signing has become almost as normalized as email when doing business. While not 100% of companies are onboarded on digital signatures yet, hardly anyone is surprised when receiving a link to sign something digitally. As we got used to the user experience of sending emails, we also got used to the experience of sending document signature requests, with all the downsides:
- I have to become active each time before anything can happen: I need to send a signature request
- My counterpart has to wait for me to send: "Did you send the signing link yet?"
- I need to monitor the requests I started for completion: "I sent you a link yesterday; please check it out."
## Introducing Direct Links
Today, we are introducing a new paradigm to signing: Async Direct Signing Links. Direct links are attached to a template and can be used anytime by anyone using the link. You set up the signature experience and flow once using all existing template mechanisms and you are done. You can provide anyone with the link so they can sign whenever they need to. You can even post the link publicly if you want to maximize its reach, i.e. for sales contracts.
<video
id="vid"
width="100%"
src="https://github.com/documenso/design/assets/1309312/129f690b-29b4-4a11-b9a0-14fc6648e611"
autoPlay
loop
muted
></video>
## Embrace Async
So, how does this help anyone? You may still need to send a signature request to people, but in the cases you don't, you are not forced to anymore. Need an NDA? Check out our standing NDA link. A customer needs an updated Form W-9? Just use the company W-9 Link; it always has the most up-to-date form. You can even go as far as publicly posting a link to a software development or design contract any potential customer can sign anytime. Can they talk to you first? Sure, but if they don't need to or already have to, they go straight to the link. The process of actively sending has gotten us used to using a sync paradigm (I send, you receive and sign, and I get the result), whereas an async one (you sign whenever it suits you, and I become active only then, if at all) is way better suited. Adding more approval and signature steps makes sure you still control the outcome, but the process becomes a lot more efficient. For example, you can grab your own copy of the early adopter's pledge here if you missed it: [documen.so/pledge](https://documen.so/pledge).
> Take a minute to think about every signing request you send and whether they really require you to be part of the transaction. Could they be outsourced to the recipient and only reviewed once their part is done?
## Coming Soon: Profiles
The best place to put your public links will be your **Documenso profile**, which is also close to launching. We want to get a feel for how links are used and move on to profiles shortly after. Want to try out direct links? Grab a free account here to get started: [documen.so/free](https://documen.so/free).
As always, we want to hear from you on [Twitter / X](https://twitter.com/eltimuro) (DMs are open) or [Discord](https://documen.so/discord) if you have any questions, ideas, or comments.
Best from Hamburg\
Timur

View File

@ -1,51 +0,0 @@
---
title: Announcing Documenso
description: Launching an open-source document signing tool because trusted-based products should be built on openness. The first release will be in 2023. Sign up at documenso.com to be on board.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2022-12-29
tags:
- Announcement
---
<figure>
<MdxNextImage
src="/blog/blog-banner-announcing-documenso.webp"
width="1400"
height="884"
alt="Documenso announcement blog banner"
/>
<figcaption className="text-center">Documenso — The Open Source DocuSign Alternative.</figcaption>
</figure>
## TL; DR;
I'm launching an open source document signing tool because trust-based products should be built on openness. The first release will be in 2023. Sign up at <a href="https://documenso.com" target="_blank">documenso.com</a> and get on board.
## Lets build the worlds most trusted document-signing tool.
Today I'm excited to announce my new project Documenso. Documenso is an open source document signing tool you can host yourself and freely build upon because it's, you know, open source. Before I get more into the details of what and when will be launched I want to take a moment and talk about why.
## Digital signing is great
Signing Documents digitally has countless benefits: Less struggle with printing, less wasting paper, faster request delivery, easier changes, easier coordination of people far away, verifiable document integrity, and verifiable signer identity (this is a vast topic, will write more on soon), easier storage and search of signed documents, the list goes on. Digital Signatures take something very old and very trusted like personally signing documents into the digital space, adding the benefits listed above. It also introduces a new party to every signing transaction, the signing tool providers. What was peer to peer transaction before, now goes through an intermediary. While this isn't a problem in itself, it should make us think about how we want these providers of trust to work.
## How do we build trusted systems?
While doing research for Documenso I came upon a quote that expresses the current state of document signing pretty well:
> Document signing is NOT a technical problem. [Editors Note: Because it was solved technically a long time ago] Its a legal acceptance problem — and everyone KNOWS DocuSign and friends and understands how theyre admissible. Anything else would have to compete with that and people would be suspicious of it for a long time.
While this may sound like a hurdle at first, it immediately gave me a sense of validation for a more open approach to signing. People will and should be suspicious of their tools and demand a high bar when it comes to trust. And the way to earn this trust is by being open. Trusted tools should be the result of thoughtful discussion and reviews. They should be the result of the needs and will of its community. They should be transparent, adaptable, and empowering while using. Open Source embodies these values very well for software, which makes it a perfect fit for this space and creating a high-trust tool.
## Next Steps
So, what can you expect from here on out? I've started to build Documenso 0.1 which is scheduled to release in “early” 2023. If you're interested in helping make this happen, let me know via [hi@documenso.com](mailto:hi@documenso.com). Getting working code into the hands of the perspective Documenso community is currently the #1 goal. Other than that I'll be releasing several articles about document signing and what something like Documenso should look like, in my humble opinion. So stay tuned!
If you think Documenso is worthy of support, please share <a href="https://documenso.com" target="_blank">documenso.com</a> with anyone interested, and sign up to be among the first to try out version 0.1 as soon as it launches.
Cheers from Hamburg
Timur

View File

@ -1,68 +0,0 @@
---
title: Documenso Profiles Are Here
description: Today, we are launching Documenso Profiles, a new way to let your peers sign your documents.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-07-01
tags:
- Announcement
- Direct Links
- Profiles
---
<figure>
<MdxNextImage
src="/blog/profile1.png"
width="1260"
height="1260"
alt="Documenso Profile of Timur"
/>
<figcaption className="text-center">Let people sign anytime with Documenso Profiles. Try it [with my profile](https://app.documenso.com/p/timur).</figcaption>
</figure>
> TLDR; We are launching a Documenso Profile where you can display your templates for everyone to sign at any time.
## Introducing Documenso Profiles
Today, Im excited to announce that we are launching Documenso Profiles 🎉 While we have been focussing on the conventional signing experience so far, Direct Links and now profiles are our first steps to bring some long-awaited innovation back to digital signatures.
Documenso Profiles allows you to share any template with a public link in a very easy-to-understand way. Adding templates to your profiles allows everyone to sign your documents just when they need to. Forms, NDAs, Disclaimers, and even contracts are now available anytime they are needed. Profiles turn the classic signing flow on its head by letting the recipient sign first before the documents owner becomes active. Booking links (e.g., Cal.com) and customer self-service portals (e.g., Stripe Billing Portal) are becoming the norm, so its time we did the same for signing.
## The Best Way to Share Your Singing Links
With profiles, we want to offer you the best way to share your standing Documenso Template Links in a public place. You can add your Documenso Profile to your social profiles, Email footer, Video Description, or wherever your audience, customers, and partners interact with you. The profile will be a public, trusted place to ensure you know who you are dealing with.
Looking at the classical social media fake profile problem, we know this is tricky to achieve. We will pay close attention to how profiles are used and how we can help the community use them easily and securely. As a first step towards this direction, we are introducing a trust badge next to your name. There will be 3 levels to start:
- Free Users: No Badge
- Paid Users: Green Badge
- Early Adopters: Gold Badge
<figure>
<MdxNextImage
src="/blog/profile2.png"
width="1260"
height="1260"
alt="Documenso Profile Edit Screen"
/>
<figcaption className="text-center">Add and remove templates anytime.</figcaption>
</figure>
## An Open Economy built on Documenso
We see offering profiles as a first step towards creating a full economy on top of the open signing ecosystem we envision. While we want to keep building the product with the community, we also want an economy to grow on the open tech we create. This includes using the tech (profiles) or offering service on top of the tech (hosting and customization). Our ecosystem is still young, and the goal is not to have Documenso Inc. as the only commercial actor but to fill our own niche in a global and thriving open ecosystem. One of our guiding principles is solving things once and for all. While our focus will be on the core signing product, we want to enable others to offer templates for use on profiles or privately. A lot of contracts, forms, and other paperwork have been recreated countless times. Offering high-quality, peer-reviewed templates is a natural extension of the current platform. There will be free templates, offered as marketing for their creators, and paid templates, offered as actual products.
## What's next
While an open signing economy is really exciting, we know it will take time to mature. Building out a mature ecosystem for builders and entrepreneurs takes time. While this aspect of Documenso matures, we will be focussing on the core of the platform: Letting you integrate and embed Documenso wherever you want it.
If you already have a Documenso account, you can [activate your profile here](https://app.documenso.com/settings/public-profile).
Dont have an account and want to check out profiles? You can do so using our [free plan](https://documen.so/free).
As always, we want to hear from you on [Twitter / X](https://twitter.com/eltimuro) (DMs are open) or [Discord](https://documen.so/discord) if you have any questions, ideas, or comments.
Best from Hamburg\
Timur

View File

@ -1,63 +0,0 @@
---
title: 21 CFR Part 11 is here, and so is Vial.com
description: We launched Vial.com with a 21 CFR Part 11 compliant setup. Reach out if 21 CFR Part 11 compliance is among your needs.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-07-18
tags:
- Vial.com
- 21 CFR Part 11
- Compliance
---
<video id="vid" width="100%" src="/blog/vial.webm" autoPlay loop muted></video>
<figcaption className="text-center">
Vial.com uses Documenso for 21 CFR Part 11 compliant signing.
</figcaption>
> TLDR; We launched Vial.com on Documenso and are open for 21 CFR Part 11 business.
# What is 21 CFR
You have never heard of 21 CFR Part 11? You are in good company since most people haven't. If you have, you probably work in an industry regulated by the U.S. Food and Drug Administration (FDA). Title 21 of the Code of Federal Regulations (CFR) is dedicated to detailing FDA-regulated business, and sub-part 11 sets out guidelines for using electronic signatures in this highly regulated field. Hence, 21 CFR Part 11 is highly relevant for regulated industries that aim to employ digital signatures. The guidelines set out in 21 CFR Part 11 aim to provide trustworthy, reliable, and equivalent to paper records and handwritten signatures. All Industries that fall under the FDA's regulation, e.g. pharmaceuticals, biotechnology, medical devices, and biologics, must comply with these rules when choosing or creating systems for electronic signatures.
Compliance with 21 CFR Part 11 is crucial for companies to use electronic records and signatures in their operations legally. It affects how companies manage documentation, conduct audits, and maintain regulatory submissions. Non-compliance can result in legal penalties, rejected submissions, and delays in product approvals, emphasizing the importance of adhering to these guidelines in FDA-regulated activities.
# Vial.com
Vial is a technology company on a mission to advance programs to market through computationally designed therapeutics and cost-effective clinical trials. It is imperative that Vial manages this process securely, effectively, and highly compliant. By leveraging it's modern platform, Vial aims to accelerate drug development and, ultimately, time to market for new therapies. You can learn more about them [here](https://vial.com/about-us).
[Together](https://documen.so/vial-documenso), Documenso and Vial set out to create the first open-source, 21 CFR Part 11 compliant signing solution. After iterating over the product together, Vial moved their operation from DocuSign, a known legacy signing provider, to a Documenso Enterprise plan. We are very happy to be able to support Vials mission by fulfilling our own: bringing open signing and all its innovation to where it's needed.
# 21 CFR Part 11 on Documenso Highlights
21 CFR Part 11 is a highly complex statute, and going into the all design rationales and the following implementation details, deserves its own article later. For now, I want to share a few notable highlights.
## The Full Experience
We implemented 21 CFR Part 11, keeping the main user experience of Documenso intact. Our 21 CFR module is not separate but natively integrated into all Documenso flows, thus not sacrificing usability for compliance. This also means most (if not all) advanced features we offer are usable in a compliant way. This prevents customers from being trapped in an anti-innovation bubble, not allowing access to new features for fear of non-compliance.
## Action Reauth Using Passkeys
<video id="vid" width="100%" src="/blog/vial2.webm" autoPlay loop muted controls></video>
<figcaption className="text-center">
Using passkeys (used here via fingerprint scanner) is the smoothest way to re-authenticate.
</figcaption>
One of the requirements affecting day-to-day life the most is the requirement to actually reauthenticate every signature placed on a document. While we can't change that, we can help make the reauthentication as painless as possible. To this end, we opted for passkeys. While Documenso supports passkeys to log in, they are also supported to authenticate signing on a per-signature level as part of the Documenso Enterprise Plan. The user still has to authenticate every signature but can now do so from the comfort of their passkey provider, be that 1Password, their browser, or any other provider.
## Direct Links
We recently launched [Direct Template Links](https://documen.so/direct-links), a new way to let people sign and fill out forms. Links can be completed anytime, creating a new document in the process. Direct Links are also 21 CFR part 11 compliant, using action reauthentication, audit log, and all other compliance requirements.
# Documenso Enterprise Plan
With the successful launch of Vial, we are now open for business. 21 CFR Part 11 compliance is part of the Documenso Enterprise plan, which includes all regulations we currently support and upcoming additions. While the pricing depends heavily on your needs and scale, we offer fixed-price plans for better predictability for both sides. In our experience, volume-based pricing is a legacy headache we want to avoid.
If you are FDA-regulated and looking for a modern signing solution, we are happy to discuss your requirements in detail. You can write us (hi@documenso.com) or contact [our enterprise team](https://documen.so/21cfr) at any time or stage.
If you have any questions or comments, please reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord).
Best from Hamburg\
Timur

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