E-signatures inside your product.

coss.com Sign is an e-signature API. People sign PDFs inside your app or from an email, and you get a sealed PDF with a hash-chained audit trail.

Read the docs

How it works

Create a request on your server, open the signing page in your app, and download the sealed PDF when the last person signs.

// On your server: ask for a signature, then open a session for the signed-in user.
const { :  } = await ...({
  : "Services agreement",
  : [{ : "agreement.pdf", :  }],
  : [
    {
      : "Ada Lovelace",
      : "ada@example.com",
      : "embedded", // or "email": coss.com sends the link
      : "user_42",
      : [
        { : "signature", : "{{signature:signer_1}}" },
        { : "date_signed", : "{{date:signer_1}}" },
      ],
    },
  ],
});

const  = ?.[0];
if ( && ) {
  const { :  } = await ...(., .);
  // Hand session.url to the browser.
}
// In the browser: the signing page in an iframe on your own page.
({
  : ,
  ,
  : () => {
    if (. === "signed") .("Request is", .);
  },
});

When the last signer signs, coss.com seals the completed document and sends sign_request.completed; coss.sign.requests.signedDocument(id) downloads it. See embedded signing and the API reference.

Signing, end to end

From the uploaded PDF to the sealed copy, every step is an API call, a webhook and a line in your logs.

Fields by position or anchor

Place fields in PDF points on a page, or write {{signature:signer_1}} into the document and give the field by its anchor: it covers every occurrence. Signature, initials, date signed, name, email, text and checkbox fields. See fields and anchors.

Embedded or by email

Embedded signers sign in your app, in an iframe mountSigning opens, with your accent color and theme. Email signers get their link when it's their turn, reminders until they sign, and the signed PDF afterwards. See email signing.

Consent, then a signature

Before a signer sees a document, they agree to sign electronically, and the SHA-256 of the consent text they saw is recorded. They adopt a typed or drawn signature, or decline with a reason, and nothing they filled in changes after they finish.

Signing order

Signers sign in parallel by default, or one after another with signing_order: "sequential": each is invited, or allowed to sign, once everyone before them has signed. Requests expire when you say, and their links stop working.

Templates and a builder

Templates hold documents and fields for roles instead of people. Name a signer per role and fill merge_fields to make a request. Your own users can edit templates in your app, in the builder mountBuilder opens. See templates.

Webhooks for every step

sign_request.sent, viewed, signer_signed, declined, completed, canceled and expired reach your webhooks, and each is a line in your environment's logs. Payloads never include documents or field values.

A record that proves itself

The completed PDF and its audit trail are built so anyone can check that nothing changed.

The signed document is every PDF with the signatures and values drawn in, followed by certificate pages: each signer, how they were identified (the emailed link, or your app and its client_ref), when they opened, consented and signed, the address and browser they signed from, each document's SHA-256 and the whole audit trail.

coss.com seals it with a PAdES signature and an RFC 3161 timestamp, so PDF viewers show it hasn't changed since. The seal carries the revocation data of every certificate involved (PAdES B-LT), so it still verifies after those certificates expire. The audit trail is append-only: each event's hash covers the event and the previous hash, so the last one vouches for the whole trail. See completion and the audit trail.

Specifications

The limits of a request. The API reference lists each one with its field.

Document size
25 MB, 500 pages
Documents per request
10
Signers per request
20
Fields per request
500
Request expiry
up to 365 days ahead
Email reminders
up to 3, every 1 to 30 days
Embedded session
1 hour by default, at most 24 hours
Embedding origins
up to 10, https
Seal
PAdES B-LT, RFC 3161 timestamp
Signature types
simple electronic (ESIGN, UETA, eIDAS)
Requests kept
until you delete them

Questions

How do I add e-signatures to my app?
Create a signature request with coss.sign.requests.create(), giving the PDFs and each signer with their fields. Signers either get an email with a signing link, or sign inside your app in an iframe you mount with mountSigning from coss/sign. When everyone has signed, a sign_request.completed webhook says the sealed PDF is ready to download.
Are coss.com signatures legally binding?
They are simple electronic signatures under the US ESIGN Act and UETA and the EU's eIDAS. Each signer agrees to sign electronically, signs with a deliberate act and is identified by the emailed link or by your app, and the audit trail records each step.
How do I place signature fields without coordinates?
Write anchors such as {{signature:signer_1}} into the document as text, white text included, and give the field by its anchor. coss.com finds every occurrence in the PDF's text and places the field over each one. Fields can also be placed by page and position in PDF points.
What does the completed PDF contain?
Every document with the signatures and values drawn in, followed by certificate pages listing each signer, how they were identified, when they consented and signed, the address and browser they signed from, each document's SHA-256 and the whole audit trail. It is sealed with a PAdES signature and a trusted timestamp, so any later change shows.
Can my own users build templates?
Yes. Create a builder session for a template with coss.sign.templates.createBuilderSession() and mount it in your app with mountBuilder from coss/sign. Your users upload PDFs, add signer roles and place fields; a builder session only reaches its own template.
How do I test signing without real signatures?
Use a sandbox key. Requests work end to end, with the real signing page and a sealed PDF, but emails go to the sandbox's fake provider, the signing page and the certificate say it is a test, and nothing is billed.
On the same key, SDK, webhooks and logs: nothing more to set up.

Compared

How it stacks up against the services you may be using, with sources.

Start with Sign today.

Development keys record every request and event and deliver nothing, so you can build and test before you verify a domain. Hand your coding agent this prompt:

Add coss.com to this project: read https://coss.com/llms.txt, get a development key with `npx coss-cli init --agents`, and build and test with it.

Pricing