Skip to main content

Automate Document Signing

Everything the builder does, your scripts and apps can do. Generate a contract from a template when a deal closes, send it, watch for completion, and file the sealed PDF — without anyone opening the Document Signing UI.

What it's for​

The builder is for one-off sends. Automation is for the repeatable ones: onboarding every new client with the same engagement letter, issuing a renewal the week a subscription lapses, or letting customers sign inside your own product.

Three ways in​

SurfaceUse it when
AutessaScript SDK — autessa.eSignatureLogic runs inside Autessa: a table trigger, a scheduled job, an agent tool, a custom app backend
Poweruser APILogic runs in your own system and calls Autessa over HTTP
Custom AppsYou want signers to sign inside an app you built, without leaving it

All three drive the same service, so an envelope created by a script is identical to one created in the builder — same statuses, same audit trail, same sealed PDF.

The lifecycle, in calls​

Whichever surface you use, the sequence is the same:

  1. Get an upload URL and PUT your document bytes to it.
  2. Create a draft envelope referencing the uploaded file.
  3. Set recipients — this is where signing order, completion policy, and CC viewers are decided.
  4. Set fields, binding each signer field to a recipient.
  5. Set prefill values for any static content.
  6. Send.
  7. Poll or check the envelope until it completes, then download the sealed PDF.

How to send an envelope from AutessaScript​

// 1. Upload the document
const up = autessa.eSignature.generateFileUploadLink({ fileExtension: 'pdf' }).data;
// PUT your PDF bytes to up.uploadUrl, then:

// 2. Create the draft
const created = autessa.eSignature.envelope.create({
title: 'Engagement Letter — Northwind',
s3Uri: up.s3Uri,
});
const envelopeId = created.data.envelope.id;

// 3. Recipients: signing order, completion policy, and a CC viewer
autessa.eSignature.envelope.recipients({
envelopeId,
signingOrder: 'SEQUENTIAL', // 'PARALLEL' = everyone at once
completionPolicy: 'ALL', // 'ANY_ONE' completes on the first signature
recipients: [
{ id: 'r1', email: 'client@northwind.com', name: 'Dana Fox',
recipientKind: 'SIGNER', signingGroup: 1 },
{ id: 'r2', email: 'partner@ourfirm.com', name: 'Sam Reid',
recipientKind: 'SIGNER', signingGroup: 2 },
{ id: 'r3', email: 'records@ourfirm.com',
recipientKind: 'VIEWER' }, // CC'd, never signs
],
});

// 4. Fields, bound to recipients
autessa.eSignature.envelope.fields({
envelopeId,
fields: [
{ id: 'f1', fillSource: 'SIGNER', recipientId: 'r1', fieldType: 'SIGNATURE',
label: 'Client signature',
pageIndex: 0, xPct: 0.6, yPct: 0.8, widthPct: 0.25, heightPct: 0.05 },
{ id: 'f2', fillSource: 'PREFILL', fieldType: 'DATE_STATIC',
label: 'Effective date',
pageIndex: 0, xPct: 0.2, yPct: 0.1, widthPct: 0.15, heightPct: 0.035 },
],
});

// 5. Fill the prefilled content
autessa.eSignature.envelope.prefill({
envelopeId,
values: [{ fieldId: 'f2', value: '2026-07-15' }],
});

// 6. Send — optionally overriding the signing-link expiry
const sent = autessa.eSignature.envelope.send({ envelopeId, linkTtlDays: 14 });
if (!sent.ok) console.log('send blocked:', sent.errors);

Note the shape of steps 3 and 4: the id values you pass for recipients (r1, r2) are what fields reference as recipientId. signingGroup is the signer slot — under SEQUENTIAL it's also the turn order, and two recipients sharing a signingGroup form a client group where either can sign.

completionPolicy: 'ANY_ONE' doesn't combine with signingOrder: 'SEQUENTIAL' — a one-at-a-time envelope that completes on the first signature is a contradiction, and the call is rejected.

How to send from a template​

Far less code, because the layout already exists:

const created = autessa.eSignature.template.createEnvelope({
templateId,
title: 'Engagement Letter — Northwind',
roleAssignments: [
{ roleId: 'role_client', recipients: [
{ id: 'r1', email: 'client@northwind.com', name: 'Dana Fox',
recipientKind: 'SIGNER' },
]},
{ roleId: 'role_partner', recipients: [
{ id: 'r2', email: 'partner@ourfirm.com', recipientKind: 'SIGNER' },
]},
],
});

autessa.eSignature.envelope.send({ envelopeId: created.data.envelope.id });

Every role must get at least one recipient with a non-blank email. Only READ access on the template is required, so a shared team template can be driven by anyone's automation. Signing order, completion policy, field layout, and CC roles all come from the template.

How to watch for completion​

There's no completion webhook. Poll the envelope, or list by status:

const { data } = autessa.eSignature.envelope.list({
statusFilter: ['SENT'], page: 0, pageSize: 25,
});
data.envelopes.forEach(e =>
console.log(e.title, e.collectedSignatureCount + '/' + e.requiredSignatureCount));

For a single envelope, envelope.get returns full state including every recipient's status and the whole audit trail:

const { ok, data } = autessa.eSignature.envelope.get({ envelopeId });
if (ok && data.envelope.status === 'COMPLETED') {
const dl = autessa.eSignature.envelope.download({ envelopeId });
// dl.data.url is a presigned URL to the sealed PDF; dl.data.filename names it
}

A scheduled job running this hourly is also the right way to build automated signer chasing — reminders are manual in the UI, but envelope.remind is a call like any other.

How to check your own signing inbox​

autessa.eSignature.inbox.list returns envelopes where you are a recipient, rather than ones you own. There's no inbox view in the builder — it is an API- and SDK-only surface, useful for building a "documents awaiting your signature" panel into an internal app.

const { data } = autessa.eSignature.inbox.list({ statusFilter: ['SENT'], page: 0 });

How to embed signing in a Custom App​

Custom Apps ship a <PdfSigner /> component that renders Autessa's hosted signer UI inline, so a user can sign without leaving your app or opening an email.

The flow is: create and send the envelope as usual, resolve a signing token for the current user, then render the component with it.

<PdfSigner token={signingToken} onComplete={handleSigned} />

The App Builder's copilot also has read-only awareness of your envelopes through two tools — list_esignature_envelopes and get_esignature_envelope_details — so you can ask it to build screens against real signing data. Both are discovery-only: the copilot can read envelopes, not create, send, or void them.

How to call it over HTTP​

If your logic lives outside Autessa, the Poweruser API exposes the same operations under https://api.autessa.com/autessa_poweruser/e-signature:

  • Envelopes — create, recipients, fields, prefill, send, remind, void, download, inbox
  • Templates — create, roles, fields, instantiate, share
  • Folders — create, nest, file envelopes, share

See the Poweruser API overview for authentication.