Introduces customization options for the document completion email
template to allow for custom email bodies and subjects for documents
created from direct templates.
## Testing Performed
- Verified correct rendering of custom email subject and body for direct
template documents
- Verified the all other completed email types are sent correctly
chore Top 3 Signing Efficiency Hacks for Freelancers
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a blog post titled "Top 3 Signing Efficiency Hacks for
Freelancers" with tips on streamlining contract signing using Documenso.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
changelog for v 1.5.6
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Display document creation time in the documents view.
- Introduced direct template links for easier access.
- Added support for OpenID Connect (OIDC) for improved authentication
options.
- **Enhancements**
- Transitioned to a new rust-based library for signing documents,
enhancing performance and security.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
announcing profiles blogpost
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced "Documenso Profiles" that allow users to share digital
signature templates publicly.
- Recipients can sign documents directly via public links, streamlining
the signing process.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
How to Sign an NDA online (fast) blog article
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Published a new blog post on signing NDAs faster with Documenso,
highlighting the use of direct links, templates, and basic signing for
efficiency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
**Pending testing on preview**
Enable yearly team pricing during checkout.
## Changes Made
- Enable selecting yearly team pricing during checkout
- Update pricing on marketing to $480 for yearly team plan
## Testing Performed
- Stripe simulations
Pending manual testing
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Updated the savings message in the pricing table to reflect new
savings amounts.
- Adjusted yearly pricing from $500 to $480.
- Modified user addition costs based on subscription periods.
- **Improvements**
- Simplified button text in the Create Team Checkout Dialog to
consistently display "Checkout".
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
When using account required auth for a given document this change now
shows the sign up or sign in button depending on if an account actually
exists within
Documenso.
This change should reduce friction and confusion when a recipient has
been invited to a document.
## 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
- Updated the ssr for the signing page to fetch whether a user account
exists when document auth is required
- Pass the user exists flag to the document auth required page
## Testing Performed
- Created and sent a document to a user with an account and one without an account in both a logged in and logged out state and confirmed that the dialogs are displayed as expected.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced user statistics display including metrics on document
creation and signing in the admin dashboard.
- Added a bar chart visualizing monthly growth data of users with
documents.
- **Enhancements**
- Updated dashboard stats page to provide more detailed user-related
metrics and charts.
- Added new CSS variable `--gold` for consistent theming across light
and dark modes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Show a dialog when the document has signers with no signature fields
placed.
## Changes Made
Created a new dialog that'll be triggered when the document owner tries
to send a document to the signers without placing signature fields. The
document owners can't proceed to the next step unless they add signature
fields.
## Checklist
- [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.
https://github.com/documenso/documenso/assets/25515812/f1b5c34e-2ce0-40e3-804c-f05d23045710
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced "Direct Links" for async signing, allowing users to create
documents from templates using public links.
- Added `MissingSignatureFieldDialog` component to ensure users don't
miss adding signature fields.
- **Enhancements**
- Updated blog content to provide guidance on contract management and
announce new pricing plans.
- **Bug Fixes**
- Improved async signing process for better efficiency and control.
- **Refactor**
- Improved internal code structure and import order for stripe-related
functionality.
- **Tests**
- Enhanced e2e tests to verify signature presence before document
creation and updated test flows for document approval.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: David Nguyen <davidngu28@gmail.com>
## Description
This pull request introduces the functionality to display pending fields
on the document page view. This enhancement allows users to see which
fields are pending and need to be completed.

## Changes Made
- Added `getPendingFieldsForDocument` function in
`packages/lib/server-only/field/get-pending-fields-for-document.ts` to
fetch pending fields for a document.
- Created a new component `DocumentPendingFields` in
`document-pending-fields.tsx` to display the pending fields with options
to hide individual fields.
## Testing Performed
- Tested the new feature by creating documents with pending fields and
verifying their display on the document page view.
- Verified that the pending fields are correctly hidden when the "Hide
field" button is clicked.
- Ran unit tests for the new functionality and existing components to
ensure no regressions.
## Checklist
- [x] I have tested these changes locally and they work as expected.
- [x] I have added/updated tests that prove the effectiveness of these
changes.
- [x] 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.
## Additional Notes
No additional notes.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced logic for handling pending and completed document fields
based on signing status.
- **Refactor**
- Replaced `getCompletedFieldsForDocument` with `getFieldsForDocument`.
- Updated `DocumentReadOnlyFields` component to `DocumentPendingFields`.
- **Bug Fixes**
- Improved field retrieval accuracy and display based on recipient
signing status.
- **Style**
- Enhanced UI elements with new icons and button adjustments for better
user interaction.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: David Nguyen <davidngu28@gmail.com>
## Description
Currently a work in progress but this adds background tasks to Documenso
for handling tasks that take a little longer and aren't part of the
overall critical path.
## Related Issue
N/A
## Changes Made
Added a pluggable jobs provider supporting both a local provider and a
Trigger.dev provider.
## Testing Performed
- Verified job level retries work
- Verified task level retries work without incrementing job retries


**This will still have a lot of rough edges but is a perfect MVP for
local _durable_ compute which may accept more providers later on**
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added background job management functionalities to handle email
sending and job processing.
- Introduced support for triggering and managing jobs using various
providers.
- **Chores**
- Updated environment configuration files to support new job management
features.
- Added and updated scripts and dependencies for job management and CLI
commands.
- **Refactor**
- Refactored email sending functionalities to utilize the new job queue
mechanism.
- **Documentation**
- Updated documentation to reflect the new environment variables and
configurations related to background jobs.
- **Configuration**
- Updated Docker configurations to support new services for job
management.
- Updated VSCode settings for improved development experience with new
dependencies and formatting rules.
- **Database**
- Added new database schemas and migrations to support background job
management and tracking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
documenso for freelancer contracts article
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Published a new blog post: "How Documenso Enhances Contract Management
for Freelancers, Helping Them Close More Clients Efficiently." This post
offers insights into contract management and the benefits of digital
signatures using Documenso.
- **Documentation**
- Updated a hyperlink in the conclusion section of the blog post titled
"How Documenso Helps Freelancers Close More Clients Efficiently" to
direct users to a new URL related to signing freelance contracts with
Documenso.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
added changelog page to marketing site
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a changelog page to detail recent updates and features.
- Added a link to the changelog in the website footer for easy access.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
When using account required auth for a given document
this change now shows the sign up or sign in button
depending on if an account actually exists within
Documenso.
This change should reduce friction and confusion when a
recipient has been invited to a document.
direct links account blogarticle
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced Direct Links for templates, allowing asynchronous document
signing via unique shareable links for easy access.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
"How Documenso Helps Freelancers Close More Clients Efficiently" blog
article
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Documentation**
- Added a new blog post titled "How Documenso Helps Freelancers Close
More Clients Efficiently," discussing the benefits of using Documenso to
streamline the proposal process with digital signatures for enhanced
speed and security in closing deals.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Adjusts the styling to improve the layout and appearance of the carousel
controls and thumbnails on smaller screens.
## Changes Made
- Updated the carousel control styling to be more responsive.
- Adjusted the font size and padding of the slide component for better
display on mobile screens.
## Screenshot

## Checklist
- [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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
PDFs can have pages that are rotated, which are correctly rendered in
the frontend. However, when we load the PDF in the backend, the rotation
is applied which causes issues when we want to insert fields.
To account for this, we swap the width and height for pages that are
rotated by 90/270 degrees. This is so we can calculate the virtual
position the field was placed if it was correctly oriented in the
frontend.
Then when we insert the fields, we apply a transformation to the
position of the field so it is rotated correctly.
**Test document with 0/90/180/270 rotated pages**
[rotated_test.pdf](https://github.com/user-attachments/files/15798138/rotated_test.pdf)
chore: sunset early adopters
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a new `Carousel` component with video autoplay
functionality.
- Added a `Thumb` component for carousel navigation.
- Introduced a new `Enterprise` component detailing enterprise licensing
and compliance.
- **Updates**
- Updated the `Hero` component to replace the `Widget` with the new
`Carousel`.
- Revised the `PricingTable` component to reflect new pricing plans and
details.
- Changed tooltip text in the marketing app for better clarity.
- Updated button texts and links in the `Callout` component to promote
the "Free Plan".
- **Content**
- Published a blog post announcing the end of the Early Adopters Plan
and introducing new pricing plans.
- **Dependencies**
- Added Embla Carousel dependencies for enhanced carousel functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Modifies the generated filename for the downloaded PDF by appending
"_signed" to the base title.
## Changes Made
- Update the filename in the downloadFile function call to append
"_signed" to the baseTitle variable.
## Testing Performed
Tested the `downloadPDF` function locally to ensure that the downloaded
PDF file has the correct filename with "_signed" appended.
## Description
Update the direct template signing process and emails to correctly
reflect the role of the recipient who actioned the direct template.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Dynamic updating of title and description based on recipient role in
the document signing process.
- Enhanced email templates to include recipient roles, providing more
context in email notifications.
- **Improvements**
- More descriptive actions in email templates based on recipient roles,
improving clarity for recipients.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Direct templates links is a feature that provides template owners the
ability to allow users to create documents based of their templates.
## General outline
This works by allowing the template owner to configure a "direct
recipient" in the template.
When a user opens the direct link to the template, it will create a flow
where they sign the fields configured by the template owner for the
direct recipient. After these fields are signed the following will
occur:
- A document will be created where the owner is the template owner
- The direct recipient fields will be signed
- The document will be sent to any other recipients configured in the
template
- If there are none the document will be immediately completed
## Notes
There's a custom prisma migration to migrate all documents to have
'DOCUMENT' as the source, then sets the column to required.
---------
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
## Description
This PR adds generic OIDC as an authentication provider. This allows
personal users and companies potentially to define whatever IdP they
want as long as it supports the OIDC well known format. (Azure, Zitadel,
Authentik, KeyCloak, Google, etc. all support it)
## Related Issue
Fixes#1090
## Changes Made
- Adds OIDC buttons to the signin and registration pages
- Adds appropriate environment variables
- Adds migration to add OIDC to the `IdentityProvider` Enum
## Testing Performed
#### Zitadel
- Created application in Zitadel as an web app, with Client auth
- Enabled `User Info inside ID Token` in Token settings
- Copied client id and client secret to the new .ENV variables
- Copied the well-known URL from the URLs section to .ENV
- Created new account with OIDC provider button
- Verified email manually
- Signed into account with OIDC provider
- Logged out
- Signed into accounting again with OIDC provider
#### Authentik
- Created application in Authentik
- Copied client id and client secret to the new .ENV variables
- Copied the well-known URL from the URLs section to .ENV
- Created new account with OIDC provider button
- Verified email manually
- Signed into account with OIDC provider
- Logged out
- Signed into accounting again with OIDC provider
#### Azure AD
- Created application in Azure AD using OAuth2
- Copied client id and client secret to the new .ENV variables
- Copied the well-known URL from the URLs section to .ENV
- Created new account with OIDC provider button
- Verified email manually
- Signed into account with OIDC provider
- Logged out
- Signed into accounting again with OIDC provider
Adds fields to the Account model to support various pieces
of data returned by OIDC providers such as AzureAD and GitLab.
Additionally passes through the email verification status and handles
retrieving the email for providers such as AzureAD who use a different
claim instead.
Reverts the change to find-documents to use Kysely. I'd like to gain
confidence by using it in smaller pieces before commiting to doing
what is one of our most complicated queries in Documenso.
Introduces the ability to not send an email when sending
(publishing) a document using the API.
Additionally returns the signing link for each recipient
when working with recipient API endpoints and returns
the document object including recipients when sending
documents via API.
A series of changes to improve sealing robustness avoiding errors that
have appeared during monitoring.
Additionally handles the recently published CVE affecting the
`pdfjs-dist` library.
Bumps ReactPDF and pdfjs-dist to avoid the CVE that allows
for code execution in pdf's. This change doesn't specifically
upgrade to the latest pdfjs-dist due to issues with top level
await, instead disabling the evaluation of javascript within
the PDF.
Use Noto Sans to gracefully handle inserting custom text
on PDF's. Previously we were using Helvetica which is a
standard PDF font but that would fail for any character
that couldn't be encoded in WinANSI.
Noto Sans was chosen as it has support for a large number
of languages and glyphs with challenges now being adding
support for CJK glyphs.
Previously we used the form flattening method from PDF-Lib
but unfortunately when it encountered orphaned form items
or other PDF oddities it would throw an error.
Because of this certain documents would fail to seal and
be stuck in a pending state with no recourse available.
This change rewrites the form flattening handler to be
more lenient when coming across the unknown opting to skip
items it can't handle rather than abort.
---
name: Pull Request
about: Submit changes to the project for review and inclusion
---
## Description
Display time in 12h format in the documents table.
<!--- 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". -->
Fixes#1077
## Changes Made
<!--- Provide a summary of the changes made in this pull request. -->
<!--- Include any relevant technical details or architecture changes.
-->
- Use DateTime.DATETIME_SHORT
- ...
## Testing Performed
<!--- Describe the testing that you have performed to validate these
changes. -->
<!--- Include information about test cases, testing environments, and
results. -->
- Tested time in different timezone.
- Ran tests in web and mobile browser
1. Login
2. Add a document
3. Verify that you see date and time in 12h format as per your locale.
## 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.
- [x] I have added/updated tests that prove the effectiveness of these
changes.
- [x] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [x] I have addressed the code review feedback from the previous
submission, if applicable.
## Additional Notes
<img width="1512" alt="Screenshot 2024-04-29 at 04 21 53"
src="https://github.com/documenso/documenso/assets/29673073/778155d4-a920-40bd-acdc-7451c9c5d4b7">
<img width="300" alt="Screenshot 2024-04-29 at 04 22 18"
src="https://github.com/documenso/documenso/assets/29673073/3471de0f-f426-4ea1-be1e-220462aff9e4">
## Description
General enhancements for templates.
## Changes Made
Added the following changes to the template flow:
- Allow adding document meta settings
- Allow adding email settings
- Allow adding document access & action authentication
- Allow adding recipient action authentication
- Save the state between template steps similar to how it works for
documents
Other changes:
- Extract common fields between document and template flows
- Remove the title field from "Use template" since we now have it as
part of the template flow
- Add new API endpoint for generating templates
## Testing Performed
Added E2E tests for templates and creating documents from templates
**Description:**
This PR updates and adds a new action to assign `status: assigned` label
---------
Signed-off-by: Adithya Krishna <aadithya794@gmail.com>
## Description
Update the template flow to allow for entering recipient placeholder
emails and names
## Changes Made
- General refactoring
- Added advanced recipient settings for future usage
## Description
Currently if you complete a pending encrypted document, it will prevent
the document from being sealed due to the systems inability to decrypt
it.
This PR disables uploading any documents that cannot be loaded as a
temporary measure.
**Note**
This is a client side only check
## Changes Made
- Disable uploading documents that cannot be parsed
- Refactor putFile to putDocumentFile
- Add a flag as a backup incase something goes wrong
## Description
Currently users who sign in via Google SSO do not get assigned a Stripe
customer account.
This enforces the Stripe customer requirement on sign in.
There might be a better place to put this so it's open to any
suggestions.
## Description
Improves the sealing process by being strict on how long certificate
generation can take, opting to fail generation and continue sealing.
Also changes the ordering of sealing so an error in the process won't
also cause a document to be "COMPLETED" since it hasn't been
cryptographically sealed yet.
The downside to this change is that documents that fail during sealing
will require manual intervention as a signer or owner won't be able to
*complete* the document.
## Testing Performed
- Modified code to force specific failure modes to occur and verified
that documents were either gracefully sealed without a certificate or
not sealed and not completed.
Improves the sealing process by being strict on how
long certificate generation can take, opting to fail
generation and continue sealing.
Also changes the ordering of sealing so an error in the
process won't also cause a document to be "COMPLETED"
since it hasn't been cryptographically sealed yet.
The downside to this change is that documents that fail
during sealing will require manual intervention as a signer
or owner won't be able to *complete* the document.
## Description
Currently deleting a pending document where you are a recipient off will
delete the document, but will also throw an error.
This is due to the recipient being updated after the document deleted,
which is only supposed to happen for completed documents.
## Description
Automatically marks the document as completed if all the recipients are
CC.
## Changes Made
Added an if statement in the last form step (`onAddSubjectFormSubmit`)
that checks if all the recipients are CC. If so, the document status is
updated to `COMPLETED`.
## Testing Performed
Tested the changes and they work as expected.
## 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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Enhanced document sending logic to update document status based on
recipient roles.
- **Bug Fixes**
- Removed redundant form submission handling in the document editing
feature.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Feature flags are broken on SSR due to this error
```
TypeError: fetch failed
at Object.fetch (node:internal/deps/undici/undici:11731:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
cause: RequestContentLengthMismatchError: Request body length does not match content-length header
at write (node:internal/deps/undici/undici:8590:41)
at _resume (node:internal/deps/undici/undici:8563:33)
at resume (node:internal/deps/undici/undici:8459:7)
at [dispatch] (node:internal/deps/undici/undici:7704:11)
at Client.Intercept (node:internal/deps/undici/undici:7377:20)
at Client.dispatch (node:internal/deps/undici/undici:6023:44)
at [dispatch] (node:internal/deps/undici/undici:6254:32)
at Pool.dispatch (node:internal/deps/undici/undici:6023:44)
at [dispatch] (node:internal/deps/undici/undici:9343:27)
at Agent.Intercept (node:internal/deps/undici/undici:7377:20) {
code: 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH'
}
}
```
I've removed content-length header since it isn't mandatory to my
knowledge for get requests.
## Changes
- Add fallback local flags when individual flag request fails
- Add error logging
- Remove `content-length` from headers being passed to Posthog
## Description
Upgrade playwright once again and use CDP for remote connections to
avoid version lock-in with `playwright.connect`
Resolves the issue where all CI is failing currently due to downgrading
playwright.
## Description
Currently if you create a team webhook, you can see it in your personal
webhooks.
However, interacting with them will throw errors because there is server
side logic preventing any interaction with them since they are outside
of the correct context.
So the solution is to either:
- Allow the user to edit the team webhooks that they created on their
personal webhooks page
- Hide team webhooks for personal webhooks pages
This PR goes with the second option, but is open to suggestions.
## Description
Added the ability for recipients to see fields from other recipients who
have completed the document when they are signing the document
Added the ability for the document owner to see fields from recipients
who have completed the field on the document page view (only visible
when the document is pending)
## 🚨🚨 Migrations🚨🚨
- Drop all `Fields` that do not have a `Recipient` set (not sure how it
was possible in the first place)
- Remove optional `Recipient` field on `Field` which doesn't make sense
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
- **New Features**
- Enhanced document viewing by adding read-only fields based on document
status.
- Improved signing page by fetching and displaying completed fields for
tokens.
- Updated avatar component to show recipient status with tooltips for
better user interaction.
- **Bug Fixes**
- Made `recipientId` a required field in the database to ensure data
consistency.
- **Refactor**
- Optimized popover functionality in UI components for better
performance and user experience.
- **Documentation**
- Added detailed component and function descriptions for new features in
the system.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Disable the document certificate download button when the document is
not complete
## Changes Made
- Disable UI button
- Disable TRPC API endpoint
## Testing Performed
Tested locally for pending, draft and completed documents
**Description:**
This PR adds a check for filename title and if the title ends with
`.pdf` then the extension isnt added or else its added
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Bug Fixes**
- Enhanced email attachment handling to ensure PDF files are correctly
identified with a ".pdf" extension.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Allow users to download a completed document via API.
## Testing Performed
Tested the code locally by trying to download both draft and completed
docs. Works as expected.
## Checklist
- [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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Implemented functionality to download signed documents directly from
the app.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Updated the email content based on whether the document owner is a
recipient or not.
If the document owner is a recipient (self-signer):
* the email subject will be `Please view/sign/approve your document`
* the email header will be `Please view/sign/approve your document
"<your-doc-title>"`
* the email content will be `You have initiated the document
"<your-doc-title>" that requires you to view/sign/approve it.`
Otherwise:
* the email subject will be `Please view/sign/approve this document`
* the email header will be `<doc-owner> has invited you to
view/sign/approve "<doc-title>"`
* the email content will be `<doc-owner> has invited you to
view/sign/approve the document "<doc-title>".`
## Related Issue
Related to #1091
## Testing Performed
Tested the feature with a different number of recipients (including and
excluding the document owner - self-signer). Tested both the sending and
resending functionality.
## Checklist
- [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.
## UI Screenshots




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Summary by CodeRabbit
- **New Features**
- Enhanced the document invitation components to support scenarios where
the recipient is also the sender, providing customized email content and
subject lines.
- Introduced new properties in email templates to improve clarity and
relevance based on the user's role in the document signing process.
- **Refactor**
- Updated components to use a more flexible `headerContent` property for
displaying invitation headers, replacing previous individual inviter
details.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Currently users can sign and complete draft documents, which will result
in a completed document in an invalid state.
## Changes Made
- Prevent recipients from inserting or uninserting fields for draft
documents
- Prevent recipients from completing draft documents
- Remove ability to copy signing tokens unless document is pending
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Enhanced document status visibility and control across various
components in the application. Users can now see and interact with
document statuses more dynamically in views like `DocumentPageView`,
`DocumentEditPageView`, and `DocumentsDataTable`.
- Improved document signing process with updated status checks, ensuring
actions like signing, completing, and removing fields are only available
under appropriate document statuses.
- **Bug Fixes**
- Adjusted document status validation logic in server-side operations to
prevent actions on incorrectly stated documents, enhancing the overall
security and functionality of document processing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Add additional information for each role to help document owners
understand what each role involves.
## Changes Made



## Testing Performed
Tested the changes locally.
## 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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Updated recipient role terminology and added tooltips in the
`AddSignersFormPartial` component:
- "Signer" changed to "Needs to sign" with tooltip
- "Receives copy" changed to "Needs to approve" with tooltip
- "Approver" changed to "Needs to view" with tooltip
- "Viewer" changed to "Receives copy" with tooltip
- Enhanced select dropdown options with icons and tooltips for different
recipient roles in the `AddTemplatePlaceholderRecipients` component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Timur Ercan <timur.ercan31@gmail.com>
## Description
Fix the issue where duplicate templates can be created
## Changes Made
- Prevent duplicate templates by correctly disabling elements
- Clear the PDF when the form is reset
- General UI changes to new template dialog for consistency
- Add description for new template dialog
- Add close button for new template dialog
## Testing Performed
Manual testing
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have followed the project's coding style guidelines.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced new components in the template creation dialog for better
usability: `DialogClose`, `DialogDescription`, and `DialogFooter`.
- Enhanced file upload handling and display.
- Added a cancel button and a create template button to the dialog
footer for improved navigation.
- **Refactor**
- Updated the dialog content and form layout for a more intuitive user
experience.
- Refactored form structure and labels for clarity.
- **Removed Features**
- Removed the `Label` component from the dialog.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
Currently, when the command menu is opened using the Command+K hotkey,
two modals are getting rendered.
This is because the modals are mounted in two components: header and
desktop-nav. Upon triggering the hotkey, both modals are rendered.
## Related Issue
#1032
## Changes Made
The changes I made are in the desktop nav component. If the desktop nav
receives the command menu state value and the state setter function, it
will trigger only that. If not, it will trigger the state setter that is
defined in the desktop nav. This way, we are preventing the modal from
mounting two times.
## Testing Performed
- Tested behaviour of command menu in the portal
- Tested on browsers chrome, arc, safari, chrome, firefox
## Checklist
- [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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Enhanced the navigation experience by integrating command menu state
management directly within the `DesktopNav` component, allowing for
smoother interactions and control.
- **Refactor**
- Simplified the handling of the command menu by removing the
`CommandMenu` component and managing its functionality within
`DesktopNav`.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: David Nguyen <davidngu28@gmail.com>
## Description
This PR introduces the ability to add oneself as a signer by simply
clicking a button, rather than filling the details manually.
### "Add Myself" in the document creation flow
https://github.com/documenso/documenso/assets/25515812/0de762e3-563a-491f-a742-9078bf1d627d
### "Add Myself" in the document template creation flow
https://github.com/documenso/documenso/assets/25515812/775bae01-3f5a-4b24-abbf-a47b14ec594a
## Related Issue
Addresses
[#113](https://github.com/documenso/backlog-internal/issues/113)
## Changes Made
Added a new button that grabs the details of the logged-in user and
fills the fields *(email, name, and role)* automatically when clicked.
## Testing Performed
Tested the changes locally through the UI.
## Checklist
- [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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced the ability for users to add themselves as signers within
documents seamlessly.
- **Enhancements**
- Improved form handling logic to accommodate new self-signer
functionality.
- Enhanced user interface elements to support the addition of self as a
signer, including a new "Add myself" button and disabling input fields
during the process.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
**Description:**
- Updated mobile header with respect to latest designs
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added a new `showText` property to the `MenuSwitcher` component to
control text visibility.
- Added a `textSectionClassName` property to the `AvatarWithText`
component for conditional text section styling.
- Updated the `CommandDialog` and `DialogContent` components with new
positioning and styling properties.
- **Style Updates**
- Adjusted text size responsiveness in the `Hero` component for various
screen sizes.
- Modified text truncation and input styling in the `Widget` component.
- Changed the width of the `SheetContent` element in `MobileNavigation`
and adjusted footer layout.
- **Documentation**
- Added instructions for certificate placement in `SIGNING.md`.
- **Refactor**
- Standardized type imports across various components and utilities for
improved type checking.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Signed-off-by: Adithya Krishna <adithya@documenso.com>
Signed-off-by: Adithya Krishna <aadithya794@gmail.com>
Co-authored-by: David Nguyen <davidngu28@gmail.com>
The searchDocuments function is used for the shortcuts commands, afaik.
The function returns the documents that match the user query (if any),
alongside all their recipients.
The reason for that is so it can build the path for the document. E.g.
if you're the document owner, the document path will be
`..../documents/{id}`. But if you're a signer for example, the document
path (link) will be `..../sign/{token}`.
So instead of doing that on the frontend, I moved it to the backend.
At least that's what I understood. If I'm wrong, please correct me.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Enhanced the `CommandMenu` component to simplify search result
generation and improve document link management based on user roles.
- **Refactor**
- Updated document search logic to include recipient token masking and
refined document mapping.
- **Style**
- Minor formatting improvement in document routing code.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **Refactor**
- Enhanced the API specification generation process to include operation
IDs, security schemes, and security definitions more efficiently.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a "Claim Account" feature allowing new users to sign up by
providing their name, email, and password.
- Enhanced user experience for both logged-in and non-logged-in users
with improved UI/UX and additional functionality.
- **Enhancements**
- Implemented form validation and error handling for a smoother sign-up
process.
- Integrated analytics to track user actions during account claiming.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
Co-authored-by: David Nguyen <davidngu28@gmail.com>
---
name: Pull Request
about: Submit changes to the project for review and inclusion
---
## Description
Should fix the rerendering of the status widget
## 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. -->
## Description
When document audit logs were first introduced, we by default set the
`fieldSecurity` to `NONE`
Now that document auth has been added, this is causing issues since we
do not use `NONE` to define field that has no migrations required, but
rather have the `fieldSecurity` field itself be undefined.
To keeps things consistent, this migration replaces `NONE` with
undefined.
There are a few ways to approach this:
- Run a prisma migration on the JSON
- Modify the data before we pass the data to the schema in
`parseDocumentAuditLogData`
- Use `NONE` instead of undefined
If anyone thinks there's a better way to do this, please drop a comment
🙇
## Description
General UI updates
## Changes Made
- Add consistent spacing between document edit/view/log pages
- Add document status to document audit log page
- Update document loading page to reserve space for the document status
below the title
- Update the document audit log page to show full dates in the correct
locale
## Description
Adds the ability to prefill native PDF form fields via the API using
either normal documents or templates.
Since we won't always know when a document is uploaded and has forms we
opt to do this on creation for templates and on sending the document to
recipients in all cases. This means that for a created document it can
look a little funky since the form fields are missing the data until the
document is sent.
This should be improved in a later change but since we've scoped this to
an API only workflow for now we are less concerned with the visual
issues.
## Related Issue
N/A
## Changes Made
- Added the `formValues` field the document model
- Added a new method for finding and filling form fields based on a `key
| value` pair
- Updated the API input shapes to take the new field.
## Testing Performed
- Have created and tested a document using the API both for creation and
usage with a template.
- Have verified that the fields display as expected either during
creation or sending depending on the document type.
## Description
Fetch the updated version of the document after sealing it and return
it. Previously, the `document.documentData.data` wasn't up to date. Now
it is.
## Related Issue
Fixes#1088.
## Testing Performed
* Added console.logs in the code to make sure it returns the proper data
* Set up a webhook and tested that the webhook receives the updated data
## 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.
## Changes Made
- Refactor/optimise tests
- Reduce flakiness
- Add parallel tests (if there's enough CPU capacity)
- Removed explicit worker count when running parallel tests. Defaults to
50% of CPU capacity.
Might want to consider sharding the test across runners in the future as
our tests grows.
## Description
Fixed issue where accounts that were initially created via
email/password, then linked to an SSO account, can bypass the 2FA during
login if they use their email password.
## Testing Performed
Tested locally, and 2FA is now required for linked SSO accounts
## Description
Add the following document action auth options:
- 2FA
- Passkey
If the user does not have the required auth setup, we onboard them
directly.
## Changes made
Note: Added secondaryId to the VerificationToken schema
## Testing Performed
Tested locally, pending preview tests
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have added/updated tests that prove the effectiveness of these
changes.
- [X] I have followed the project's coding style guidelines.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced components for 2FA, account, and passkey authentication
during document signing.
- Added "Require passkey" option to document settings and signer
authentication settings.
- Enhanced form submission and loading states for improved user
experience.
- **Refactor**
- Optimized authentication components to efficiently support multiple
authentication methods.
- **Chores**
- Updated and renamed functions and components for clarity and
consistency across the authentication system.
- Refined sorting options and database schema to support new
authentication features.
- **Bug Fixes**
- Adjusted SignInForm to verify browser support for WebAuthn before
proceeding.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Added a dialog button at the bottom of the admin/documents/[id] page
with confirmation popup.
Confirmation popup have validation for reason to input.
On confirmation document is deleted, and an email is triggred to the
owner of document with the reason stated.
Let me know if there is any more requirement or correction is needed in
this pr. :) #1020
## Description
Currently opening modals, clicking select boxes or using anything from
radix that overlays the screen in some way will shift the screen.
This can be easily noticeable when changing the document "Period"
selector on the /documents page.
## Changes Made
Undo the gutter change for now. Can find a proper solution another time.
https://github.com/documenso/documenso/assets/20962767/5bcae576-2944-4ae5-a2c3-0589e7f61bdb
This change flattens and normalizes annotation and widget layers within
the PDF document removing items that can be accidentally modified after
signing which would void the signature attached to the document.
Initially this change was just to assign to an ArcoForm object in the
document catalog if it existed but quickly turned into the above.
When annotations aren't flattened Adobe PDF will say that the signature
needs to be validated and upon doing so will become invalid due to the
annotation layers being touched.
To resolve this I set out to flatten and remove the annotations by
pulling out their normal appearances if they are present, converting
them into xobjects and then drawing those using the drawObject operator.
This resolves a critical issue the users experienced during the signing
flow when they had marked up a document using annotations in pdf
editors.
## Description
Currently if you try to load the document edit page when fields need to
be rendered, you will not be able to see the fields until you proceed to
the next step.
This is because the fields require the document PDF to be loaded prior
to rendering them.
This PR resolves that issue by only rendering the fields after the PDF
is loaded.
## Changes Made
- Add a state to track whether the PDF is loaded
- Render the fields only after the PDF is loaded
## Testing Performed
Tested document flow manually and the fields are rendered correctly on
load.
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have updated the documentation to reflect these changes, if
applicable.
## Description
**Fixes issues with mismatching state between document steps.**
For example, editing a recipient and proceeding to the next step may not
display the updated recipient. And going back will display the old
recipient instead of the updated values.
**This PR also improves mutation and query speeds by adding logic to
bypass query invalidation.**
```ts
export const trpc = createTRPCReact<AppRouter>({
unstable_overrides: {
useMutation: {
async onSuccess(opts) {
await opts.originalFn();
// This forces mutations to wait for all the queries on the page to reload, and in
// this case one of the queries is `searchDocument` for the command overlay, which
// on average takes ~500ms. This means that every single mutation must wait for this.
await opts.queryClient.invalidateQueries();
},
},
},
});
```
I've added workarounds to allow us to bypass things such as batching and
invalidating queries. But I think we should instead remove this and
update all the mutations where a query is required for a more optimised
system.
## Example benchmarks
Using stg-app vs this preview there's an average 50% speed increase
across mutations.
**Set signer step:**
Average old speed: ~1100ms
Average new speed: ~550ms
**Set recipient step:**
Average old speed: ~1200ms
Average new speed: ~600ms
**Set fields step:**
Average old speed: ~1200ms
Average new speed: ~600ms
## Related Issue
This will resolve#470
## Changes Made
- Added ability to skip batch queries
- Added a state to store the required document data.
- Refetch the data between steps if/when required
- Optimise mutations and queries
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have followed the project's coding style guidelines.
---------
Co-authored-by: Lucas Smith <me@lucasjamessmith.me>
## Description
Add support to login with passkeys.
Passkeys can be added via the user security settings page.
Note: Currently left out adding the type of authentication method for
the 'user security audit logs' because we're using the `signIn`
next-auth event which doesn't appear to provide the context. Will look
into it at another time.
## Changes Made
- Add passkeys to login
- Add passkeys feature flag
- Add page to manage passkeys
- Add audit logs relating to passkeys
- Updated prisma schema to support passkeys & anonymous verification
tokens
## Testing Performed
To be done.
MacOS:
- Safari ✅
- Chrome ✅
- Firefox ✅
Windows:
- Chrome [Untested]
- Firefox [Untested]
Linux:
- Chrome [Untested]
- Firefox [Untested]
iOS:
- Safari ✅
## 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.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced Passkey authentication, including creation, sign-in, and
management of passkeys.
- Added a Passkeys section in Security Settings for managing user
passkeys.
- Implemented UI updates for Passkey authentication, including a new
dialog for creating passkeys and a data table for managing them.
- Enhanced security settings with server-side feature flags to
conditionally display new security features.
- **Bug Fixes**
- Improved UI consistency in the Settings Security Activity Page.
- Updated button styling in the 2FA Recovery Codes component for better
visibility.
- **Refactor**
- Streamlined authentication options to include WebAuthn credentials
provider.
- **Chores**
- Updated database schema to support passkeys and related functionality.
- Added new audit log types for passkey-related activities.
- Enhanced server-only authentication utilities for passkey registration
and management.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Details
Currently there's no way to have a proper PR template selector. Since we
rarely use the E2E template, I've opted to move the generic PR template
to be the default template.
## Description
Update the add signer form to disable the signers when required.
I assume the actual issue is that `{...field}` was spreading a disabled
prop which was overriding our one.
## Changes Made
- Use fieldset to disable inputs
- Manually disable select since fieldset doesn't work for that select
for some reason
Right now, the eslint command runs separately for each staged file. This
PR aims to change that by running just one eslint command for all the
files that have been changed.
## Description
Updates the `on-create.sh` script to use our `dx` command resolving
issues where it couldn't find the docker compose file due to changes
that have happened since publishing the Documenso docker image.
## Related Issue
Resolves#1026
## Test Details
N/A
## Checklist
- [x] I have written the new test and ensured it works as intended.
- [x] I have added necessary documentation to explain the purpose of the
test.
- [x] I have followed the project's testing guidelines and coding style.
- [x] I have addressed any review feedback from previous submissions, if
applicable.
## Additional Notes
N/A
## Description
Updates the docker documentation and compose files to include key file
related configuration for self hosters. This was missed as the key file
environment variables weren't documented in the `.env.example` file
which was used for creating the docker documentation.
## Related Issue
#1012
## Changes Made
- Updated the docker configuration to include key file environment
variables
- Updated the .env.example to include key file env vars
- Updated the compose images to use volumes for key files
## Testing Performed
- I have used the containers with the updated values and confirmed that
they work as expected
## Checklist
- [x] I have tested these changes locally and they work as expected.
- [x] I have added/updated tests that prove the effectiveness of these
changes.
- [x] I have updated the documentation to reflect these changes, if
applicable.
- [x] I have followed the project's coding style guidelines.
- [x] I have addressed the code review feedback from the previous
submission, if applicable.
## Additional Notes
N/A
## Description
This pull request addresses the issue where users on touchscreen devices
couldn't properly see the Recipients list. I have implemented a two-easy
solution to address this problem, offering a seamless user experience
across device types:
1. Popover for Touchscreen: For touchscreen devices, I have added a
popover that displays the Recipients list when users tap on the avatars.
2. Tooltip for Larger Screens: On larger screens (desktops and laptops),
I have added a tooltip that appears when users hover over the avatars.
## Changes
1. Added `Popover` for smaller devices and keep the `Tooltip` for larger
devices.
2. Renamed the component `stack-avatars-wtih-tooltip` to
`stack-avatars-wtih-ui` because now it contains both Tooltip and
Popover.
3. Used the `useWindowSize` hook to conditionally render the `Tooltip`
and `Popover`
4. To avoid repeating the same code, I've created a new component named
`stack-avatars-components.tsx` to show the recipient's details. This
component uses both Popover and Tooltip.
## PR Preview
https://github.com/documenso/documenso/assets/87828904/2dc9b056-b4bd-43dd-b427-a0e803dee55a
## Issue
Closes#756
When prisma:migrate-dev needs to reset the database it will run the seed script to repopulate data. Now that we've added the seed script to our root setup command we will want to avoid this behaviour since we will end up double seeding the database which currently can cause issues.
## Description
Fixes the issue with Vercel preview deployments failing.
It appears that the old `PGHOST` environment variable injected by neon
was:
`ep-snowy-snowflake-a2vc5pa2.eu-central-1.aws.neon.tech`
It is now:
`ep-snowy-snowflake-a2vc5pa2.eu-central-1-pooler.aws.neon.tech`
Notice the `-pooler` being attached automatically to the `PGHOST`.
## References
> The following changes were made to the [Neon Vercel
Integration](https://vercel.com/integrations/neon):
>
>To ensure that users accessing a Neon database from a serverless
environment have enough connections, the DATABASE_URL and PGHOST
environment variables added to a Vercel project by the Neon integration
are now set to a pooled Neon connection string by default. Pooled
connections support up to 10,000 simultaneous connections. Previously,
these variables were set to an unpooled connection string supporting
fewer concurrent connections.
https://neon.tech/docs/changeloghttps://neon.tech/docs/guides/vercel#manage-vercel-environment-variables
Remove `bcrypt` in favor of `@node-rs/bcrypt` which includes precompiled
binaries for many platforms reducing the number of tasks to run post
`npm install`.
Resolves#986
Tidy the docker setup and include a Github Action
for publishing docker containers to DockerHub and
Github Container Registry.
Also add a small README file with docker hosting instructions.
Tidy the docker setup and include a Github Action
for publishing docker containers to DockerHub and
Github Container Registry.
Also add a small README file with docker hosting instructions.
Return the recipient as an array to match the other formats for Zapier.
Otherwise, Zaps with the "DOCUMENT_OPENED" hooks won't work.
All the other webhooks return the "Recipient" field as an array.
---
name: Pull Request
about: Submit changes to the project for review and inclusion
---
## 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. -->
This PR adds the public-facing API.

The public API will allow users to interact with Documenso
programmatically. At the moment, there are 5 available endpoints:
1. `GET /documents`
- get all documents of the user making the API call
- it accepts 2 URL query parameters - `page` and `perPage`, but they are
not mandatory
2. `GET /documents/:id`
- get a specific document of the user making the API call
- it requires 1 URL parameter, which represents the ID of the document
that needs to be retrieved
3. `DELETE /documents/:id`
- delete a specific document of the user making the API call
- it requires 1 URL parameter, which represents the ID of the document
that needs to be deleted
4. `POST /documents`
- making a POST request to this endpoint will return an S3 pre-signed
URL where you can upload the document
- it requires you to pass the file name and the file content type
5. `PATCH /documents/:id/send-for-signing`
- send a document for signing
- it allows you to pass the following:
- signer email *(required)*
- signer name *(optional)*
- field type (signature, email, name, etc.) *(required)*
- page number where to insert the field *(required)*
- page X *(required)*
- page Y *(required)*
- page width *(required)*
- page height *(required)*
- email subject *(optional)*
- email body *(optional)*
The users are authenticated through API tokens. The users can create one
or more tokens in their account settings, and each token will be
available for 1 year _(duration open to suggestions/changes)_.
Each time the user makes a request, the app checks if the token exists
and if it's valid. The app will return `401` *(unauthorized)* and the
appropriate error message if either is false. If both are true AND the
user uses the correct HTTP verb and passes the required URL parameters
and body, the API call will be successful.
Code overview:
- `@documenso/packages/lib/trpc/api-contract` - this folder contains the
`contract` and `schema` files. The `contract.ts` file describes the
structure of the API, the format of the requests and responses, and how
to authenticate your API calls, among others. The `schema.ts` file
contains the Zod schemas used in the API contract.
- `@documenso/packages/trpc/server/api-token-router` - this folder
contains the `router.rs` and `schema.ts` files. Here are the tRPC
procedures used on the frontend. That is, the user's settings page,
where the user can list/create/delete API tokens.
- `@documenso/packages/trpc/tsconfig.json` - I added `"strict": true`
because that's what's suggested in the `ts-rest` documentation.
*([source](https://ts-rest.com/docs/quickstart#create-a-contract))*
- `[...ts-rest].tsx` - This file contains the implementation of the API.
You can see the logic behind each route.
- the rest of the code represents the code for the API tokens page in
the user's settings.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added two-factor authentication form handling in profile settings.
- Introduced account deletion functionality, including Stripe customer
data removal.
- Updated UI components and styles for improved user interaction, such
as enhanced visual feedback for destructive actions.
- **Refactor**
- Improved code quality by updating import statements for type-only
imports.
- **Chores**
- Restructured the `forwardPorts` array in dev container configuration
for clarity.
- Removed a trailing comma in the `vscode` extensions list to adhere to
JSON format rules.
- **Documentation**
- Added comments to clarify the handling of undefined values in
two-factor authentication verification.
- **Database**
- Implemented a SQL migration script for creating a default deleted user
in the system.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Description
This feature allows us to have a dedicated page to view details for a
document.
The current `/documents/[id]` page has been moved to
`/documents/[id]/edit`.
The new `/documents/[id]` page will now display general information on
the document itself.
This will allow us to provide more details relating to a document in the
future, such as version history.
## Examples
These may be outdated as deployment failed
Login via example@documenso.com
Draft document no recipients:
https://stg-7hpkvyc5i-documenso.vercel.app/documents/446
Draft document with recipients:
https://stg-7hpkvyc5i-documenso.vercel.app/documents/440
Pending document:
https://stg-7hpkvyc5i-documenso.vercel.app/documents/447
Completed document:
https://stg-7hpkvyc5i-documenso.vercel.app/documents/448
Pending teams document:
https://stg-7hpkvyc5i-documenso.vercel.app/t/hello/documents/449/
## 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.
- [X] I have followed the project's coding style guidelines.
## Additional Notes
When a user "sends" a document (DRAFT -> PENDING), should we redirect
them to the document/id page, or keep it how it currently is and have it
redirect to `/documents` page?
Disables the generation of the blog and content pages using
generateStaticPaths to deal with a regression with routing
introduced with next-runtime-env.
## Description
Add support for enterprise billing plans.
Enterprise billing plans by default get access to everything early
adopters do:
- Unlimited teams
- Unlimited documents
They will also get additional features in the future.
## Notes
Pending webhook updates to support enterprise onboarding.
Rolled back env changes `NEXT_PUBLIC_PROJECT` since it doesn't seem to
work.
improved document-dropzone ui for small vertical screens (screens less
than 800px vertically)
Although it can still become congested on really small vertical screens,
but possibility is really low.
fixes: #840
Adding a security.txt file enables security researchers to quickly and
easily see where they can submit security issues and know that they are
being taken serious. From the proposal website:
> "When security risks in web services are discovered by independent
security researchers who understand the severity of the risk, they often
lack the channels to disclose them properly. As a result, security
issues may be left unreported. security.txt defines a standard to help
organizations define the process for security researchers to disclose
security vulnerabilities securely.”
See also https://securitytxt.org
## Description
Currently we're not restricting team transfer and email verification
tokens from flowing into the frontend.
This changes restricts it to only return the required information
instead of the whole data object.
## Description
Currently the document redirect URL feature is preventing documents from
being created unless a redirect URL is provided.
During the document edit flow, the redirect URL is hidden in an advanced
tab with the value of an empty string, which will always fail the
current Zod validation since `optional` requires undefined to pass.
There are multiple ways to fix this, but I think this is the easiest
method where we can assume an empty string is valid.
## Description
Fixed issue where setting a recipient role as CC will prevent any
further changes as it is considered as "sent" and "signed".
## Other changes
- Prevent editing document after completed
- Removed CC and Viewers from the field recipient list since they will
never be filled
- Minor UI issues
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have added/updated tests that prove the effectiveness of these
changes.
- [X] I have followed the project's coding style guidelines.
## Description
Add the ability to feature flag the teams feature via UI.
Also added minor UI changes
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have added/updated tests that prove the effectiveness of these
changes.
- [X] I have followed the project's coding style guidelines.
## Description
Fixed issue where you are prevented from removing fields for a recipient
that has multiple fields.
Example:
Recipient has 3 fields, you remove 1 and proceed to next step. In the
next step the field reappears as it was not deleted.
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have added/updated tests that prove the effectiveness of these
changes.
- [X] I have followed the project's coding style guidelines.
## Description
Add support for teams which will allow users to collaborate on
documents.
Teams features allows users to:
- Create, manage and transfer teams
- Manage team members
- Manage team emails
- Manage a shared team inbox and documents
These changes do NOT include the following, which are planned for a
future release:
- Team templates
- Team API
- Search menu integration
## Testing Performed
- Added E2E tests for general team management
- Added E2E tests to validate document counts
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] 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.
## Description
**Fixed document limitation bypassing issues through templates.**
Previously, users could bypass document restrictions by utilizing
templates even after reaching their limitations. This fix ensures that
templates will no longer function as a workaround when users reach their
document limits.
## Changes
1. imported `useLimits` hook on `data-table-templates.tsx`
2. Disabled the 'Use Template' button when the user reaches their limit.
3. Added an Alert Component on top of the templates page to notify users
that they can't use templates anymore because they have reached their
limit.
4. Used `getServerLimits` hook on `template-router` to a condition on
the server.
## Example

## Issue
Closes#883
## Description
Adds the ability to see the events relating to the account.
Event data includes:
- Device
- IP Address
- Time
- Action
Actions are:
- Profile update
- Account linked to SSO (Example user signs in with Google after
creating a email/password account)
- Enable 2FA
- Disable 2FA
- Reset password
- Update password
- Sign out
- Sign in
- Sign in fail
- Sign in 2FA fail
## Changes
- Added audit logs
- Updated 2FA dialogs to have consistent footers
- Update `/settings/security/page` layout
## Testing Performed
Tested events:

More tested events:

## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have followed the project's coding style guidelines.
## Additional Notes
- Not sure if we really want to record the sign out event or not
- Might want to design breadcrumbs for nested setting pages
## Description
Currently the count for the documents table tabs do not display the
correct values when the period filter is applied.
## Changes Made
- Updated `getStats` to support filtering on period
## Testing Performed
- Tested to see if the documents tab count were being filtered based on
the period
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have followed the project's coding style guidelines.
## Description
This pull request solves the problem where the avatar component within
the document list has the same z-index value as the header component,
causing the avatar to be above the header. When two elements have the
same z-index value, the last one takes priority!
## Related Issue
Fixes#870
## Changes Made
1. Increases the value of the header's `z-index` by `10` (the current
value is `50`
## Description
Currently we are required to ensure PII data is not passed around in
search parameters and in the open for GDPR reasons.
Allowing us to encrypt and decrypt values with expiry dates will allow
us to ensure this doesn't happen.
## Changes Made
- Added TPRC router for encryption method
## Testing Performed
- Tested encrypting and decrypting data with and without `expiredAt`
- Tested via directly accessing API and also via trpc in react
components
- Tested parsing en email search param in a page and decrypting it
successfully
## Checklist
- [X] I have tested these changes locally and they work as expected.
- [X] I have followed the project's coding style guidelines.
Extracts the API implementation to a package so we can
potentially reuse it across different applications in the
event that we move off using a Next.js API route.
Additionally tidies up the tokens page and form to be more simplified.
@ -84,16 +73,28 @@ Contact us if you are interested in our Enterprise plan for large organizations
<ahref="https://cal.com/timurercan/enterprise-customers?utm_source=banner&utm_campaign=oss"><imgalt="Book us with Cal.com"src="https://cal.com/book-with-cal-dark.svg"/></a>
You can pull the Docker image from either of these registries and run it with your preferred container hosting provider.
Please note that you will need to provide environment variables for connecting to the database, mailserver, and so forth.
For detailed instructions on how to configure and run the Docker container, please refer to the [Docker README](./docker/README.md) in the `docker` directory.
4. You will be prompted to enter a password for the p12 file. Choose a strong password and remember it, as you will need it to use the certificate (**can be empty for dev certificates**)
5. Place the certificate `/apps/web/resources/certificate.p12`
5. Place the certificate `/apps/web/resources/certificate.p12` (If the path does not exist, it needs to be created)
> 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.
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.
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, I’m 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 document’s owner becomes active. Booking links (e.g., Cal.com) and customer self-service portals (e.g., Stripe Billing Portal) are becoming the norm, so it’s 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).
Don’t 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.
title: 'Building Documenso — Part 1: Certificates'
description: In today's fast-paced world, productivity and efficiency are crucial for success, both in personal and professional endeavors. We all strive to make the most of our time and energy to achieve our goals effectively. However, it's not always easy to stay on track and maintain peak performance. In this blog post, we'll explore 10 valuable tips to help you boost productivity and efficiency in your daily life.
description: Let's take a look why you need a signing certificate and how Documenso does it.
title: 'Building Documenso — Part 2: Signature Validity'
description: Is a signature valid? And what does that mean? It's a surprisingly complex question; let's take a look.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-04-05
tags:
- Document Signature
- Certificates
- Signing
---
<figure>
<MdxNextImage
src="/blog/eu-validate-1.png"
width= "650"
height= "650"
alt= "A report card for signature validity."
/>
<figcaption className="text-center">
If a tree does not comply with the EU trust list, does it make a sound when validating?r
</figcaption>
</figure>
> TLDR; Signatures can be valid and compliant for different signature levels, even if some validators show higher-level errors. Not all helpful security measures are mandated by law.
# A valid question
A few days ago, an early adopter brought up this question in our [Discord](https://documen.so/discord):
<figure>
<MdxNextImage
src="/blog/eu-validate-2.png"
width= "650"
height= "650"
alt= "A report card for signature validity."
/>
<figcaption className="text-center">
You can check out the validator here: [https://documen.so/eu-validator](https://documen.so/eu-validator)
</figcaption>
</figure>
For those unfamiliar with the tool, he used the validator tool of the EU's Digital Signature Service (DSS) Framework to check the signature of a document signed with Documenso. The EU provides this tool to help users and providers check the validity level of their signatures.
A short refresher from [Building Documenso — Part 1: Certificates](https://documen.so/certs):
> Documenso inserts all visual signatures into the document and then seals it using the "Documenso Inc." corporate certificate. This makes the resulting PDF document tamper-proof and guarantees it hasn't changed since signing.
Before we answer if the document was signed correctly, we need to understand what the goal was.
There are three signature levels in the European eIDAS regulation:
1. **Simple Electronic Signatures (Level 1/ SES):** This is just a visual signature or even a checkbox on a document.
2. **Advanded Electronic Signatures (Level 2/ AES)**: An actual crypographic signature (not just a seal on the whole document, but a specific signature), using a certificate linked to the identification data of the signer.
3. **Qualified Electronic Signatures (Level 3/ QES):** Same as 2. but done by a government-certified entity on certified hardware and after identifying the signer with an official ID document (e.g., passport)
> 💡 Side Note: Number 2 (AES) is how most people imagine digital signatures. But most of the market uses 1. plus a seal on the whole document under the name of the signing provider (e.g., Documenso). The signer's data is only inserted visually, not in the actual signature. Why? One of the reasons is that it's much easier, and without a readily available open source framework to draw from, it is quite tricky to build. This is something we aim to build (which many have done) and open source (which no one has done).
From the perspective of eIDAS, Documenso offers Level 1/ SES signatures since it does not adhere to all of the requirements of Level 2/ AES. This means that, technically, there is no legal need to seal the document to achieve this level of validity (at least within eIDAS). We do it anyway since it improves the level of confidence users can have in the signed document. Sealing the document, even though not legally required, is a great example of Documenso's approach to signatures. First, we aim to provide all legal requirements for a given use case. Then, we add any protection that can be added without unwarranted friction to the creation of the signature.
## Not if valid, but how valid
**Q: So, is the signature in the image valid?**
A: Yes, as an eidas Level 1 SES.
**Q: Then why does it say "Unable to build a certificate chain up to a trusted list"**
A: The certificate we use to seal the document after inserting the signatures is not on the EU Trust list.
**Q: Does that mean it is less secure?**
A: No, it means the provider (Wisekey) is not on a list maintained by the EU. The cryptographic signature is just as strong as any other
For someone who does not deal with this stuff daily, this can be hard to comprehend. Whether you use a certificate you generated yourself, one generated by a certificate authority (CA) like Wisekey, or one by another on the EU trust list (e.g., Bundesdruckerei), the cryptographic security guaranteeing that the document has not been tampered with is always the same. Many providers like Documenso, DocuSign, PandaDoc, and Digisigner all use this method for their regular plans. That means if you were to run a document signed by them through the validator above, the result would be the same[1]. The interesting question is why? Why do it like this?
## Certificate Infrastructure is broken
While there are some actual expenses involved in providing AES and QES, the blunt reality is that it's just good business to charge for them per signature, making it unsuitable for the "standard offerings"; almost no one has the resources to set this up themselves. While this initial process of becoming a QES-certified entity is really expensive, selling the certificates afterward is very lucrative. This leads to less innovation in the space and only big players providing these high-compliance services. Even certificates only used to seal documents without being QES certified are sold for a large range of prices, and they cost almost nothing to produce.
## Why Though?
**Q: Why do people buy a certificate for money and not just generate one themselves? Isn't the cryptographic security the same?**
A: Self-generated certificates are not recognized for higher-level compliance signatures like QES
**Q: So if you don't need higher-level signatures, you could just generate one yourself?**
A: Yes, you could. Since eIDAS Level 1 does not require a cert, you could use your own.
**Q: Why don't more people?**
A: One reason is that apart from the EU trust list, there are others, like the Adobe trust list. While not legally required, being on that one (like Wisekey) gives you a green checkmark in Adobe PDF, which is how most people check signature validity.
**Q: Not a question, but all of this sounds weird**
A: It is. This is one of the reasons why Documenso exists. We plan to make this easier.
**Q: How?**
A: By explaining and providing easy-to-use tools and eventually free, highly compliant signature certificates for everyone.
Eventually, we plan to start a free certificate authority called Let's Sign, named after another instituion that broke the paid certificate paradigm to the benefit of the internet: [Let's Encrypt](https://letsencrypt.org/).
As always, feel free to connect on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments.
Best from Hamburg\
Timur
\
\
\
[1] The signature format (e.g. PKCS7-B) will vary. It's the format what the signature inserted into the document looks like. eIDAS itself does not specifically require any given format, but the PAdES defined by the EU is mostly used by european providers.
description: We are creating signing as a public good and are commoditizing it to make it cheaper and better.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-01-25
tags:
- Vision
- Mission
- Open Source
---
<figure>
<MdxNextImage
src="/blog/lighthouse.jpeg"
width="650"
height="650"
alt="A lighthouse on a tiny island."
/>
<figcaption className="text-center">
Lighthouses are often used as an example of a public good; As they benefit all maritime users, but no one can be excluded from using them as a navigational aid. Use by one person neither prevents access by other people, nor does it reduce availability to others.
</figcaption>
</figure>
# Commodifying Signing
> TLDR; We are creating signing as a public good and are commoditizing it to make it cheaper and better.
While we are in full-on building mode with Documenso, I think a lot about the big picture of what we are attempting to do. One phrase that keeps popping up is, "We are commodifying signing." Let's dig deeper into what that means.
Let's start with why we are doing this. Documenso's mission is to solve the domain of signing once and for all for everyone. In so many calls, I hear stories about how organizations build their own solution because the existing ones are too expensive or need to be more flexible. That means not hundreds but probably thousands of companies worldwide have done the same. This is simply wasting humanity's time. Since digital signing systems are understood well enough that seemingly "everyone" can build them, given enough pain, It's time to do it once correctly.
## Is signing already a commodity?
> In economics, a **commodity** is an economic good, usually a resource, that has explicitly full or substantial fungibility: that is, the market treats instances of the good as equivalent or nearly so with no regard to who produced them.
That sounds like the signing market today. There is no shortage of signing providers, and you can get similar signing services from many places. So why is this different from what we want, and why does this not satisfy the market?
- Signing is expensive and painful when you are locked into your vendor, and they charge by signing volume.
- Signing is also expensive and painful when you have to build it yourself since no vendor fits your requirements or you are not allowed to
To understand why, we need to look at the landscape as it is today:
- **Public Goods**: Web Tech, Digital Signature Algorithms and Standards
What the current players have done is to commodify the listed public goods into commercial products:
> […]the action and process of transforming goods, services, ideas, nature, personal information, people, or animals into commodities.
> (Let's ignore the end of that list for now and what it says about humanity, yikes)
While this paradigm brought digital signing to many businesses worldwide, we aim for a different future. To solve signing once and for all, we need to achieve two core points:
- Making it cheaper so it's profitable for everyone to use
- Making it more accessible so everyone can use it (e.g. regulated industries) and flexible enough (extendable, open).
To achieve this, we must transform the landscape to look like this:
- **Public Goods**: (no longer private): OS (Open Source) Signing Code Base, OS Regulatory Know-How
- **Public Goods**: OS Web Tech, Digital Signature Algorithms and Standards
## Raising the Bar
Before creating a commodity, we are raising the bar of what the underlying public good is. Having an open source singing framework you can extend, self-host, and understand makes the resulting solution much more accessible and extendable for everyone. Now for the final feat of making signing cheaper:
As we have seen, signing has already been commodified. But since it was done by a closed source and, frankly, a very opaque industry, no downward price spiral has ensued. By building Documenso open source with an open culture, we can pierce the veil and trigger what the space has been missing for a long time: Commoditization. If you had to read that again, so did I:
> In business literature, **commoditization** is defined as the process by which goods that have economic value and are distinguishable in terms of attributes (uniqueness or brand) become simple commodities in the eyes of the market or consumers.
By only selling what creates value for the customer (hosting a highly available service, keeping it compliant, supporting with technical issues and challenges, preparing industry-specific components), we are commoditizing signing since everyone can do it now: The resources enabling it are public goods, aka. open source. A leveled playing field, as described above, is the perfect environment for a community-first, technology-first, and value-first company like Documenso to flourish.
## Changing the Game
In this new world, a company needing signing (literally every company) can decide if the ROI (Return on Investment) of building signing themselves is greater than simply paying for the value-added activities they will need anyway. Pricing our offering not on volume but fixed is a nice additional wedge into the market we intend to use here.
The market dynamic now changes to who can offer the greatest value added to the public goods, driving the price down as this can be done much more efficiently than locking customers into closed source SaaS. Documenso, being a lean company, which we intend to stay with for a long time, will help kickstart this effect. Open Source capital efficiency is real. Our planned enterprise components, hosting support, and partner ecosystem will all leverage this effect.
We will grow our community around the public good, the open-source repo, and create an ecosystem around the commodities built on top of it (components, hosting, compliance, support). We will solve signing once and for all, and the world will be better for it. Onwards.
As always, feel free to connect on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments.
> 🔔 UPDATE: We launched <a href="https://documen.so/day1" target="_blank">teams</a> and the early adopters plan will be replaced by the new teams pricing as soon as all availible early adopters seats are filled.
## Community-Driven Development
As we ramp up hiring and development speed for Documenso, I want to discuss how we plan to build its core version.
title: How Documenso Enhances Contract Management for Freelancers, Helping Them Close More Clients Efficiently
description: Making it easy for the customer to sign the contract after they say yes is critical. Let take a look how Documenso can help.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-06-20
tags:
- Freelancer
- Proposal
- Productivity
---
## Yes to Yes
> [Check out Part 1](https://documen.so/freelance-proposal) to learn about signing freelance proposals with Documenso and getting your first yes
A basic rule of sales is going from "yes to yes”. Outlining the main points of working together in a proposal is a good way to get to your first yes since it reduces details and focuses on the main points of the work at hand. After being on the same page about the work and getting the first yes, it's time to draw up a formal contract. While agreeing to the proposal has some weight as well, the legal contract formalizes the commitments of both sides in an enforceable way. Having clear legal terms on payments, unexpected cases, and even dissolving the partnership helps both parties to feel assured about what to expect.
### **Digital Signatures for the Win**
Digitally signing documents accelerates contract closure, enhancing both speed and security. Parties can review and sign documents within minutes, eliminating the days required for manual signatures or even weeks with traditional mail. Beyond these efficiency gains, digital signatures boost trust by making the process secure and auditable. Once signed, digital documents are immutable, and every step is logged.
Documenso simplifies this process, allowing you to send contracts effortlessly. As an open-source solution, our product's integrity and security are verifiable by anyone, which is why thousands of users rely on Documenso for their signing needs. Discover more at [https://documen.so/open](https://documen.so/open).
## Preparing the Contract
As a freelancer, obtaining a contract template ensures you have a standardized and professional agreement ready for new clients, helping to protect your interests and clarify project terms. While there are many good templates out there, be sure to verify that they fit your case since contracts are often very specific to a certain case. Always consider having your contract checked by a legal professional if it's a high-value transaction.
Here is a quick checklist of what your contract should include:
### Checklist
- Names and Addresses of you and your client
- Scope of Work to be performed, deadlines and deliverables
- Payment Terms, Payment Schedules, and Pricing
- A clear timeline
- Provisions for unexpected extra work
- Intellectual Property Rights Provisions
- Confidentiality and Non-Disclosure Agreements, if needed
- Termination Clauses: Condition and terms when the contract can be terminated, including notice period and compensation
- Indemnity and Liability
- Dispute Resolution
- Provisions ensuring changes can only be made in writing
- Completeness Agreement: Both parties state this is the full extent of the agreement
- Severability Clause ensuring minor errors will not endanger the whole contract
- The signees with name, role, and date
## Getting the Signature
Once you have your contract ready, you can upload it and add recipients and signature fields. To add a more personal touch, consider adding a personal message to the signature request.
<figure>
<MdxNextImage
src="/blog/l1.png"
width="1260"
height="630"
alt="Manually Copy Signature Link by Hovering of the Recipient"
/>
<figcaption className="text-center">
Copy recipient links to send them for a personal touch manually.
</figcaption>
</figure>
You can also copy the link for each recipient after sending it and send it via another channel e.g. WhatsApp with a personal message. To further customize the experience, you can define a redirect when your customer signs the contract to redirect them to a Cal.com Link to get started, a Thank You Page, or a Form.
<figure>
<MdxNextImage
src="/blog/l2.png"
width="1260"
height="630"
alt="Redirect Link in Advanced Settings"
/>
<figcaption className="text-center">
Redirect after Signing for a more personal experience.
</figcaption>
</figure>
The more you add to the workflow, the more important it is to keep up to date with the process. Using Zapier, you can add a variety of notifications, from email to Discord messages, to keep a good overview and respond quickly. It's not just about getting the signatures; it's about creating the workflow that provides the best experience for you and your customers.
<figure>
<MdxNextImage
src="/blog/l3.png"
width="1260"
height="630"
alt="Zapier Documenso Discord Integration"
/>
<figcaption className="text-center">
Trigger any kind of notification with[Zapier](https://documen.so/zapier)
</figcaption>
</figure>
### Conclusion
Sending a contract to clients using Documenso makes the process fast and easy. Seeing if your contract was signed or even read helps you understand where you are in the process. You can use the [Documenso Free Plan](https://app.documenso.com/signup?utm_source=blog-freelancer-contract) to send 5 contracts per month. Digital signing in 2024 is the best practice for professionals seeking the most efficient way to get business done.
Let us know what you think and what we can improve. Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here and would love to hear from you :)
title: How Documenso Helps Freelancers Close More Clients Efficiently
description: Reducing friction when sending proposals is critical to closing new clients. By using Documenso, freelancers can save time, enhance client interactions, and ultimately close more deals efficiently.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-06-14
tags:
- Freelancer
- Proposal
- Productivity
---
Getting new clients, or maybe even your first client, to sign with you is at the very core of freelance work. Whether you develop software, create designs, or market products, it all starts with a signature from you and your future customer. Closing a customer usually means agreeing on a proposal first and then signing a formal agreement afterward. Signing proposals and contracts is fast, easy, and painless with Documenso, so let's take a look.
## Understanding Proposal and Contracts
### 1. Initial Proposal
> Agreeing on what needs to be done and terms for payment
A proposal will include the scope of the work (what does the customer want done?), desired deliverables (documents, code, features, videos, etc.), timelines, payment terms (one-time, monthly, per hour), and prices (e.g. $60/ hour, $5k one-time). A proposal is important for both sides to be clear about the goal and the terms that apply. Customers usually decide based on the proposal if your offer is what they want.
### 2. Formal Contract
> After the client signs the proposal, a contract can be signed, formalizing the agreement and adding detailed legal terms.
Once the terms are agreed upon, a more formal document should specify the terms of working together, especially legal details such as confidentiality, indemnification, governing law, etc. The contract provides clarity on legal details for both sides and formalizes their claims.
Sending one or even multiple documents to a potential client and having them send them back signed (in the worst case, they send it via actual mail) is time-consuming for both sides. It also introduces friction at a time when making it as easy as possible for your potential client to say yes should be your number one goal.
### **Digital Signatures for the Win**
Signing documents digitally makes closing proposals and contracts faster and more secure. Each party can review and sign the documents in minutes instead of days (inserting the signatures manually via PDF editor) or even weeks (using conventional mail). Apart from the efficiency gains, signing digitally also increases trust by making the process more secure and auditable. Digitally signed documents can’t be changed after the fact, and every step of the process is logged.
Documenso lets you reap these benefits by sending proposals and contracts with minimal effort. Being open source, the whole world can verify our product and how we deliver on these promises, which is why thousands of users already trust Documenso for their signing needs: [https://documen.so/open](https://documen.so/open).
## Preparing the Proposal
If you already have a proposal template, create a new version for your client and export it to PDF. If your tool doesn’t support that, your system's “PDF printer” lets you create a PDF from almost any tool by using the print function. If you do not have a template yet, you can find a lot of content and guides on the matter through a quick Google search. Here is a quick checklist of what your proposal should cover:
- A clear and concise title
- Your contact information
- Date of the proposal/ validity period
- Experience, qualifications, and prior relevant projects
- A summary of the project
- A detailed description of the project
- Goals, outcomes, and deliverables
- Tasks and activities to achieve the goals and outcomes
- A timeline with milestones and deadlines
- Pricing terms and payment schedule
- Summary of major terms for the coming contract
## Sending the Proposal
If you don’t have a Documenso Account yet, you can [create one for free](https://documen.so/signup?utm_source=blog-freelancer-proposal). Once you sign up, you can upload your proposal PDF by simply dragging it into the upload area. Add your potential client as a recipient, add a signature field, and you are done! You can track the status of your proposal simply by clicking the Document in the overview. Documenso will also notify you once the proposal is signed.
Sending a proposal to potential clients using Documenso makes getting to the first “yes” fast and easy. Seeing if your proposal was signed or even read helps you to get a feel for where you are in the process. You can use the [Documenso Free Plan](https://app.documenso.com/signup?utm_source=blog-freelancer-proposal) to send 5 proposals per month. Digital Signing in 2024 is the best practice for all professionals looking for the most efficient way to get business done.
> [Check out Part 2](https://documen.so/freelance-contract) to learn about signing freelance contracts with Documenso.
Let us know what you think and what we can improve. Which field types are you missing? Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here and would love to hear from you :)
> TLDR; Docucmenso now supports teams that share documents, templates and a team mail address. Early Adopter get UNLIMITED<sup>1</sup> Users.
## Kicking off Launch Week II - "Connected"
The day has come! Roughly 5 months after kicked off our first launch week with open sourcing our design and Malfunction Mania, Launch Week #2 is here 🎉 This Launch Week's theme is "connected", since this is all about connecting humans, machines and documents.
Working with documents and getting that signature is a team sport. This is why we are kicking it off today with a very long-awaited feature: Documenso now supports teams!
## Introducing Teams for Documenso
You can now create teams next to your personal account: Simply invite your colleagues, and you can include everyone you like in working with your documents. With teams, you can:
- Send unlimited signature requests with unlimited recipients
- Create, view, edit and sign documents owned by the team
- Define a dedicated team email, to receive signing requests into a team inbox for the owner to sign
- Manage team roles: Member (Create+Edit), Managers (+Manage Team Members), Owner (+Transfer Team +Delete Team + Sign Documents sent to team email)
## Pricing
Together with Teams, we are announcing the new teams pricing:
- $10 per seat per month
- 5 seats minimum
- You can add seats dynamically as needed
This pricing will take effect, as soon as the early adopter seats run out. Want to check out teams: [https://documen.so/teams](https://documen.so/teams).
## Early Adopter Perks
There is one more point on pricing I have been looking forward to for a long time:
All early adopter plans now include **UNLIMITED teams and users**<sup>1</sup> . We appreciate your support so far very much, and I'm happy to announce this first of more early adopter perks to come. We have roughly 48 early adopter plans left, so if you plan to onboard your team, now is a great time to [grab your early adopter seat.](https://documen.so/claim-early-adopters-plan)
We are eager to hear from all teams users how you like this addition and what we can add to make it even better. Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here, and we would love to hear from you :)
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 1! Teams just dropped. Check it out https://documen.so/day1 🚀"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
Best from Hamburg\
Timur
\
[1] Within reason. If you are unsure what that means, feel free to contact hi@documenso.com and ask for clarification if it's more than 100.
> TLDR; You can now reuse documents via templates. More field types coming soon as well.
## Introducing Templates
It's day 2 of Launch Week, everybody 🙌 After introducing [Teams](https://documenso.com/blog/launch-week-2-day-1) yesterday, today we are looking at making Documenso faster for daily use:
We are launching templates for Documenso! Templates are an easy way to reuse documents you send out often with just a few clicks. With templates, you can:
<figure>
<MdxNextImage
src="/blog/quickfill.png"
width="1260"
height="630"
alt="Template recipients quick fill view"
/>
<figcaption className="text-center">
Quickly fill out recipients, when creating from a template
</figcaption>
</figure>
- Save often-uploaded documents for reuse
- Pre-define fields, so you just have to send the document
- Quickly fill out recipients and roles for new documents
- Share templates with your team to make working together even easier
<figure>
<MdxNextImage
src="/blog/template.png"
width="1260"
height="630"
alt="Create from template view"
/>
<figcaption className="text-center">
POV: You are a diligent german and create custom receipts with Documenso
</figcaption>
</figure>
## Pricing
Templates are **included in all Documenso Plans!** That includes our free tier: The limit of 5 documents per month still applies, but you are free to reach it with less friction using templates. Sharing templates with other users is only possible with the teams plan. If you want to share templates with people not in your team, we might have something coming up later this week 👀
## What's Next for Templates
We have a lot of great stuff coming up for templates as well:
- More Field Types are in the pipeline
- Sharing Templates Externally 👀
Check out templates [here](https://documen.so/templates) and let us know what you think and what we can improve. Which field types are you missing? Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here and would love to hear from you :)
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 2! They just launched templates, and I'm pumped 🎉🚀🚀🚀. Check it out https://documen.so/day2"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
description: Documenso's mission is to create a plattform developers all around the world can build upon. Today we are releasing the first version of our public API, included in all plans!
> TLDR; The public API is now availible for all plans.
## Introducing the public Documenso API
Launch. Week. Day. 3 🎉 Documenso's mission is to create a platform that developers all around the world can build upon. Today we are releasing the first version of our public API, and we are pumped. Since this is the first version, we focused on the basics. With the new API you can:
- Get Documents (Individual or all Accessible)
- Upload Documents
- Delete Documents
- Create Documents from Templates
- Trigger Sending Documents for Singing
You can check out the detailed API documentation here:
> API DOCUMENTATION: [https://app.documenso.com/api/v1/openapi](https://app.documenso.com/api/v1/openapi)
## Pricing
We are building Documenso to be an open and extendable platform; therefore the API is included in all current plans. The API is authenticated via auth tokens, which every user can create at no extra cost, as can teams. Existing limits still apply (i.e., the number of included documents for the free plan). While we don't have all the details yet, we don't intend to price the API usage in itself (rather the accounts using it) since we want you to build on Documenso without being smothered by API costs.
> Try the API here for free: [https://documen.so/api](https://documen.so/api)
## What's next for the API
You tell us. This is by far the most requested feature, so we would like to hear from you. What should we add? How can we integrate even better?
Connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here and would love to hear from you :)
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 3! The public API is here 👀 Check it out https://documen.so/day3"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
title: Launch Week II - Day 4 - Webhooks and Zapier
description: If you want to integrate Documenso without fiddling with the API, we got you as well. You can now integrate Documenso via Zapier, included in all plans!
> TLDR; Zapier Integration is now available for all plans.
## Introducing Zapier for Documenso
Day 4 🥳 Yesterday we introduced our [public API](https://documen.so/day3) for developers to build on Documenso. If you are not a developer or simple want a quicker integration this is for you: Documenso now support Zapier Integrations! Just connect your Documenso account via a simple login flow with Zapier and you will have access to Zapier's universe of integrations 💫 The integration currently supports:
- Document Created ([https://documen.so/zapier-created](https://documen.so/zapier-created))
- Document Sent ([Chttps://documen.so/zapier-sent](https://documen.so/zapier-sent))
- Document Opened ([https://documen.so/zapier-opened](https://documen.so/zapier-opened))
- Document Signed ([https://documen.so/zapier-signed](https://documen.so/zapier-signed))
> ⚡️ You can create your own Zaps here: https://zapier.com/apps/documenso/integrations
Each event comes with extensive meta-data for you to use in Zapier. Missing something? Reach out on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord). We're always here and would love to hear from you :)
## Also Introducing for Documenso: Webhooks
To build the Zapier Integration, we needed a good webhooks concept, so we added that as well. Together with your Zaps, you can also now create customer webhooks in Documenso. You can try webhooks here for free: [https://documen.so/webhooks](https://documen.so/webhooks)
<figure>
<MdxNextImage
src="/blog/hooks.png"
width="1260"
height="630"
alt="Webhooks UI"
/>
<figcaption className="text-center">
Create unlimited custom webhooks with each plan.
</figcaption>
</figure>
## Pricing
Just like the API, we consider the Zapier integration and webhooks part of the open Documenso platform. Zapier is **available for all Documenso plans**, including free! [Login now](https://documen.so/login) to check it out.
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 4! Documenso now supports @Zapier 🤯 https://documen.so/day4"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
title: Launch Week II - Day 5 - Documenso Profiles
description: Documenso profiles allow you to send signing links to people so they can sign anytime and see who you are. Documenso Profile Usernames can be claimed starting today. Long ones free, short ones paid. Profiles will launch as soon as they are shiny.
> TLDR; Documenso profiles allow you to send signing links to people so they can sign anytime and see who you are. Documenso Profile Usernames can be claimed starting today. Long ones free, short ones paid. Profiles launch as soon as they are shiny.
## Introducing Documenso Profile Links
Day 5 - The Finale 🔥
Signing documents has always been between humans, and signing something together should be as frictionless as possible. It should also be async, so you don't force your counterpart to jog to their device to send something when you are ready. Today we are announcing the new Documenso Profiles:
<figure>
<MdxNextImage
src="/blog/profile.png"
width="1260"
height="813"
alt="Timur's Documenso Profile"
/>
<figcaption className="text-center">
Async > Sync: Add public templates to your Documenso Link and let people sign whenever they are ready.
</figcaption>
</figure>
Documenso profiles work with your existing templates. You can just add them to your public profile to let everyone with your link sign them. With profiles, we want to bring back the human aspect of signing.
By making profiles public, you can always access what your counterparty offers and make them more visible in the process. Long-term, we plan to add more to profiles to help you ensure the person you are dealing with is who they claim to be. Documenso wants to be the trust layer of the internet, and we want to start at the very fundamental level: The individual transaction.
Profiles are our first step towards bringing more trust into everything, simply by making the use of signing more frictionless. As there is more and more content of questionable origin out there, we want to support you in making it clear what you send out and what not.
## Pricing and Claiming
Documenso profile username can be claimed starting today. Documenso profiles will launch as soon as we are happy with the details ✨
- Long usernames (6 characters or more) come free with every account, e.g. **documenso.com/u/timurercan**
- Short usernames (5 characters or fewer) or less require any paid account ([Early Adopter](https://documen.so/claim-early-adopters-plan), [Teams](https://documen.so/teams) or Enterprise): **e.g., documenso.com/u/timur**
You can claim your username here: [https://documen.so/claim](https://documen.so/claim)
> 🚨 We need you help to help us to make this the biggest launch week yet: <a href="https://twitter.com/intent/tweet?text=It's @Documenso Launch Week Day 5! You can now claim your username for the upcoming profile links 😮 https://documen.so/day5"> Support us on Twitter </a> or anywhere to spread awareness for open signing! The best posts will receive merch codes 👀
@ -109,7 +109,7 @@ It's similar to the Kanban board for the development backlog.
While the internal design backlog also existed in Linear, the public design repository is new. Since designing in the open is tricky, we opted to publish the detailed design artifacts with the corresponding feature instead.
We already have design.documenso.com housing our general design system. Here, we will publish the specifics of how we applied this to each feature. We will publish the first artifacts here soon, what may be in the cards can be found on the [LIVE Roadmap](https://documen.so/live).
Feel free to connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here to help and would love to hear from you :)
Feel free to connect with us on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions or comments! We're always here to help and would love to hear from you :)
title: 'Building the Documenso Public API - The Why and How'
description: 'This article talks about the need for the public API and the process of building it. It also discusses the requirements we had to meet and the constraints we had to work within.'
authorName: 'Catalin'
authorImage: '/blog/blog-author-catalin.webp'
authorRole: 'I like to code and write'
date: 2024-03-08
tags:
- Development
- API
---
This article covers the process of building the public API for Documenso. It starts by explaining why the API was needed for a digital document signing company in the first place. Then, it'll dive into the steps we took to build it. Lastly, it'll present the requirements we had to meet and the constraints we had to work within.
## Why the public API
We decided to build the public API to open a new way of interacting with Documenso. While the web app does the job well, there are use cases where it's not enough. In those cases, the users might want to interact with the platform programmatically. Usually, that's for integrating Documenso with other applications.
With the new public API that's now possible. You can integrate Documenso's functionalities within other applications to automate tasks, create custom solutions, and build custom workflows, to name just a few.
The API provides 12 endpoints at the time of writing this article:
- (GET) `/api/v1/documents` - retrieve all the documents
- (POST) `/api/v1/documents` - upload a new document and getting a presigned URL
- (GET) `/api/v1/documents/{id}` - fetch a specific document
- (DELETE) `/api/v1/documents/{id}` - delete a specific document
- (POST) `/api/v1/templates/{templateId}/create-document` - create a new document from an existing template
- (POST) `/api/v1/documents/{id}/send` - send a document for signing
- (POST) `/api/v1/documents/{id}/recipients` - create a document recipient
- (PATCH) `/api/v1/documents/{id}/recipients/{recipientId}` - update the details of a document recipient
- (DELETE) `/api/v1/documents/{id}/recipients/{recipientId}` - delete a specific recipient from a document
- (POST) `/api/v1/documents/{id}/fields` - create a field for a document
- (PATCH) `/api/v1/documents/{id}/fields` - update the details of a document field
- (DELETE) `/api/v1/documents/{id}/fields` - delete a field from a document
> Check out the [API documentation](https://app.documenso.com/api/v1/openapi).
Moreover, it also enables us to enhance the platform by bringing other integrations to Documenso, such as Zapier.
In conclusion, the new public API extends Documenso's capabilities, provides more flexibility for users, and opens up a broader world of possibilities.
## Picking the right approach & tech
Once we decided to build the API, we had to choose the approach and technologies to use. There were 2 options:
1. Build an additional application
2. Launch the API in the existing codebase
### 1. Build an additional application
That would mean creating a new codebase and building the API from scratch. Having a separate app for the API would result in benefits such as:
- lower latency responses
- supporting larger field uploads
- separation between the apps (Documenso and the API)
- customizability and flexibility
- easier testing and debugging
This approach has significant benefits. However, one major drawback is that it requires additional resources.
We'd have to spend a lot of time just on the core stuff, such as building and configuring the basic server. After that, we'd spend time implementing the endpoints and authorization, among other things. When the building is done, there will be another application to deploy and manage. All of this would stretch our already limited resources.
So, we asked ourselves if there is another way of doing it without sacrificing the API quality and the developer experience.
### 2. Launch the API in the existing codebase
The other option was to launch the API in the existing codebase. Rather than writing everything from scratch, we could use most of our existing code.
Since we're using tRPC for our internal API (backend), we looked for solutions that work well with tRPC. We narrowed down the choices to:
Both technologies allow you to build public APIs. The `trpc-openapi` technology allows you to easily turn tRPC procedures into REST endpoints. It's more like a plugin for tRPC.
On the other hand, `ts-rest` is more of a standalone solution. `ts-rest` enables you to create a contract for the API, which can be used both on the client and server. You can consume and implement the contract in your application, thus providing end-to-end type safety and RPC-like client.
> You can see a [comparison between trpc-openapi and ts-rest](https://catalins.tech/public-api-trpc/) here.
So, the main difference between the 2 is that `trpc-openapi` is like a plugin that extends tRPC's capabilities, whereas `ts-rest` provides the tools for building a standalone API.
### Our choice
After analyzing and comparing the 2 options, we decided to go with `ts-rest` because of its benefits. Here's a paragraph from the `ts-rest` documentation that hits the nail on the head:
> tRPC has many plugins to solve this issue by mapping the API implementation to a REST-like API, however, these approaches are often a bit clunky and reduce the safety of the system overall, ts-rest does this heavy lifting in the client and server implementations rather than requiring a second layer of abstraction and API endpoint(s) to be defined.
## API Requirements
We defined the following requirements for the API:
- The API should use path-based versioning (e.g. `/v1`)
- The system should use bearer tokens for API authentication
- The API token should be a random string of 32 to 40 characters
- The system should hash the token and store the hashed value
- The system should only display the API token when it's created
- The API should have self-generated documentation like Swagger
- Users should be able to create an API key
- Users should be able to choose a token name
- Users should be able to choose an expiration date for the token
- User should be able to choose between 7 days, 1 month, 3 months, 6 months, 12 months, never
- System should display all the user's tokens in the settings page
- System should display the token name, creation date, expiration date and a delete button
- Users should be able to delete an API key
- Users should be able to retrieve all the documents from their account
- Users should be able to upload a new document
- Users should receive an S3 pre-signed URL after a successful upload
- Users should be able to retrieve a specific document from their account by its id
- Users should be able to delete a specific document from their account by its id
- Users should be able to create a new document from an existing document template
- Users should be able to send a document for signing to 1 or more recipients
- Users should be able to create a recipient for a document
- Users should be able to update the details of a recipient
- Users should be able to delete a recipient from a document
- Users should be able to create a field (e.g. signature, email, name, date) for a document
- Users should be able to update a field for a document
- Users should be able to delete a field from a document
## Constraints
We also faced the following constraints while developing the API:
**1. Resources**
Limited resources were one of the main constraints. We're a new startup with a relatively small team. Building and maintaining an additional application would strain our limited resources.
**2. Technology stack**
Another constraint was the technology stack. Our tech stack includes TypeScript, Prisma, and tRPC, among others. We also use Vercel for hosting.
As a result, we wanted to use technologies we are comfortable with. This allowed us to leverage our existing knowledge and ensured consistency across our applications.
Using familiar technologies also meant we could develop the API faster, as we didn't have to spend time learning new technologies. We could also leverage existing code and tools used in our main application.
It's worth mentioning that this is not a permanent decision. We're open to moving the API to another codebase/tech stack when it makes sense (e.g. API is heavily used and needs better performance).
**3. File uploads**
Due to our current architecture, we support file uploads with a maximum size of 50 MB. To circumvent this, we created an additional step for uploading documents.
Users make a POST request to the `/api/v1/documents` endpoint and the API responds with an S3 pre-signed URL. The users then make a 2nd request to the pre-signed URL with their document.
## How we built the API

Our codebase is a monorepo, so we created a new API package in the `packages` directory. It contains both the API implementation and its documentation. The main 2 blocks of the implementation consist of the API contract and the code for the API endpoints.
In a few words, the API contract defines the API structure, the format of the requests and responses, how to authenticate API calls, the available endpoints and their associated HTTP verbs. You can explore the [API contract](https://github.com/documenso/documenso/blob/main/packages/api/v1/contract.ts) on GitHub.
Then, there's the implementation part, which is the actual code for each endpoint defined in the API contract. The implementation is where the API contract is brought to life and made functional.
Let's take the endpoint `/api/v1/documents` as an example.
```ts
export const ApiContractV1 = c.router(
{
getDocuments: {
method: 'GET',
path: '/api/v1/documents',
query: ZGetDocumentsQuerySchema,
responses: {
200: ZSuccessfulResponseSchema,
401: ZUnsuccessfulResponseSchema,
404: ZUnsuccessfulResponseSchema,
},
summary: 'Get all documents',
},
...
}
);
```
The API contract specifies the following things for `getDocuments`:
- the allowed HTTP request method is GET, so trying to make a POST request, for example, results in an error
- the path is `/api/v1/documents`
- the query parameters the user can pass with the request
- in this case - `page` and `perPage`
- the allowed responses and their schema
- `200` returns an object containing an array of all documents and a field `totalPages`, which is self-explanatory
- `401` returns an object with a message such as "Unauthorized"
- `404` returns an object with a message such as "Not found"
The implementation of this endpoint needs to match the contract completely; otherwise, `ts-rest` will complain, and your API might not work as intended.
The `getDocuments` function from the `implementation.ts` file runs when the user hits the endpoint.
There is a middleware, too, `authenticatedMiddleware`, that handles the authentication for API requests. It ensures that the API token exists and the token used has the appropriate privileges for the resource it accesses.
That's how the other endpoints work as well. The code differs, but the principles are the same. You can explore the [API implementation](https://github.com/documenso/documenso/blob/main/packages/api/v1/implementation.ts) and the [middleware code](https://github.com/documenso/documenso/blob/main/packages/api/v1/middleware/authenticated.ts) on GitHub.
### Documentation
For the documentation, we decided to use Swagger UI, which automatically generates the documentation from the OpenAPI specification.
The OpenAPI specification describes an API containing the available endpoints and their HTTP request methods, authentication methods, and so on. Its purpose is to help both machines and humans understand the API without having to look at the code.
The Documenso OpenAPI specification is live [here](https://documenso.com/api/v1/openapi.json).
Thankfully, `ts-rest` makes it seamless to generate the OpenAPI specification.
```ts
import { generateOpenApi } from '@ts-rest/open-api';
import { ApiContractV1 } from './contract';
export const OpenAPIV1 = generateOpenApi(
ApiContractV1,
{
info: {
title: 'Documenso API',
version: '1.0.0',
description: 'The Documenso API for retrieving, creating, updating and deleting documents.',
},
},
{
setOperationId: true,
},
);
```
Then, the Swagger UI takes the OpenAPI specification as a prop and generates the documentation. The code below shows the component responsible for generating the documentation.
```ts
'use client';
import SwaggerUI from 'swagger-ui-react';
import 'swagger-ui-react/swagger-ui.css';
import { OpenAPIV1 } from '@documenso/api/v1/openapi';
Lastly, we create an API endpoint to display the Swagger documentation. The code below dynamically imports the `OpenApiDocsPage` component and displays it.
You can access and play around with the documentation at [documenso.com/api/v1/openapi](https://documenso.com/api/v1/openapi). You should see a page like the one shown in the screenshot below.

> This article shows how to [generate Swagger documentation for a Next.js API](https://catalins.tech/generate-swagger-documentation-next-js-api/).
So, that's how we went about building the first iteration of the public API after taking into consideration all the constraints and the current needs. The [GitHub pull request for the API](https://github.com/documenso/documenso/pull/674) is publicly available on GitHub. You can go through it at your own pace.
## Conclusion
The current architecture and approach work well for our current stage and needs. However, as we continue to grow and evolve, our architecture and approach will likely need to adapt. We monitor API usage and performance regularly and collect feedback from users. This enables us to find areas for improvement, understand our users' needs, and make informed decisions about the next steps.
title: 'Embracing the Future and Moving Back Again: From Server Actions to tRPC'
description: 'This article talks about the need for the public API and the process of building it. It also talks about the requirements, constraints, challenges and lessons learnt from building it.'
authorName: 'Lucas Smith'
authorImage: '/blog/blog-author-lucas.png'
authorRole: 'Co-Founder'
date: 2024-03-07
tags:
- Development
---
On October 26, 2022, during the Next.js Conf, Vercel unveiled Next.js 13, introducing a bunch of new features and a whole new paradigm shift for creating Next.js apps.
React Server Components (RSCs) have been known for some time but haven't yet been implemented in a React meta-framework. With Next.js now adding them, the world of server-side rendering React applications was about to change.
## The promise of React Server Components
Described by Vercel as a tool for writing UIs rendered or optionally cached on the server, RSC promised direct integration with databases and server-specific capabilities, a departure from the typical React and SSR models.
This feature initially appeared as a game-changer, promising simpler data fetching and routing, thanks to async server components and additional nested layout support.
After experimenting with it for about six months on other projects, I came to the conclusion that while it was a little rough at the edges, it was indeed a game changer and something that should be adopted in Next.js projects moving forward.
## A new new paradigm: Server Actions
Vercel didn't stop at adding Server Components. A short while after the initial Next.js 13 release, they introduced "Server Actions." Server Actions allow for the calling of server-side functions without API routes, reducing the amount of ceremony required for adding a new mutation or event to your application.
## Betting on new technology
Following the release of both Server Actions and Server Components, we at Documenso embarked on a rewrite of the application. We had accumulated a bit of technical debt from the initial MVP, which was best shed as we also improved the design with help from our new designer.
Having had much success with Server Components on other projects, I opted to go all in on both Server Components and Server Actions for the new version of the application. I was excited to see how much simpler and more efficient the application would be with these new technologies.
Following our relaunch, we felt quite happy with our choices of server actions, which even let us cocktail certain client—and server-side logic into a single component without needing a bunch of effort on our end.
## Navigating challenges with Server Actions
While initially successful, we soon encountered issues with Server Actions, particularly when monitoring the application. Unfortunately, server actions make it much harder to monitor network requests and identify failed server actions since they use the route that they are currently on.
Despite this issue, things were manageable; however, a critical issue arose when the usage of server actions caused bundle corruption, resulting in a top-level await insertion that would cause builds and tests to fail.
This last issue was a deal breaker since it highlighted how much magic we were relying on with server actions. I like to avoid adding more magic where possible since, with bundlers and meta-frameworks, we are already handing off a lot of heavy lifting and getting a lot of magic in return.
## Going all in on tRPC
My quick and final solution to the issues we were facing was to fully embrace [tRPC](https://trpc.io/), which we already used in other app areas. The migration took less than a day and resolved all our issues while adding a lot more visibility to failing actions since they now had a dedicated API route.
For those unfamiliar with tRPC, it is a framework for building end-to-end typesafe APIs with TypeScript and Next.js. It's an awesome library that lets you call your defined API safely within the client, causing build time errors when things inevitably drift.
I've been a big fan of tRPC for some time now, so the decision to drop server actions and instead use more of tRPC was easy for me.
## Lessons learned and the future
While I believe server actions are a great idea, and I'm sure they will be improved in the future, I've relearned the lesson that it's best to avoid magic where possible.
This doesn't mean we won't consider moving certain things back to server actions in the future. But for now, we will wait and watch how others use them and how they evolve.
description: Signing an NDA with Documenso direct links is amazingly fast. Let’s look at how to make it even faster.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-06-27
tags:
- NDA
- Direct Links
- Productivity
---
<figure>
<MdxNextImage
src="/blog/nda.jpg"
width="1400"
height="884"
alt="Direct Links in Templates List View"
/>
<figcaption className="text-center">A generic document saying "NDA" to underline this article is about NDAs.</figcaption>
</figure>
> TLDR; Documenso makes sending NDAs faster, faster with templates, and even still faster using direct links.
## What is an NDA?
An NDA, or non-disclosure agreement, is a legal contract that establishes a confidential relationship. The parties involved agree not to disclose information covered by the agreement. NDAs are often used to protect sensitive information or trade secrets and to ensure that such information isn't made public by the recipient without permission. They are commonly used in business settings, such as during negotiations or when new employees are hired who will have access to proprietary information.
## Do I need an NDA?
> Disclaimer: This is not legal advice, and the most important legal questions are often ultra-case-specific and should be discussed with a legal professional
There is a solid amount of debate around the question of whether an NDA actually protects anyone and is worth the friction. Investors scoff at the idea of a startup requiring them to sign an NDA before disclosing their "billion dollar idea" as they see hundreds of them and are aware that without proper execution, there is nothing to protect.
In another classical example, a big company and a small company e.g. a startup, sign an NDA before going into detail for partnership talks. While this seems prudent, given the resource asymmetry, the startup probably won't be able to litigate against breach of contract successfully. If Microsoft (not saying they do) breaks your NDA, you will hardly sue them into a settlement.
That being said, as with most contracts, NDAs can be useful if both parties keep the spirit of the agreement. In this case, detailing in writing what can and cannot be disclosed is good for managing expectations and building trust. NDAs are also common practice in merger and acquisition projects and are often part of hiring critical roles within a company.
### Level 1: Basic Signing
If you need to sign an NDA, signing it with Documenso is incredibly fast already. Let's take a look at how to make it even faster. Simply uploading and sending is the most straightforward way to get this done. It works like this:
- Upload the NDA PDF template
- Add the recipients
- place the signature fields
- Hit send
- Sign the NDA while or after waiting for your counterpart to sign
If you have to sign the same NDA multiple times with different people, you can create a template to save time. Creating a template is just as easy as creating a document, just skipping the sending step. After creating the template for your NDA, you can create a signable document with just 1 click. Simply fill in the recipient email, and you are done.
> Pro Tip: Check "Send Document" to immediately send it after filling out the recipient if you are familiar with the template.
You can send out templates without even going through the full flow.
</figcaption>
### Level 3: Using a Direct Link
Using a pre-defined template is pretty fast, but can we make it even faster? Yes, we can! By adding a direct link to your NDA template and publishing it (internally or even externally). A [Direct Link](http://documenso.com/blog/announcing-direct-links) lets people sign your NDA without you lifting a finger. Everyone with access to the link can sign it at any time, making discussions of who sends what when a thing of the past. You can use Direct links with a pre-signed template for maximum convenience or with a second signer/ approver from your side to keep control over the process.
You can try it here and [sign a demo NDA](https://documen.so/demo-nda) with me.
> Pro Tip: Use [Zapier](https://documen.so/zapier) to get notified of that platform of your choice as soon as someone signs your link.
## Conclusion
Signing NDAs is not always effective, but it can be necessary, so be sure to use a tool to make it easy and fast. Documenso is a great DocuSign alternative that helps you get it done. If you need to get an NDA out today, you can use the [Documenso Free plan](https://documen.so/free), which gives you 5 signatures per month and 3 Direct Link templates.
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.
description: We reached or Early Adopter cap and not transition to our regular pricing 🎉
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-06-12
tags:
- Early Adopters
- Pricing
- Open Startup
---
<figure>
<MdxNextImage
src="/blog/sunset.jpg"
width="1260"
height="630"
alt="A beautiful sunset as a metaphor for the Early Adopter phase ending"
/>
<figcaption className="text-center">
"Being early is, uh, good." -Unknown
</figcaption>
</figure>
> TLDR; The Early Adopters Plan ended, and we have a new pricing. If you are an Early Adopter, reach out for a Discord community badge 🏅
# The End of the Beginning
12 months, 13 releases, and 344 merged pull requests after announcing the Early Adopter plan in our first-ever launch week, and we hit the cap of 100. Documenso has changed and grown a lot since then. For us, this is a great milestone towards our broader mission of bringing open signing to the world since now we are joined by a community consisting of contributors and early customers all around the world.
# The New Plans
Starting today, we are sunsetting the Early Adopter Plan in favor of our new, more nuanced pricing model. The Early Adopter plan will succeeded by the **Individual plan**, which is still priced at $30/mo. The Individual plans will still include unlimited signatures and recipients since this aligns with our core belief of empowering our users wherever possible. If you managed to grab an Early Adopter plan, reach out on X or Discord to receive a special community badge. Early Adopters are meant to get preferential treatment where possible.
Previously soft-launched as part of Early Adopters, we are officially introducing the **Team Plan** to our pricing for customers requiring multi-user accounts. Priced at $50/ mo. for 5 users, this plan offers unlimited signature volume as well. Additional users can be added for $10/mo. as needed. We have carefully crafted the billing of teams to ensure that dynamic changes are accurately reflected at the end of each billing cycle, providing you with a fair-value pricing structure.
Our **Free Plan** stays unchanged, offering coverage to casual users and an easy way to try out Documenso or start developing.
Check out our [new pricing page here](https://documen.so/pricing). We also updated our [open page](https://documen.so/open) to reflect the end of Early Adopters. The metric now counts active subscriptions from Individuals and Teams.
# API Access
All plans include access to the API as per our philosophy, making Documenso an open platform, and allowing everyone to build on it, no matter how big or small. Besides the Free Plan's 5 signatures per month limit, the API does not have access restrictions. Even the free plan can keep using the API after using its signature volume for non-signing operations like reading, editing, and even creating documents. Since the individual plan technically allows for running a Fortune 500 company for $30/ mo., plan we are adding a fair use clause here: You are free to use the API "a lot" if you are a big organization trying to stay on the Individual Plan we will ask to have a word about upgrading (which might make sense anyway considering your requirements). Fair use excludes Early Adopters, which we consider limitless by any measure. If you need clarification on whether your case is covered under fair use, you can contact us on Discord or support@documenso.com. It's probably fine, though.
We also have a lot in the pipeline, and we are excited to share everything with you soon. A Big Shoutout to all Early Adopters. We salute you, and you will receive the preferred treatment where possible.
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).
title: Top 3 Signing Efficiency Hacks for Freelancers
description: Streamlining signing contracts and paperwork is crucial for freelancers looking to save time and focus on their business. Take a look at these 3 tips on how Documenso can help you.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-07-04
tags:
- Productivity
- Zapier
- Direct Links
---
<figure>
<MdxNextImage
src="/blog/zen.webp"
width="1400"
height="884"
alt="Direct Links in Templates List View"
/>
<figcaption className="text-center">Documenso helps you reduce your cognitive load while running your business.</figcaption>
</figure>
> TLDR; Set up notifications using Zapier, use a redirect to send users to the next step, and start working async with direct links.
Signing all the paperwork of a freelance business can be a headache. Besides adding to the daily workload, it can pull much focus from your core tasks. Let's take a look at how Documenso can help you keep the cognitive load of admin tasks to a minimum:
## Tip 1: Set Up Notifications
> At Documenso, we pipe almost everything relevant into Discord. This helps us naturally keep track and start conversations.
Getting customers and partners to sign off on critical agreements is no easy feat. It's even harder when keeping track forces you to switch between channels (email, WhatsApp, Discord, Slack, Notion, etc.). Setting up custom notifications for read or signed documents can help you keep track naturally. Using the Documenso [Zapier Integration](https://documen.so/zapier) lets you funnel important document events to the place where your focus is. Pipe send, read, and sign notifications directly to your Telegram account. Keep up to date on the go. Sync document completion events to your CRM. Ideally, a signed document does not give you any "homework”. Besides, you are already busy getting started on the actual work.
## Tip 2: Use Redirects
Your client signed the deal? Your designer signed their statement of work? Great. Don't risk losing steam getting from one step to the next. Your customers and partners have just as much noise around them as you. Help them to stay on task by doing the next thing easily. Documenso lets you set up redirects to send signers to where they need to go next. Send your newest customer to a booking page for onboarding. Forward your designer to the next briefing you prepared. Keeping up flow is critical; sending everyone where they need to go while in focus mode helps get things done faster.
## Tip 3: Go Async with Direct Links
> Try Direct Links by signing our [Supporters Pledge](https://documen.so/pledge)
Your customer wanting to approve an additional budget is great. It’s so great. In fact, you want to get on it as soon as possible and not have a calm moment until you send them something to sign. Even if you are fast, you are not mind-ready, though. So, what if your customers could do it whenever they like?
Direct Links lets you set up proposal templates and contracts, which are ready to sign anytime. You can include them in your [initial proposal](https://documen.so/freelance-proposal) or on your [public profile](https://documen.so/profiles). This way, customers can get more of your offering whenever they want.
## Conclusion
Setting up notifications, redirects, and direct signing links using your favorite open source DocuSign alternative helps streamline your business and reduce the cognitive load of managing it. You can get everything mentioned here plus 5 free monthly signatures in the [Documenso 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.
description: I started Documenso because I wanted to build a modern tech company in a growing space with a mission bigger than money, I overpaid for a SSL cert 13 years ago, like encryption and want to help make the internet/ world more open.
authorName: 'Timur Ercan'
authorImage: '/blog/blog-author-timur.jpeg'
authorRole: 'Co-Founder'
date: 2024-02-06
tags:
- Founders
- Mission
- Open Source
---
<figure>
<MdxNextImage
src="/blog/burgers.jpeg"
width="650"
height="100"
alt="Burgers, drinks on a table between friends."
/>
<figcaption className="text-center">
Not the burger from the story. But it could be as well, the place is pretty generic.
</figcaption>
</figure>
> TLDR; I started Documenso because I wanted to build a modern tech company in a growing space with a mission bigger than money, I overpaid for a SSL cert 13 years ago, like encryption, and wanted to help make the world/ Internet more open.
It's hard to pinpoint when I decided to start Documenso. I first uttered the word "Documenso" while sitting in a restaurant with [Felix](https://twitter.com/flxmgdnz), eating a burger and discussing what's next in late 2022. Shortly after, I sat down with a can of caffeine and started building [Documenso 0.9](https://github.com/documenso/documenso/releases/tag/0.9-developer-preview). Starting Documenso is the most deliberate business decision I ever made. It was deliberate from the personal side and deliberate from the business side.
Looking at the personal side, I've had some time off and was actively looking for my next move. Looking back, I stumbled into my first company. Less so with the second one, but I joined my co-founders and did not develop the core concept myself. While coming up with Documenso, I was deliberately looking for a few things, based on my previous experiences:
- An entrepreneurial space that was a big enough opportunity
- A huge macro trend, lifting everything in it's space
- A mode of working that fits my flow (which, luckily for me, is pretty close to the modern startup/ tech scene)
- A more significant impact to be made than just earning lots of money (though there is nothing wrong with that)
Quick shoutout to everyone feeling even a pinch of imposter syndrome while calling themselves a founder. It was after ten years, slightly after starting Documenso, that I started doing it in my head without cringing. So cut yourself some slack. Considering how long I've been doing this, I would have earned the internal title sooner, and so do you. After grappling with my identity for a second, as is customary for founders, my decision to start this journey came quickly.
Aside from the personal dimension, I had a clear mindset of what I wanted. The criteria I describe below clicked into place one after another, in no particular order. Having experienced no market demand and a very gritty, grindy market, I was looking for something more fundamental. Something basic, infrastructure-like, with a huge demand. A growing market deeply rooted in the ever-increasing digitalization of the world.
And to be honest, I just always liked digital signature tools. It's a product that is easy enough to comprehend and build but complex and impactful enough to satisfy a hard need. It's a product you can build very product-driven since the market and domain are well understood. So when asked about what's next for me, I literally said, "Digital, um, let's say… signatures". As it turns out, my first gut feeling was spot on, but how spot on I only realized when I started researching the space. An open source document signing company happens to be the perfect intersection of all the criteria and personal preferences I described above; it's pretty amazing, actually:
- The global signing market is enormous and rapidly growing
- To put it bluntly, the signing space is vast and dominated by one outdated player. Outdated in terms of tech, pricing, and ecosystem
- The signing space is also ridiculously opaque for a space based on open web tech, open encryption tech, and open signing standards. Even by closed-source standards
- We are currently seeing a renaissance for commercial open source startups, combining venture founder financials with open source mechanics
- Rebuilding a fundamental infrastructure as open source with a meaningful scale has a profoundly transformative effect on any space
- Working in open source requires being open, cooperative, and inclusive. It also requires quite a bit of context jumping, "going with the flow," and empathy
- Apart from fixing the signing space, making Documenso successful would be another domino tile toward open source eating the world, which is great for everyone
Building a company is so complex it can't be planned out. Basing it on great fundamentals and the expected dynamics is the best founders can do, in my humble opinion. After these fundamental decisions, you are (almost) just along for the ride and need to focus on solving the "conventional" problems of starting a company the best you can. With digital signatures hitting so many points of my personal and professional checklist, this already was a great fit. What got me excited at first, though, apart from the perspective of drinking caffeine and coding, was this:
Roughly 13 years ago, I was launching my first product. We obviously wanted SSL encryption on the product site, so I had to buy an SSL certificate. ~$200ish, two years validity, from VeriSign, I think. Apart from it being ridiculously complicated to get, it bothered me that we had basically paid $200 for what is essentially a long number someone generated. SSL wasn't even that widespread back then because it was mainly considered important for e-commerce, no wonder considering it cost so much. "Why would I encrypt a blog?". Fast forward to today, and everyone can get a free SSL cert courtesy of [Let's Encrypt](https://letsencrypt.org/) and browsers are basically blocking unencrypted sites. Mostly, it is even built into hosting platforms, so you barely even notice as a developer.
I had forgotten all about that story until I realized this is where signing is today. A global need fulfilled only by a closed ecosystem, not really state-of-the-art companies, leading to, let's call it, steep prices. I had considered Let's Encrypt a pillar of the open internet for so long that I forgot that they weren't always there. One day, someone said, let's make the internet better. Signing is another domain that should have had an open ecosystem for a long time. Another parallel to that story is the fact that the cryptographic certificates you need for document signing are also stuck in the "pre-Let's Encrypt world." Free document signing certificates via "Let's Sign" are now another to-do on the [long-term roadmap](https://documen.so/roadmap) list for the open signing ecosystem. Effecting this change in any way is a huge driver for me.
Apart from my personal gripes with the corporate certificate industry, I have always found encryption fascinating. It's such a fundamental force in society when you think about it: Secure Communication, Secure Commerce, and even [internet native, open source money (Bitcoin)](https://github.com/bitcoin/bitcoin) were created using a bit of smart math. All these examples are expressions of very fundamental human behaviors that should be enabled and protected by open infrastructures.
I never told rthis to anyone before, but since starting Documenso, I realized that I underestimated the impact and importance of open source for quite some time. When I was in University, I distantly remember my mindset of "yeah, open source is nice, but the great, commercially successful products used in the real world are built by closed companies (aka Microsoft)" _shudder_ It was never really a conscious thought, but enough that I started learning MS Silverlight before plain Javascript. It was slowly, over time, that I realized that open web standards are superior to closed ones, and even later, I understood the same holds true for all software. Open source fixes something in the economy I find hard to articulate. I did my best in [Commodifying Signing](https://documenso.com/blog/commodifying-signing).
To wrap this up, Documenso happens to be the perfect storm of market opportunity, my interests, and my passions. Creating a company in which people want to work for the long term while tackling these issues is a critical side quest of Documenso. This is not only about building the next generation of signing tech; it's also about doing our part to normalize open, healthy, efficient working cultures and tackling relevant problems.
As always, feel free to connect on [Twitter / X](https://twitter.com/eltimuro) (DM open) or [Discord](https://documen.so/discord) if you have any questions, comments, thoughts or feelings.
Check out what's new in the latest version and read our thoughts on it. For more technical details, you can find our releases on GitHub [here](https://github.com/documenso/documenso/releases). You can find our [release candidates here](https://github.com/documenso/documenso/tags).
---
## v1.5.6 (latest)
### <small>Released 28th June 2024</small>
> This release contains [11 fixes](https://github.com/documenso/documenso/releases/tag/v1.5.6)
### 🕗 Show Creation Time
We are now displaying the document creation time in the documents view. This allows for easier identification of multiple documents created on the same day.
### 🔗 Direct Template Links
With this release, we are introducing direct link templates. This allows you to statically link to any template and let anyone with the link sign it at any time. A new document is created in your account when a template is signed. Templates with direct links still support all other template features, allowing you to create intricate workflows triggered by the signers.
Learn more about Direct Links [on our blog](https://documenso.com/blog/announcing-direct-links) or try them by signing the [Documenso Supporters Pledge](https://documen.so/pledge).
### 🛂 OpenID Connect (OIDC) Support
Thanks to [Matt Kilgore](https://github.com/tankerkiller125), Documenso now supports OIDC as an authentication provider. This allows self-hosted users to define whatever identity provider they want as long as it supports the OIDC. Azure, Zitadel, Authentik, KeyCloak, and Google all support OIDC.
---
## v1.5.5
### <small>Released 6th May 2024</small>
> This release contains [20 fixes](https://github.com/documenso/documenso/releases/tag/v1.5.5)
### ✅ Show Completed Fields
Fields completed by other recipients are now visible to everyone to communicate the state of the document better and allow users an informed decision on what they are signing.
### ⬇️ Download Completed Documents via API
Completed documents can now be downloaded via the API using this new endpoint:
**GET /API/V1//DOCUMENTS/\{ID\}/DOWNLOAD**
Check out the full Open API docs here: [https://documen.so/openapi](https://documen.so/openapi)
### ➕ Adding Yourself as a Signer
Adding yourself as a signer is now just one click away.
---
## v1.5.4
### <small>Released 11th April 2024</small>
> This release contains [21 fixes](https://github.com/documenso/documenso/releases/tag/v1.5.4)
#### 🔑 Passkeys
To improve security and usability for high-security setups, we added passkeys with this release. Passkeys can now be used to log in or re-authenticate each signature for high-compliance cases.
#### 📄 Signing Certificate & Audit Log
On the security/ compliance side, we also added Signing Certificates and Audit Logs. Every signed document now has a certificate attached, showing technical details of the signature to improve transparency and security. Further, every action on a document from creation to completion is now logged in the audit log to guarantee the integrity of the process.
#### 🔏🦀 @documenso/pdf-sign
We are pretty hyped about this one: Since version 0.9, we relied on https://github.com/vbuch/node-signpdf to add the digital signatures to our documents. Since signing is at the heart of Documenso, we created our own rust-based library for signing. As of 1.5.4, Documenso's signing runs on @documenso/pdf-sign. The library offers a better architecture to enable signing with private keys that are not stored locally (e.g. via HSM). We are in the process of cleaning up the library to open source it like the rest of Documenso 🌱 The library will also help us to offer Long Term Validation (LTV) for signatures soon. While we are currently limited to signing with PKCS7-B, eventually, we plan to support all common signing standards like PAdES, CAdES, and XAdES.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.